sql >> データベース >  >> NoSQL >> MongoDB

node.jsとmongodbでの非同期データベースクエリの処理

    さらに説明する前に、コードにバグがあることに注意してください:

    function(err_positive, result_positive) {
        result_positive.count(function(err, count){
            console.log("Total matches: " + count);
            positives[i] = count;  // <--- BUG: i id always 5 because it
        });                        //           is captured in a closure
    }
    

    古典的なクロージャーとループの問題。参照:お願いしますループでのJavaScriptクロージャの使用について説明する

    次に、ループ内で非同期関数を処理する方法について説明します。基本的な考え方は、完了した非同期呼び出しの数を追跡し、最後の呼び出しが戻ったらコードを実行する必要があるということです。例:

    var END=5;
    var counter=end;
    for (var i=0;i<END; i++) {
      collection.find(
        {value:1},
        {created_on: 
          {       
            $gte:startTime + (i*60*1000 - 30*1000),
            $lt: startTime + (i*60*1000 + 30*1000)
          }
        },
        (function(j){
          return function(err_positive, result_positive) {
            result_positive.count(function(err, count){
                console.log("Total matches: " + count);
                positives[j] = count;
            });
    
            counter--;
            if (!counter) {
              /*
               * Last result, now we have all positives.
               *
               * Add code that need to process the result here.
               *
               */
            }
          }
        })(i)
      ); 
    }
    

    ただし、これを続けていくと、一時変数の束が作成され、ひどくネストされたコードになってしまうことは明らかです。ただし、これはjavascriptであるため、このパターンのロジックを関数にカプセル化できます。これが、JavaScriptでのこの「すべてを完了するのを待つ」ロジックの実装です。node.jsでの並列実行の調整

    ただし、node.jsを使用しているため、npmから便利な非同期モジュールを使用できます。 https:// npmjs .org / package / async

    asyncを使用すると、次のようにコードを記述できます。

    var queries = [];
    
    // Build up queries:
    for (var i=0;i <5; i++) {
      queries.push((function(j){
        return function(callback) {
          collection.find(
            {value:1},
            {created_on: 
              {       
                $gte:startTime + (j*60*1000 - 30*1000),
                $lt: startTime + (j*60*1000 + 30*1000)
              }
            },
            function(err_positive, result_positive) {
              result_positive.count(function(err, count){
                console.log("Total matches: " + count);
                positives[j] = count;          
                callback();
              });
            }
    
          );
        }
      })(i));
      queries.push((function(j){
        return function(callback) {
          collection.find(
            {value:0},
            {created_on: 
              {
                $gte:startTime + (j*60*1000 - 30*1000),
                $lt: startTime + (j*60*1000 + 30*1000)
              }
            },
            function(err_negative, result_negative) {
              result_negative.count(function(err, count){
                console.log("Total matches: " + count);
                negatives[j] = count;
                callback();
              });
            }   
          );
        }
      })(i));  
    }
    
    // Now execute the queries:
    async.parallel(queries, function(){
      // This function executes after all the queries have returned
      // So we have access to the completed positives and negatives:
    
      // For example, we can dump the arrays in Firebug:
      console.log(positives,negatives);
    });
    



    1. MongoDB用のPerconaサーバーをアップグレードするためのヒント

    2. mongoでドキュメントを条件付きでアップサートするにはどうすればよいですか?

    3. Mongooseの配列のすべての値の前に文字列を追加するにはどうすればよいですか?

    4. MongoDB $ sampleRate