集約フレームワークを使用する必要があります。集計は次のようになります。
db.stack.aggregate([
{ $match: { "samples.key" : "test-key" } },
{ $unwind : "$samples" },
{ $match : { "samples.key" : "test-key" } },
{ $project : { "new_key" : "$samples.key", "new_value" : "$samples.value" } },
{ $group : { `_id` : "$new_key", answer : { $avg : "$new_value" } } }
])
集約フレームワークを考える最良の方法は、組立ラインのようなものです。クエリ自体はJSONドキュメントの配列であり、各サブドキュメントはアセンブリの異なるステップを表します。
ステップ1:$ match
最初のステップは、SQLのWHERE句のような基本的なフィルターです。このステップを最初に配置して、test-key
を含む配列要素を含まないすべてのドキュメントを除外します。 。これをパイプラインの先頭に配置すると、集計でインデックスを使用できるようになります。
ステップ2:$ unwind
2番目のステップ、$unwind
は、「サンプル」配列内の各要素を分離するために使用されるため、すべての要素に対して操作を実行できます。そのステップだけでクエリを実行すると、私が何を意味するのかがわかります。簡単に言えば:
{ name : "bob",
children : [ {"name" : mary}, { "name" : "sue" } ]
}
2つのドキュメントになります:
{ name : "bob", children : [ { "name" : mary } ] }
{ name : "bob", children : [ { "name" : sue } ] }
ステップ3:$ match
3番目のステップ、$match
、は最初の$match
の正確な複製です ステージですが、目的は異なります。 $unwind
に続くので 、このステージでは、フィルター基準に一致しない以前の配列要素(現在はドキュメント)がフィルターで除外されます。この場合、samples.key = "test-key"
のドキュメントのみを保持します
ステップ4:$ project(オプション)
4番目のステップ、$project
、ドキュメントを再構築します。この場合、アイテムを配列から取り出して、直接参照できるようにしました。上記の例を使用して..
{ name : "bob", children : [ { "name" : mary } ] }
になります
{ new_name : "bob", new_child_name : mary }
このステップは完全にオプションであることに注意してください。この$project
がなくても、後の段階を完了することができます。 いくつかの小さな変更の後。ほとんどの場合、$project
完全に化粧品です。集計には、$project
のフィールドを手動で含めたり除外したりするなど、内部で多数の最適化が行われます。 必要ないはずです。
ステップ5:$ group
最後に、$group
魔法が起こる場所です。 _id
SQLの世界で「グループ化」するものを評価します。 2番目のフィールドは、$project
で定義した値を平均することを示しています。 ステップ。 $sum
は簡単に置き換えることができます 合計を実行しますが、カウント操作は通常、次の方法で実行されます。my_count : { $sum : 1 }
。
ここで注意すべき最も重要なことは、実行される作業の大部分は、操作の実行が簡単になるポイントにデータをフォーマットすることであるということです。
ファイナルノート
最後に、これはではないことに注意したいと思います。 samples.value
以降に提供されたサンプルデータで作業する はテキストとして定義されており、算術演算では使用できません。興味がある場合は、フィールドのタイプの変更についてここで説明します:MongoDBフィールドのタイプを変更する方法