1

指定されたレコード ID について、MongoDB に次のものがある場合、サブドキュメント フィールドの平均を取得するにはどうすればよいですか。

/* 0 */
{
    "item" : "1",
    "samples" : [ 
        {
            "key" : "test-key",
            "value" : "1"
        }, 
        {
            "key" : "test-key2",
            "value" : "2"
        }
    ]
}

/* 1 */
{
    "item" : "1",
    "samples" : [ 
        {
            "key" : "test-key",
            "value" : "3"
        }, 
        {
            "key" : "test-key2",
            "value" : "4"
        }
    ]
}

特定のアイテム ID (この場合は 1) の key = "test-key" の値の平均を取得したいと考えています。したがって、平均は $avg (1 + 3) = 2 になります。

ありがとう

4

1 に答える 1

12

集約フレームワークを使用する必要があります。集計は次のようになります。

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、"samples" 配列内の各要素を分離するために使用されるため、それらすべてに対して操作を実行できます。そのステップだけでクエリを実行すると、私の言いたいことがわかるでしょう。簡単に言えば:

{ 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、魔法が起こる場所です。SQLの_id世界で「グループ化」する値。2 番目のフィールドは、$projectステップで定義した値の平均を示しています。$sum合計を実行するために簡単に置き換えることができますが、通常、カウント操作は次の方法で行われますmy_count : { $sum : 1 }

ここで注意すべき最も重要なことは、行われている作業の大部分は、操作が簡単に実行できるようにデータをフォーマットすることであるということです。

ファイナルノート

最後に、これは、算術演算で使用できないテキストとして定義されているため、提供されているサンプル データでは機能しないことに注意してください。samples.value興味がある場合は、フィールドのタイプを変更する方法について、MongoDB How to change the type of a fieldで説明しています。

于 2013-11-08T00:12:35.160 に答える