簡體   English   中英

在 NodeJS 中存儲來自多個 MongoDB 查詢的數據

[英]Storing Data From Multiple MongoDB Queries in NodeJS

好吧,我認為如果我只是復制我的整個 node.js 路由會更容易,這樣你就可以看到我在說什么。

我正在嘗試對我的 MongoDB 數據庫進行多個查詢(每天一個)。 查詢運行良好,但是當它們觸發回調時,我的 incrementor 變量已經增加了。

所以為此:

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

這(顯然)並不理想 - 數字不一定按照查詢被觸發的順序返回,所以弄清楚哪些去哪里對我來說很重要。

我想不出一種方法來以有意義的方式將我的算術結果存儲在查詢回調中,以便我以后可以使用它。

有什么想法嗎?

附帶說明一下,與您的示例和我下面的示例不同,您確實應該保存集合引用,而不是每次需要使用它時都重新實例化它。

至於您的問題,只需將每個調用的邏輯包裝在自己的函數中即可。 這樣你就創建了一個閉包,它記住每個特定查詢是針對哪一天的。 下面我創建了一個示例,其中將所有結果放入一個對象中,然后當所有查詢完成后,它會按順序輸出所有結果。

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來自哪里,但我猜它們實際上不應該像我那樣多次硬編碼:)。

@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))
        }
    });
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM