的NodeJS与猫鼬 - 嵌套查询异步问题
我不得不MongoDB的集合,像这样:的NodeJS与猫鼬 - 嵌套查询异步问题
UserGroup collection
fields:
name: String
group_id: Number
User collection
fields:
user_name: String
group_id: Number
我想产生这样的报告:
ADMINISTRATORS -------------------------- jlopez rdiaz OPERATORS -------------------------- amiralles dcamponits
,但我得到了以下报告:
ADMINISTRATORS -------------------------- OPERATORS -------------------------- jlopez rdiaz amiralles dcamponits
以下是生成报告的代码:
UserGroup.find({}, (err, groups) => {
for(var i in groups){
console.log(groups[i].name)
console.log("--------------------")
User.find({group_id : groups[i].group_id}, (err, users) =>{
for(var j in users){
console.log(users[j].user_name)
}
})
}
})
显然,这是NodeJs/Mongoose异步性的问题。
问题:如何制作第一个For循环等待,直到每个UserGrop的内部循环结束?
在此先感谢,
David。
您可以运行使用$lookup
做在同一个数据库中的“左加入”到另一个集合中从“加盟”收集处理文档过滤聚合管道。有了这个,你将不再需要任何异步库:
UserGroup.aggregate([
{
"$lookup": {
"from": "users",
"localField": "group_id",
"foreignField": "group_id",
"as": "users"
}
},
{
"$project": {
"_id": 0,
"name": 1,
"users": {
"$map": {
"input": "$users",
"as": "user",
"in": "$$user.user_name"
}
}
}
}
], (err, groups) => {
if (err) throw err;
console.log(JSON.stringify(groups, null, 4));
})
样本输出
[
{
"name": "ADMINISTRATORS",
"users": ["jlopez", "rdiaz"]
},
{
"name": "OPERATORS",
"users": ["amiralles", "dcamponits"]
}
]
这是asyc的一个很好的用例,你可以从下面的代码中获得一个基本的想法。它基于异步每个&瀑布。 [请自行为以下代码添加适当的错误处理。]
UserGroup.find({}, (err, groups) => {
async.each(groups, (group, callback) =>{
async.waterfall([
(wCallback) => {
User.find({group_id : group.group_id}, wCallback)
},
(users, wCallback) => {
console.log(group.name)
console.log("--------------------")
for(var j in users){
console.log(users[j].user_name)
}
wCallback()
}
], callback)
})
})
我是完美的拉坦·库马尔。非常感谢你! –
你可以接受这个答案。 ;)欢迎。 –
嗨拉坦。我是新来的Stackoverflow。 首先,我很惊讶人们回应的速度有多快。 虽然我说你的答案解决了这个问题,但我认为使用用户_chridam_提到的'Aggregation Pipeline'是最好的解决方案,因为它不需要使用外部库。 **无论如何非常感谢你!** –
添加对承诺的支持猫鼬。我使用q,但你也可以使用蓝鸟。
mongoose.Promise = require('q').Promise;
然后,您可以使用q.all解决所有用户查询完成后。
var promises = [];
var groups = [];
UserGroup.find({}, (err, groups) => {
for(var i in groups){
groups.push(groups[i]);
promises.push(User.find({group_id : groups[i].group_id}));
}
});
q.all(promises).then(function(usersByGroup){
var indx = 0;
usersByGroup.forEach(function(users){
var grp = groups[indx];
console.log(groups[i].name);
console.log("--------------------");
for(var j in users){
console.log(users[j].user_name)
}
indx++;
});
});
这很有效,正如你提到的那样,没有必要使用另一个库。 ¡非常感谢你chridam! –