JSON-файлы не содержат всех результатов в AWS лямбда с помощью NodeJS

В настоящее время я работаю над проектом, используя AWS и S3, Rekognition и лямда. Я пишу на NodeJS и создана рабочая решение чего я хочу добиться. Процесс вкратце таков: изображение лица загружены на S3 ведро, то searchFacesByImage' API вызывается, чтобы увидеть, если это лицо был проиндексирован на коллекция мастер в прошлом. Если это новое лицо, то результатом будет false, и API в 'indexFaces' называется в индексе, которые стоят на master коллекция. Как только это будет сделано, я напишу вывод в 3 отдельных файлов JSON, который находится в той же S3 ведро, под названием: 'метаданные.формат JSON', 'индексация.формат JSON', 'rekognition.формат JSON'.

В метаданных.JSON-файл содержит только ExternalImageID (которые я создаю сам), дата и время индексирования именем, который был проиндексирован, и счетчик, который считает сколько раз это лицо был проиндексирован в прошлом.

В 'индексация.JSON-файл содержит ту же ExternalImageID, одни и те же данные и время индексации, и ответ от 'searchFacesByImage' API-интерфейс.

В 'rekognition.JSON-файл содержит ту же ExternalImageID и дату и время, а также ответ от API в 'indexFaces'.

Проблема заключается в том, что, когда я загрузить изображение за раз, 3 JSON-файлы начнут заселять соответственно, но как только нагрузка больше, чем несколько (я проверил это с 7) образы, в то же время, все 7 изображений будет работать через процесс и ответ данные записываются в каждый файл по С помощью бревен, но когда я на самом деле сходить для просмотра файлов JSON, не все данные есть для всех 7 изображений. Иногда данные 5 изображений в JSON, другой раз 4 картинок. Данные не должны быть в каком-то определенном порядке, она должна просто быть там. Я также проверил это, где я загружен 18 изображений за один раз и только ответ из 10 изображений в формате JSON.

Я считаю, что проблема заключается в том, что я звоню 'функция getobject' API на JSON файлы, потом добавить данные в эти файлы, а потом я звоню 'putObject' API на эти JSON-файлы, чтобы положить их обратно в S3 в ведро, но в то время как первые изображения переживает этот процесс, следующее изображение хочет сделать то же самое, но нет файла, чтобы использовать 'функция getobject', потому что он занят с предыдущего изображения тогда он просто пропускает изображения, хотя логи CloudWatch сказал, что я был добавлен в файлы.

Я понятия не имею, как работать вокруг этого. Я полагаю, ответ кроется в асинхронном JavaScript (который я не знаю, что уж так я не знаю с чего начать)

Мои извинения за длинный пост. Вот мой код ниже:

const AWS = require('aws-sdk');
const s3 = new AWS.S3({apiVersion: "2006-03-01"});
const rekognition = new AWS.Rekognition();
//const docClient = new AWS.DynamoDB.DocumentClient();
const uuidv4 = require('uuid/v4');

let bucket, key;
let dataSaveDate = new Date();

console.log('Loading function');


//-----------------------------------Exports Function---------------------------
exports.handler = function(event, context) {
    bucket = event.Records[0].s3.bucket.name;
    key = event.Records[0].s3.object.key;

    console.log(bucket);
    console.log(key);

    searchingFacesByImage(bucket, key);
};

//---------------------------------------------------------------------------

// Search for a face in an input image
function searchingFacesByImage(bucket, key) {
    let params = {
        CollectionId: "allFaces", 
        FaceMatchThreshold: 95, 
        Image: {
            S3Object: {
                Bucket: bucket, 
                Name: key
            }
        }, 
        MaxFaces: 5
    };

    const searchingFace = rekognition.searchFacesByImage(params, function(err, searchdata) {
        if (err) {
            console.log(err, err.stack);    // an error occurred
        } else {
            // console.log(JSON.stringify(searchdata, null, '\t'));
            // if data.FaceMatches > 0 : There that face in the image exists in the collection
            if (searchdata.FaceMatches.length > 0) {
                console.log("Face is a match");
            } else {
                console.log("Face is not a match");
                let mapping_id = createRandomId();
                console.log(`Created mapping_id: ${mapping_id}`);

                console.log("Start indexing face to 'allFaces'");
                indexToAllFaces(mapping_id, searchdata, bucket, key);
            }
        }
    });
    return searchingFace;
}

//---------------------------------------------------------------------------

// If face is not a match in 'allFaces', index face to 'allFaces' using mapping_id
function indexToAllFaces(mapping_id, searchData, bucket, key) {
    let params = {
        CollectionId: "allFaces", 
        DetectionAttributes: ['ALL'], 
        ExternalImageId: mapping_id, 
        Image: {
            S3Object: {
            Bucket: bucket, 
            Name: key
            }
        }
    };
    const indexFace = rekognition.indexFaces(params, function(err, data) {
        if (err) {
            console.log(err, err.stack);    // an error occurred
        } else {
            console.log("INDEXING TO 'allFaces'");
            //console.log(JSON.stringify(data, null, '\t'));

            logAllData(mapping_id, bucket, key, searchData, data);
        }
    });

    return indexFace;
}

//---------------------------------------------------------------------------

// Counting how many times a face has been indexed and logging ALL data in a single log
function logAllData(mapping_id, bucket, key, searchData, data) {
    let params = {
        CollectionId: mapping_id, 
        MaxResults: 20
    };

    const faceDetails = rekognition.listFaces(params, function(err, facedata) {
        if (err) {
            console.log(err, err.stack);    // an error occurred
        } else {
            //console.log(JSON.stringify(facedata, null, '\t'));

            metadata(mapping_id, bucket, key, facedata);
            indexing(mapping_id, bucket, searchData);
            rekognitionData(mapping_id, bucket, data);
        }
    });

    return faceDetails;
}
//-----------------------------------------------------------------------------

function metadata(mapping_id, bucket, key, faceData) {

    let body = [
        {
            "mapping_id": mapping_id,
            "time": dataSaveDate,
            "image_name": key,
            "indexing_count": faceData.Faces.length - 1
        }
    ];

    //console.log(JSON.stringify(body, null, '\t'));

    logData("metadata.json", bucket, body);
}

//------------------------------------------------------------------------------

function indexing(mapping_id, bucket, searchData) {
    let body = [
        {
            "mapping_id": mapping_id,
            "time": dataSaveDate,
            "IndexingData": searchData
        }    
    ];

    logData("indexing.json", bucket, body);
}

//------------------------------------------------------------------------------

function rekognitionData(mapping_id, bucket, data) {
    let body = [
        {
            "mapping_id": mapping_id,
            "time": dataSaveDate,
            "rekognition": data
        }    
    ];

    logData("rekognition.json", bucket, body);
}

//------------------------------------------------------------------------------
// Function to log all data to JSON files

function logData(jsonFileName, bucket, body) {
    let params = {
        Bucket: bucket,
        Key: jsonFileName
    };

    const readFile = s3.getObject(params, function(err, filedata) {
        if (err) {
            console.log(err, err.stack);        // an error occurred
        } else {
            console.log(`READING ${jsonFileName} CONTENTS`);
            // Read data from 'jsonFileName'
            let raw_content = filedata.Body.toString();
            let content = JSON.parse(raw_content);

            // Add new data to 'jsonFileName'
            content.push(...body);

            // Put new data back into jsonFileName
            s3.putObject(
                {
                    Bucket: bucket,
                    Key: jsonFileName,
                    Body: JSON.stringify(content, null, '\t'),
                    ContentType: "application/json"
                },
                function(err, res) {
                    if (err) {
                        console.log(err);
                    } else {
                        console.log(`DATA SAVED TO ${jsonFileName}`);
                    }
                }
            );
        }
    });

    return readFile;
}

//----------------------------------SCRIPT ENDS---------------------------------

+1
2019-09-17 11:47:06
источник
5 ответов

Не могли бы вы, пожалуйста, попробуйте следующее. Это позволит сравнить все столбцы со 2-го столбца до последней колонке и проверить, если каждый элемент равен или нет. Если они все же он будет печатать.

awk '{for(i=3;i<=NF;i++){if($(i-1)==$i){count++}};if((NF-2)==count){print};count=""}' Input_file

Или(путем жесткого кодирования $2 в код, так как если и это означает так умышленно беру $2=$3=$4 в сравнении, а не на заменяется на Предыдущее значение.)

i-1
+0
2019-09-19 06:07:11

Я хотел бы использовать счетчик t начального значения 2, чтобы добавить количество $i == $(i+1), где я проходит от 2 до НФ-1. печатать строку только если -это правда:

awk -F'\t' '{t=2;for(i=2;i<NF;i++){t+=$i==$(i+1)}}t==NF' file.txt
+0
2019-09-19 06:07:11

Еще один небольшой поворот на подходе. В вашем случае вы знаете, вы хотите, чтобы сравнить поля , поэтому можно просто петлю из проверка для равенства, и если это не удается, не печатать, сделать очередную запись, например

awk '{for(i=3;i<=NF;i++)if($i!=$(i-1))next}1'

Пример Использования/Выход

С ваши данные в :

$ awk '{for(i=3;i<=NF;i++)if($i!=$(i-1))next}1' file.txt
1   A   A   A
2   B   B   B
+0
2019-09-19 06:07:11

Если вам гарантия не поле содержит регулярное выражение-активных чаров и первое поле не соответствовать второй, и нет пустой строки во входных данных:

awk '{tmp=$0;gsub($2,"")} NF==1{print tmp}' file

Обратите внимание, что это решение предназначено для данного конкретного случая и менее растяжимый, чем другие.

+0
2019-09-19 06:07:11

Вот это обобщение проблемы:

Select all lines where a set of columns have the same value: c1 c2 c3 c4 ..., where ci can be any number:

Предположим, что мы хотим выбрать столбцы:

awk 'BEGIN{n=split("2 3 4 11 15",a)}
     {for(i=2;i<=n;++i) if ($(a[i])!=$(a[1])) next}1' file

Немного более надежным, в случае, если строка не может содержать все поля:

awk 'BEGIN{n=split("2 3 4 11 15",a)}
     {for(i=2;i<=n;++i) if (a[i] <= NF) if ($(a[i])!=$(a[1])) next}1' file
+0
2019-09-19 06:07:11

Посмотрите другие вопросы по меткам