28

次の構造を持つ「投稿」というコレクションがあると仮定します (実際には、より複雑なコレクションであり、投稿は単純すぎます)。

> db.posts.find()

{ "_id" : ObjectId("50ad8d451d41c8fc58000003"), "title" : "Lorem ipsum", "author" : 
"John Doe", "content" : "This is the content", "tags" : [ "SOME", "RANDOM", "TAGS" ] }

このコレクションは数十万、おそらく数百万に及ぶと予想されるため、タグで投稿をクエリし、結果をタグでグループ化し、結果をページ分割して表示する必要があります。ここで、集約フレームワークの出番です。私は、aggregate() メソッドを使用してコレクションを照会する予定です。

db.posts.aggregate([
  { "$unwind" : "$tags" },
  { "$group" : {
      _id: { tag: "$tags" },
      count: { $sum: 1 }
  } }
]);

問題は、ページネーターを作成するには、出力配列の長さを知る必要があることです。私はあなたができることを知っています:

db.posts.aggregate([
  { "$unwind" : "$tags" },
  { "$group" : {
      _id: { tag: "$tags" },
      count: { $sum: 1 }
  } }
  { "$group" : {
      _id: null,
      total: { $sum: 1 }
  } }
]);

ただし、それは前のパイプライン (最初のグループ) からの出力を破棄します。各パイプラインの出力を保持しながら、2 つの操作を組み合わせる方法はありますか? 集計操作全体の出力を一部の言語で配列にキャストして内容をカウントできることはわかっていますが、パイプライン出力が 16Mb の制限を超える可能性があります。また、カウントを取得するためだけに同じクエリを実行するのは無駄に思えます。

ドキュメントの結果とカウントを同時に取得することは可能ですか? どんな助けでも大歓迎です。

4

2 に答える 2

34
  1. $project保存tagして使用countするtmp
  2. $pushまたはを使用してリストaddToSetに保存tmpしますdata

コード:

db.test.aggregate(
    {$unwind: '$tags'}, 
    {$group:{_id: '$tags', count:{$sum:1}}},
    {$project:{tmp:{tag:'$_id', count:'$count'}}}, 
    {$group:{_id:null, total:{$sum:1}, data:{$addToSet:'$tmp'}}}
)

出力:

{
    "result" : [
            {
                    "_id" : null,
                    "total" : 5,
                    "data" : [
                            {
                                    "tag" : "SOME",
                                    "count" : 1
                            },
                            {
                                    "tag" : "RANDOM",
                                    "count" : 2
                            },
                            {
                                    "tag" : "TAGS1",
                                    "count" : 1
                            },
                            {
                                    "tag" : "TAGS",
                                    "count" : 1
                            },
                            {
                                    "tag" : "SOME1",
                                    "count" : 1
                            }
                      ]
              }
      ],
      "ok" : 1
}
于 2012-11-24T02:55:20.640 に答える
3

すべてのタグをカウントする以外に、これに集約フレームワークが必要かどうかはわかりません。

db.posts.aggregate(
  { "unwind" : "$tags" },
  { "group" : {
      _id: { tag: "$tags" },
      count: { $sum: 1 }
  } }
);

タグごとにページ分割するには、通常のクエリ構文を使用できます-次のように:

db.posts.find({tags: "RANDOM"}).skip(10).limit(10)
于 2012-11-23T13:59:49.160 に答える