Node.js 节点中带有异步mongodb查询的嵌套循环 问题
我在MongoDB有3个系列Node.js 节点中带有异步mongodb查询的嵌套循环 问题,node.js,mongodb,mongodb-query,aggregation-framework,Node.js,Mongodb,Mongodb Query,Aggregation Framework,我在MongoDB有3个系列 地区 每个文档对应一个地理区域,有一个区域名称字段,另一个字段是更广泛区域内的农场数组 细节 此集合包含与特定农场相关的文档,以及与该农场详细信息相关的各种字段,例如奶牛数量 屈服 此集合再次包含文档,其中每个文档都与特定场相关,此实例中的字段用于每天的场输出 我正在尝试编写一个函数,它将从regions集合开始,对于第一个区域,它将获取每个农场ID,并使用它查询其他两个集合,获取该农场的总产量和奶牛总数,然后对每个农场求和,以获得该区域的总数 企图
- 地区
- 每个文档对应一个地理区域,有一个区域名称字段,另一个字段是更广泛区域内的农场数组
- 细节
- 此集合包含与特定农场相关的文档,以及与该农场详细信息相关的各种字段,例如奶牛数量
- 屈服
- 此集合再次包含文档,其中每个文档都与特定场相关,此实例中的字段用于每天的场输出
var db=client.connect('mongodb://localhost:27017/mydb,函数(err,db){
如果(错误)抛出错误;
var regions=db.collection('regions');
var details=db.collection('details');
var收益率=数据库集合(“收益率”);
regions.find({“region”:“Gotham”}).toArray(函数(err,docs){
对于(var k=0;k
在外循环完成后,我想对最终的
regionield
值做点什么,但由于异步mongo调用,按照现在的结构,外循环在内循环中完成必要的计算之前就完成了。我就是想不出如何绕过这个问题。我已经看了很多问题/答案e解释回调,但我不知道如何将其应用到我的案例中。您可以使用库来简化嵌套异步调用的处理。我认为您在设计中采用了错误的方法,但稍后会详细介绍。首先,基本上更改您的列表
简单且无额外依赖关系的方法是使用驱动程序直接支持的节点。这允许您依次处理每个文档,也不会像.toArray()
那样将所有内容加载到内存中
此外,作为“流”,还有一个触发的“结束”事件,以及可以包装发出的查询的自然流控制:
var mongodb=require('mongodb'),
MongoClient=mongodb.MongoClient;
MongoClient.connect('mongodb://localhost/mydb,函数(err,db){
如果(错误)抛出错误;
var regions=db.collection('regions'),
收益率=db.集合(“收益率”);
var resultHash={};
var rstream=regions.find({“region”:“Gotham”});
rstream.on('err',函数(err){
犯错误;
});
rstream.on('end',function()){
console.log('Complete');
log(JSON.stringify(resultHash,未定义,2));
db.close();
});
rstream.on('data',函数(区域){
rstream.pause();//暂停外部流
resultHash[region.region]=0;
var fstream=yield.find({“Farm_ID”:{“$in”:region.farms}});
fstream.on('err',函数(err){
犯错误;
});
fstream.on('end',function(){
console.log(“完成的农场”);
resume();i//恢复外部流
});
fstream.on('data',函数(场){
fstream.pause();//暂停内部流
结果ash[地区.地区]+=农场产量;
fstream.resume();//恢复内部流
});
});
});
这基本上是对另一个文档中匹配的“区域”的所有“产量”值进行“求和”。还要注意的是,非常简单的使用传递数组中已经存在的所有“农场”,而不是处理另一个循环
但无论如何,你真的不应该这样做。数据库是“智能”的,你的设计需要更智能
您可以通过基本上将“区域”数据添加到“产量”数据中来避免这里的所有麻烦。然后,这只是一个运行问题:
因此,对于“收益率”中的数据:
{“地区”:“高谭”,“产量”:123}
然后只运行以下代码:
yield.aggregate(
[
{“$组”:{
“_id”:“$region”,
“收益率”:{“$sum”:“$yield”}
}}
],
功能(错误、结果){
}
);
这一切都完成了,代码中没有循环或计算
因此,如果您只需将“相关数据”如“区域”添加到您想要处理的“产量”数据中,那么MongoDB已经有了一些工具,可以轻松地在该键上进行累积
这就是脱离关系设计的意义所在。事物的工作方式不同,因此您需要以不同的方式处理它们。而且更智能。您还可以在循环中使用let而不是var
var db = client.connect('mongodb://localhost:27017/mydb', function(err,db) {
if (err) throw err;
var regions = db.collection('Regions');
var details = db.collection('Details');
var yield = db.collection('Yield');
regions.find({"region" : "Gotham"}).toArray(function(err, docs) {
for (let k = 0; k < docs.length; k++) {
var regionYield = 0;
for (let j = 0; j < docs[k].farms.length; j++) {
var farmYield = 0;
var farmID = docs[k].farms[j]
yield.find({Farm_ID: farmID}).toArray(function(err, docs) {
for (let i = 0; i < docs.length; i++) {
farmYield += +docs[i].Yield;
}
console.log('finished inner loop');
regionYield += farmYield;
});
}
console.log('finished middle loop');
}
console.log('finished outer loop');
});
var db=client.connect('mongodb://localhost:27017/mydb,函数(err,db){
如果(错误)抛出错误;
var regions=db.collection('regions');
var details=db.collection('details');
var收益率=数据库集合(“收益率”);
regions.find({“region”:“Gotham”}).toArray(函数(err,docs){
for(设k=0;k