在节点中使用异步mongodb查询的嵌套循环

时间:2015-09-04 15:11:42

标签: node.js mongodb mongodb-query aggregation-framework

问题

我在MongoDB中有3个集合

  • 区域
    • 每个文档对应一个地理区域,有一个区域名称的字段,另一个字段是更广泛区域内的一组农场
  • 细节
    • 此集合包含文档,每个文档与特定服务器场相关,并且包含与该服务器场的详细信息相关的各种字段,例如:奶牛数量
  • 屈服
    • 此集合再次包含每个与特定服务器场相关的文档,此实例中的字段用于每天的服务器场输出

我正在尝试编写一个以区域集合开头的函数,然后为第一个区域获取每个单独的服务器场ID,并使用此函数查询其他两个集合,获取总产量和总数。农场,然后总结每个农场,以获得该地区的总数。

尝试

我首先尝试使用直接的mongodb调用只有一个区域

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 (var k = 0; k < docs.length; k++) {
    var regionYield = 0;

    for (var 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 (var 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');
});

在完成外部循环后,我想用最终的regionYield值做一些事情,但是现在结构化了,外部循环在内部循环中完成必要的计算之前完成,因为异步mongo调用。我只是无法想办法解决这个问题。我在这里看了很多问题/答案,解释了回调,但我无法弄清楚如何将它应用到我的案例中。

2 个答案:

答案 0 :(得分:0)

您可以使用async库来更轻松地使用嵌套异步调用。

答案 1 :(得分:0)

此外,您可以在循环中使用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');
});

这样可以正常工作..