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

mongodb:特定の列の合計がC以上である最初の数行をクエリします

    クエリ

    集約フレームワークを使用して実行できます。 。次の集約パイプラインを検討してください

    db.collectionName.aggregate([
      {
        $group: 
          { 
            "_id": null, 
            "ds": { $push: "$$ROOT" }, 
            "cs": { $push: "$c" } 
          } 
      }, /* (1) */
      { $unwind: "$ds" }, /* (2) */
      { 
        $project: 
          { 
            "_id": "$ds._id", 
            "c": "$ds.c", 
            "cs": { $slice: [ "$cs", "$ds._id" ] } 
          } 
      }, /* (3):  */
      { $unwind: "$cs" },  /* (4) */
      { 
        $group: 
          { 
            "_id": "$_id", 
            "c": { $first: "$c" }, 
            "csum": { $sum: "$cs" } 
          } 
      }, /* (5) */
      { 
        $group: 
          { 
            "_id": null, 
            "ds": { $push: "$$ROOT" }, 
            "gteC": 
              { 
                $push: 
                  { 
                    $cond: 
                      { 
                        if: { "$gte": [ "$csum", SET_DESIRED_VALUE_FOR_C_HERE ] }, 
                        then: "$$ROOT", 
                        else: { } 
                      } 
                  } 
    
              } 
          } 
      }, /* (6) */
      { 
        $project: 
          { 
            "_id": 0,
            "docs": 
              { 
                $filter: 
                  { 
                    input: "$ds", 
                    "as": "doc", 
                    cond: { $lte: [ "$$doc.csum", { $min: "$gteC.csum" } ] }
                  }
              }
          }
      }, /* (7) */
      { $unwind: "$docs" }, /* (8) */ 
      { $project: { "_id": "$docs._id", "c": "$docs.c" } } /* (9) */
    ]);
    

    結果

    説明

    その背後にある基本的な考え方は、ヘルパー配列を構築することです。 コレクション内のドキュメントごとに( ステージ1〜3

    { "_id" : 1, "c" : 2 } -> cs = [ 2 ]
    { "_id" : 2, "c" : 6 } -> cs = [ 2, 6 ]
    { "_id" : 3, "c" : 1 } -> cs = [ 2, 6, 1 ]
    

    $sliceを使用する 配列集計演算子 次に、含まれているすべての要素の合計に置き換えます(ステージ4-5

    { "_id" : 1, "c" : 2 } -> csum = 2
    { "_id" : 2, "c" : 6 } -> csum = 8
    { "_id" : 3, "c" : 1 } -> csum = 9
    

    $unwindを使用する ステージと $sum グループアキュムレータ演算子

    次に、csum >= Cを使用してドキュメントの別のヘルパー配列を作成します (ステージ6

    /* Ex. (C = 8) */
    gteC = [ { "_id" : 3, "c" : 1, "csum" : 9 }, { "_id" : 2, "c" : 6, "csum" : 8 } ]
    

    最後のステップは、csum <= Min { gteC.csum }のすべてのドキュメントを取得することです。 。これは、 $filterを使用して行われます。 配列集計演算子ステージ7

    しかし、私はではありません これが最も効率的であることを確認してください 必要なことを達成するための集約パイプライン(改善の提案に感謝します)。

    PS クエリをテストする前に、コレクションの名前を変更し、SET_DESIRED_VALUE_FOR_C_HEREを置き換えることを忘れないでください。




    1. MongoDB update()

    2. mongodbは、更新時に空のフィールドを無期限に削除しました

    3. URL Fetchサービスを使用して非推奨のScriptDbをMongodbに置き換える方法は?

    4. MongoDBとGolangを使用したルックアップの参照で値を取得します