for循环nodeJS中的Mongo查询

时间:2018-08-10 11:33:05

标签: javascript arrays node.js mongodb

我正在尝试进行查询,该查询将在数组中查找特定元素并打印出该特定元素所在的对象。我想对数据集中的每个元素执行此操作

这是我的数据集的示例(但大约有1万个数据集。这些只是数据库中的前2组):

/* 1 */
{
    "_id" : ObjectId("5b6b19cb1be7e54a24344bd5"),
    "id" : 18009,
    "ingredients" : [ 
        "baking powder", 
        "eggs", 
        "all-purpose flour", 
        "raisins", 
        "milk", 
        "white sugar"
    ]
}

/* 2 */
{
    "_id" : ObjectId("5b6b19cb1be7e54a24344bd6"),
    "id" : 28583,
    "ingredients" : [ 
        "sugar", 
        "egg yolks", 
        "corn starch", 
        "cream of tartar", 
        "bananas", 
        "vanilla wafers", 
        "milk", 
        "vanilla extract", 
        "toasted pecans", 
        "egg whites", 
        "light rum"
    ]
}

所以我想要的是,首先找到存在发酵粉的食谱,然后我要在存在的地方打印那些对象。我想对所有成分都做同样的事情。我尝试执行以下操作来实现此目的:

const path = "mongodb://localhost:27017/NN_Recipes";


mongo.connect(path, function(err,db) {

    console.log("Connected!")


    var allIngredients;


    return new Promise((resolve, reject) => {
        db.collection('recipes_final').distinct("ingredients", function(err, resu) {

            allIngredients = resu;
            resolve();
        })
    }).then(data => {
        for(i = 0; i < allIngredients.length; i++) {

            var currentIngredient = allIngredients[i];

            var individualMatrix = db.collection('recipes_final').find({
                ingredients: currentIngredient
            }).toArray(function(error, response) {
                  // console.log(currentIngredient); //This will only print the very last element in the allIngredients[i], none of the other ones.

            });

            //all below is just things i tried to play around with.
        //     console.log(i)
        //     console.log(individualMatrix)
        //    console.log(allIngredients[i])
        }
       // console.log(allIngredients)
    })


});

谁能解释为什么只打印出数据集中的最后一个元素?

4 个答案:

答案 0 :(得分:1)

您可以尝试async/await进行所有操作,因此每个呼叫都会依次进行:

mongo.connect( path, async (err, db) => {

    const recipes = db.collection('recipes_final'),
           allIngredients = await recipes.distinct("ingredients");

    for (let ingredients of allIngredients) {
        let individualMatrix = await recipes.find({ ingredients }).toArray()
        console.log(individualMatrix)
    }
});

答案 1 :(得分:0)

不使用for循环,它不等待打印输出。您的for循环不是异步的,请使用async进行循环。

async.each(openFiles, saveFile, function(err){
    // if any of the saves produced an error, err would equal that error
});

答案 2 :(得分:0)

我发现问题出在哪里,您错过了for循环内的closure

for(i = 0; i < allIngredients.length; i++) {
   (function(i){
        var currentIngredient = allIngredients[i];

        var individualMatrix = db.collection('recipes_final').find({
            ingredients: currentIngredient
        }).toArray(function(error, response) {
              // console.log(currentIngredient); //This will only print the very last element in the allIngredients[i], none of the other ones.

        });
       })(i)
    }

答案 3 :(得分:0)

  

使用ES6 关闭

您所用的数据库查询是异步的。当您执行查询时:

db.collection('collectionName').find().toArray(callback);

此处的callback函数在下一个滴答处执行,即在整个脚本完成后执行。因此,当当前刻度结束时,i(for循环的)已等于allIngredients.length,并且指向最后一个元素。您可以使用闭包let(如果使用的是ES6)代替var来声明currentIngredient变量,从而减轻这种情况,如下所示:

for (i = 0; i < allIngredients.length; i++) {
  let currentIngredient = allIngredients[i];
  // rest of your code
}