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

MongoDB-集約フレームワーク(総数)

    プッシュとスライスを使用した解決策があります: https://stackoverflow.com/a/39784851/4752635 (@emaniacsはここでもそれについて言及しています。)

    しかし、私は2つのクエリを使用することを好みます。 $$ROOTをプッシュして$sliceを使用するソリューションでは、大規模なコレクションの場合、ドキュメントメモリの制限が16MBになります。また、大規模なコレクションの場合、2つのクエリを一緒にすると、$$ROOTをプッシュするクエリよりも高速に実行されるようです。それらを並行して実行することもできるので、2つのクエリのうち遅い方(おそらくソートするクエリ)によってのみ制限されます。

    1. 最初にフィルタリングし、次にIDでグループ化して、フィルタリングされた要素の数を取得します。ここではフィルタリングしないでください。不要です。
    2. フィルタリング、並べ替え、ページ分割を行う2番目のクエリ。

    2つのクエリと集計フレームワークを使用してこのソリューションを決定しました(注-この例ではnode.jsを使用しています):

    var aggregation = [
      {
        // If you can match fields at the begining, match as many as early as possible.
        $match: {...}
      },
      {
        // Projection.
        $project: {...}
      },
      {
        // Some things you can match only after projection or grouping, so do it now.
        $match: {...}
      }
    ];
    
    
    // Copy filtering elements from the pipeline - this is the same for both counting number of fileter elements and for pagination queries.
    var aggregationPaginated = aggregation.slice(0);
    
    // Count filtered elements.
    aggregation.push(
      {
        $group: {
          _id: null,
          count: { $sum: 1 }
        }
      }
    );
    
    // Sort in pagination query.
    aggregationPaginated.push(
      {
        $sort: sorting
      }
    );
    
    // Paginate.
    aggregationPaginated.push(
      {
        $limit: skip + length
      },
      {
        $skip: skip
      }
    );
    
    // I use mongoose.
    
    // Get total count.
    model.count(function(errCount, totalCount) {
      // Count filtered.
      model.aggregate(aggregation)
      .allowDiskUse(true)
      .exec(
      function(errFind, documents) {
        if (errFind) {
          // Errors.
          res.status(503);
          return res.json({
            'success': false,
            'response': 'err_counting'
          });
        }
        else {
          // Number of filtered elements.
          var numFiltered = documents[0].count;
    
          // Filter, sort and pagiante.
          model.request.aggregate(aggregationPaginated)
          .allowDiskUse(true)
          .exec(
            function(errFindP, documentsP) {
              if (errFindP) {
                // Errors.
                res.status(503);
                return res.json({
                  'success': false,
                  'response': 'err_pagination'
                });
              }
              else {
                return res.json({
                  'success': true,
                  'recordsTotal': totalCount,
                  'recordsFiltered': numFiltered,
                  'response': documentsP
                });
              }
          });
        }
      });
    });
    


    1. ネストされたオブジェクトを使用したMongooseJSでの$inの使用

    2. mongodbを呼び出すazure関数(ノード)はエラーなしで終了しますが、クエリから何も返されません

    3. javaプロジェクトでmongoDBmap/reduce関数を記述して保存する場所

    4. phpでアップサートした後にmongodb_idオブジェクトを取得します