【问题标题】:Storing Data From Multiple MongoDB Queries in NodeJS在 NodeJS 中存储来自多个 MongoDB 查询的数据
【发布时间】:2013-05-12 01:07:19
【问题描述】:

好吧,我认为如果我只是复制我的整个 node.js 路由这样你就可以看到我在说什么会更容易。

我正在尝试对我的 MongoDB 数据库进行多个查询(每天一个)。查询运行良好,但是当它们触发回调时,我的增量变量已经递增了。

所以对于这个:

exports.graph = function(req, res) {

  function pad(num, size) {
    var s = num+"";
    while (s.length < size) s = "0" + s;
    return s;
  }

  database.collection('customerData', function(err, collection) {

    for (var i = 2; i < 18; i++) {

      sDay = pad(i, 2);
      eDay = pad(i + 1, 2);

      collection.find({ 
        DATE: { 
          $gte: sDay + 'APR13:00:00:00',
          $lt: eDay + 'APR13:00:00:00' 
        }
      }, function(err, cursor){
        cursor.toArray(function(err, data){
          var counter = 0;
          for (var point in data) {
            trans = parseInt(data[point].Total_Transaction * 100);
            counter += trans;
          }

          console.log(i, counter / 100);  
        });
      });
    }
  });
}   

我得到这个输出:

18 22023.29
18 24483.03
18 22644.11
18 23194.31
18 21560.99
18 23024.32
18 24384.93
18 23138.34
18 24400.63
18 28418.6
18 31691.65
18 31111.62
18 42358.74
18 38355.76
18 36787.52
18 42870.19
18 22023.29
18 22644.11
18 24483.03
18 23194.31
18 21560.99
18 23024.32
18 24400.63
18 23138.34
18 24384.93
18 28418.6
18 31691.65
18 31111.62
18 42358.74
18 38355.76
18 36787.52
18 42870.19

这(显然)并不理想 - 数字不一定按照查询被触发的顺序返回,所以对我来说弄清楚哪些去哪里很重要。

我想不出一种方法以一种有意义的方式将我的算术结果存储在查询回调中,以便以后使用。

有什么想法吗?

【问题讨论】:

    标签: javascript node.js mongodb


    【解决方案1】:

    附带说明,与您的示例和我下面的示例不同,您确实应该保存集合引用,而不是在每次需要使用它时重新实例化它。

    至于您的问题,只需将每个调用的逻辑包装在其自己的函数中即可。这样你就可以创建一个闭包,它会记住每个特定查询的日期。下面我创建了一个示例,将所有结果放入一个对象中,然后当所有查询完成后,它会按顺序输出所有结果。

    var _outstanding = 0,
        _results = {};
    
    database.collection('customerData', function(err, collection) {
      for (var i = 2; i < 18; i++) {
        _outstanding++;
        getDay(collection, i, getDayCallback);
      }
    });
    
    function getDay (collection, day, callback) {
      sDay = pad(day, 2);
      eDay = pad(day + 1, 2);
    
      collection.find({ ...query obj... }).toArray(err, data) {
        var counter = 0;
        if (!err) {
          for (var point in data)
            counter += parseInt(data[point].Total_Transaction * 100);
        }
    
        callback(err, day, counter);
      });
    }
    
    function getDayCallback (err, day, count) {
      // ...actually handle any errors, of course...
      _results[day] = count;
    
      if (--_outstanding === 0) { //display the results in-order when done
        for (var i = 2; i < 18; i++)
          console.log(i, _results[i] / 100)
      }
    }
    

    在这个人为的例子中,getDaygetDayCallback 可以很容易地组合成一个函数,但在现实世界中,您很可能希望它们分开。另外,不确定218 来自哪里,但我猜它们实际上不应该像我一样被多次硬编码:)。

    【讨论】:

    • 这是完美的。谢谢!
    【解决方案2】:

    @Bret 的回答是 100% 正确的。

    我想贡献一点来展示如何通过最少的修改来转换代码以包含闭包。由于闭包在这种情况下(经常发生)非常有用,如果可能有助于了解这种模式。

    exports.graph = function(req, res) {
    
        function pad(num, size) {
            var s = num+"";
            while (s.length < size) s = "0" + s;
            return s;
        }
    
        database.collection('customerData', function(err, collection) {
    
            for (var i = 2; i < 18; i++) {
    
                sDay = pad(i, 2);
                eDay = pad(i + 1, 2);
    
                collection.find({ 
                    DATE: { 
                        $gte: sDay + 'APR13:00:00:00',
                        $lt: eDay + 'APR13:00:00:00' 
                    }
                }, (function(i){ //anonymous function which is sync-executed, bringing
                                 // 'i' to closure-scope.
                    return function(err, cursor){
                        cursor.toArray(function(err, data){
                            var counter = 0;
                            for (var point in data) {
                                trans = parseInt(data[point].Total_Transaction * 100);
                                counter += trans;
                            }
    
                            console.log(i, counter / 100);  
                        });
                    });
                }(i))
            }
        });
    }
    

    【讨论】:

    • 这太棒了!现在对我来说很有意义。谢谢!
    猜你喜欢
    • 2011-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多