2017-08-29 11 views
0

MongoDBの集計クエリに問題があります。オブジェクトの配列を含むドキュメントとの集約クエリ

[{ 
    "_id": ObjectId("19a5070b808028108101"), 
    "arr_vs": [ 
    { 
     "arr_id": "one", 
     "val": 5 
    }, 
    { 
     "arr_id": "two", 
     "val": 5 
    }] 
}, 
{ 
    "_id": ObjectId("19a5070b80802810810"), 
    "arr_vs": [ 
    { 
     "arr_id": "one", 
     "val": 5 
    }, 
    { 
     "arr_id": "two", 
     "val": 2 
    },{ 
     "arr_id": "three", 
     "val": 1 
    }] 
}] 

私はarr_vs項目に関連付けられた各値のカウントをしたい:

は、私は次のような構造で文書を持っています。

予想される出力:

{ 
    "arr_vs":{ 
     "one":[ 
      { 
       "val":5, 
       "total_count":2 
      },{ 
       "val":2, 
       "total_count": 
      } 
     }], 
     "two":[ 
      { 
       "val":5, 
       "total_count":2 
      },{ 
       "val":2, 
       "total_count": 
      } 
     }] 
    } 
} 

すべてのヘルプは理解されるであろう。

答えて

0

名前付きキーへの出力は、実際には思っているような素晴らしいものではありません。現実的には、私は通常、返された結果を扱いたいので、 "リスト/配列"はもっと意味があります。

これは、基本的には基本的に彼らの「という名前のキー」のコンセプトを放棄するように言われます、すべての新しい人です、そして、彼らは、データベースと名付けられたキーに固有の問題で作業している実感します。収集が本質的に「リスト」である理由の種類。

ですから、考え方に慣れる方が良いでしょう:基本的にはあなたを与えるために起こっている

db.collection.aggregate([ 
    { "$unwind": "$arr_vs" }, 
    { "$group": { 
    "_id": { "id": "$arr_vs.arr_id", "val": "$arr_vs.val" }, 
    "total_count": { "$sum": 1 } 
    }}, 
    { "$group": { 
    "_id": "$_id.id", 
    "v": { 
     "$push": { 
     "val": "$_id.val", 
     "total_count": "$total_count" 
     } 
    } 
    }} 
]) 

/* 1 */ 
{ 
    "_id" : "two", 
    "v" : [ 
     { 
      "val" : 2.0, 
      "total_count" : 1.0 
     }, 
     { 
      "val" : 5.0, 
      "total_count" : 1.0 
     } 
    ] 
} 

/* 2 */ 
{ 
    "_id" : "one", 
    "v" : [ 
     { 
      "val" : 5.0, 
      "total_count" : 2.0 
     } 
    ] 
} 

/* 3 */ 
{ 
    "_id" : "three", 
    "v" : [ 
     { 
      "val" : 1.0, 
      "total_count" : 1.0 
     } 
    ] 
} 

そして反復可能で使いやすいで集計されたデータであります形。

あなたの出力形式に熱心であり、少なくともMongoDBの3.4.4バージョンを持っている場合は、文書を圧縮し、$arrayToObjectを使用して、そのさらに取ることができます:

db.collection.aggregate([ 
    { "$unwind": "$arr_vs" }, 
    { "$group": { 
    "_id": { "id": "$arr_vs.arr_id", "val": "$arr_vs.val" }, 
    "total_count": { "$sum": 1 } 
    }}, 
    { "$group": { 
    "_id": "$_id.id", 
    "v": { 
     "$push": { 
     "val": "$_id.val", 
     "total_count": "$total_count" 
     } 
    } 
    }}, 
    { "$group": { 
    "_id": null, 
    "arr_vs": { 
     "$push": { 
     "k": "$_id", 
     "v": "$v"  
     } 
    } 
    }}, 
    { "$project": { 
    "_id": 0, 
    "arr_vs": { "$arrayToObject": "$arr_vs" } 
    }} 
]) 

あるいは単に「最終の適用

db.collection.aggregate([ 
    { "$unwind": "$arr_vs" }, 
    { "$group": { 
    "_id": { "id": "$arr_vs.arr_id", "val": "$arr_vs.val" }, 
    "total_count": { "$sum": 1 } 
    }}, 
    { "$group": { 
    "_id": "$_id.id", 
    "v": { 
     "$push": { 
     "val": "$_id.val", 
     "total_count": "$total_count" 
     } 
    } 
    }}, 
    { "$group": { 
    "_id": null, 
    "arr_vs": { 
     "$push": { 
     "k": "$_id", 
     "v": "$v"  
     } 
    } 
    }}, 
    /* 
    { "$project": { 
    "_id": 0, 
    "arr_vs": { "$arrayToObject": "$arr_vs" } 
    }} 
    */ 
]).map(d => ({ 
    "arr_vs": d.arr_vs.reduce((acc,curr) => 
    Object.assign(acc,({ [curr.k]: curr.v })),{})  
})) 

そして、両者が同じ出力を生成:

{ 
     "arr_vs" : { 
      "two" : [ 
       { 
        "val" : 2.0, 
        "total_count" : 1.0 
       }, 
       { 
        "val" : 5.0, 
        "total_count" : 1.0 
       } 
      ], 
      "one" : [ 
       { 
        "val" : 5.0, 
        "total_count" : 2.0 
       } 
      ], 
      "three" : [ 
       { 
        "val" : 1.0, 
        "total_count" : 1.0 
       } 
      ] 
     } 
    } 
0123をお使いのMongoDBのバージョンが新しい演算子をサポートしていない場合は、」クライアント側の形状を変更
関連する問題