0

mongoDB の集計について教えてください。次にやりたいことは次のとおりです。

コレクションがありAます。からのドキュメントはA、次のようなオブジェクトを表します。

{
  nameA: 'first',
  items: [
    'item1',
    'item2',
    'item3',
    'item4'
  ]
}

そして、次のBようなドキュメントを含むコレクションがあります。

[
    {
      item: 'item3',
      info: 'info1'
    },
    {
      item: 'item3',
      info: 'info2'
    },
    {
      item: 'item3',
      info: 'info3'
    }
]

私はビッグデータを扱っているので、1 つのクエリで処理する方がよいでしょう。コレクション A のすべてのデータが既にあるとします。次の構造結果を取得するために、コレクション B に対してクエリを作成したいと思います。

{
    'first'/*nameA*/: ['info1', 'info2', 'info3'],
    ....
}

MongoDB アグリゲーションで望ましい結果を得るにはどうすればよいですか?

4

1 に答える 1

1

Rahul Kumar がコメントで述べたように、あなたの設計はリレーショナル データベース スキーマ設計に傾倒しており、効率的な MongoDB を設計することは非常に困難です。

$lookupただし、次のように集約フレームワークのステージを活用することで、探している機能を実現することは可能です。

db.A.aggregate([
    {
        $unwind: {
            path: "$items"
        }
    },
    { 
        $lookup: {
            from: "B",
            localField: "items",
            foreignField: "item",
            as: "item_info"
        }
    },

    {
        $unwind: {
            path: "$item_info"
        }
    },

    {
        $group: {
            _id: "$nameA",
            item_info: { $addToSet: "$item_info.info" }
        }
    }
]);
  1. 最初の段階では、その出力を次の段階に渡すことができるように、配列 $unwindを正規化しますitemscollection A

  2. ステージでは$lookup、同じデータベースの一部である 2 つのコレクション間で左結合を行います。この場合、アイテム情報を取得するために使用されます。collection B

  3. 第 2$unwind段階では、抽出したデータを正規化してcollection B、オブジェクトを含む配列をフラット化し、そのオブジェクトcollection Bが対応するアイテムにマップされました。collection A

  4. 最後に、$groupステージで結果セットのすべてのエントリをグループ化し、nameA一意のアイテム情報値の配列を作成します。重複するアイテム情報値をすべて取得したい場合は、$addToSet accumulator を に置き換えることができます$push

以下は、提供したコレクションに対して上記の集計パイプラインを実行した結果です。

{ "_id" : "second", "item_info" : [ "info3", "info2", "info1" ] }
{ "_id" : "first", "item_info" : [ "info3", "info2", "info1" ] }
于 2016-09-23T08:36:49.007 に答える