MongoDB:forEach游标中打印关联过滤文档失败问题咨询
解决MongoDB forEach游标中打印过滤文档的问题
我帮你分析下问题出在哪,以及怎么解决:
首先,你的代码里有两个关键问题导致没有输出:
printjson是函数,你没有调用它:你写的是.printjson,这只是引用了函数本身,没有执行它,必须加上括号()才会触发打印。find()返回的是游标对象,直接打印游标得不到文档内容:find()不会直接返回匹配的文档,而是返回一个游标,你需要遍历这个游标才能获取到里面的每一条文档。
修正后的写法一:遍历游标打印每个匹配文档
db.getCollection('resources').find({"software":"dockerclient"}).forEach(function(res){ // 获取匹配templates的游标 const templatesCursor = db.getCollection('templates').find({resourceId: res._id.valueOf()}); // 遍历游标,打印每个文档 templatesCursor.forEach(function(templateDoc){ printjson(templateDoc); }); });
修正后的写法二:转成数组后打印所有匹配文档
如果你想一次性打印某个resource对应的所有templates文档,也可以用toArray()把游标转成数组,再打印:
db.getCollection('resources').find({"software":"dockerclient"}).forEach(function(res){ const matchedTemplates = db.getCollection('templates').find({resourceId: res._id.valueOf()}).toArray(); printjson(matchedTemplates); });
更高效的替代方案:用聚合查询关联集合
其实你这种跨集合关联查询的场景,用MongoDB的$lookup聚合操作会更高效,不需要手动嵌套遍历游标:
db.getCollection('resources').aggregate([ // 先过滤出符合条件的resources文档 { $match: { "software": "dockerclient" } }, // 关联templates集合,根据_id和resourceId匹配 { $lookup: { from: "templates", localField: "_id", foreignField: "resourceId", as: "matched_templates" } }, // 如果每个resource对应多个template,用$unwind展开数组(不需要保留数组的话可以加这步) { $unwind: "$matched_templates" }, // 直接输出匹配的template文档(可选,如果你只想看template数据的话) { $replaceRoot: { newRoot: "$matched_templates" } } ]).forEach(function(doc){ printjson(doc); });
这个聚合查询会自动帮你完成两个集合的关联,避免手动嵌套遍历的繁琐,数据量大的时候性能也更好。
内容的提问来源于stack exchange,提问作者Minstrel
相关产品推荐
相关产品推荐

