我正在尝试进行查询,该查询将在数组中查找特定元素并打印出该特定元素所在的对象。我想对数据集中的每个元素执行此操作
这是我的数据集的示例(但大约有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)
})
});
谁能解释为什么只打印出数据集中的最后一个元素?
答案 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
}