Запускаем Mon go find синхронно - PullRequest
0 голосов
/ 06 мая 2020

У меня проблема, когда у меня 20 + k строк в файле csv, и я пытаюсь обновить их на основе документов соответствующего поля в Mon go DB, который содержит 350k документов.

Хитрость в том, что мне нужно выполнить лог c для совпадений, а затем повторно обновить csv.

Я использую PapaParse для анализа / разборки файла csv

Выполняю что-то вроде работы, чтобы получить все мои совпадения

const file = fs.createReadStream('INFO.csv');
Papa.parse(file, {
    header: true,
    complete: function(row) {        
        getMatchesAndSave(row.data.map(el => { return el.fieldToMatchOn })); 
    }
});`

function getMatchesAndSave(fields) {
Order.find({fieldToMatchOn: { $in: fields}}, (err, results) => {
    if (err) return console.error(err);
    console.log(results);
});

}

Это быстро достает мне спички. Однако я не могу действительно объединить свои данные обратно в csv b c, csv имеет уникальный ключевой столбец, о котором Mon go не знает.

Итак, все данные действительно зависят от того, что находится в csv.

Поэтому я подумал сделать что-то вроде этого

`

const jsonToCSV = [];
for (let row of csvRows) {
    db.Collection.find({fieldToMatchOn: row.fieldToMatchOn}, (err, result) => {
        //Add extra data to row based on result
        row.foo = result.foo;

        //push to final output
        jsonToCSV.push(row);
    }
}
papa.unparse(jsonToCSV);
//save csv to file

Проблема с описанной выше реализацией (как бы ужасно неэффективной она ни казалась) заключается в том, что вызовы Find являются асинхронными, и в jsonToCSV ничего не передается.

Подсказки? Решение этой проблемы с помощью $ in было бы идеальным, есть ли способы получить доступ к текущему элементу в $ in (так что ищу итератор) .. таким образом я мог бы обработать это.

1 Ответ

1 голос
/ 06 мая 2020

Вы можете попробовать async / await для итерации массива csvRows, например:

const search = async () => {
  const jsonToCSV = await Promise.all(csvRows.map(async row => {
/* find returns a promise, so we can use await, but to use await is 
mandatory use it inside an async function. Map function not returns a 
promise, so this can be solve using Promise.all. */
    try {
      const result = await db.Collection.find({ fieldToMatchOn: row.fieldToMatchOn });
      row.foo = result.foo;
      return row;
    } catch (e) {
      // do somenthing if error
    }
  }));
  papa.unparse(jsonToCSV);
}

// call search function
search();

Проверьте это https://flaviocopes.com/javascript-async-await-array-map для лучшего понимания.

...