すぐには見えませんが、可能です。ここで行う必要があるのは、トップレベルのドキュメントを複製せずにコメントの配列と結合することです。これは、最初にコンテンツを2つの配列として単一の配列に結合し、次に $ unwind
コンテンツをグループ化するには:
db.collection.aggregate([
{ "$group": {
"_id": "$_id",
"author": {
"$addToSet": {
"id": "$_id",
"author": "$author",
"votes": "$votes"
}
},
"comments": { "$first": "$comments" }
}},
{ "$project": {
"combined": { "$setUnion": [ "$author", "$comments" ] }
}},
{ "$unwind": "$combined" },
{ "$group": {
"_id": "$combined.author",
"votes": { "$sum": "$combined.votes" }
}},
{ "$sort": { "votes": -1 } }
])
これにより、出力が得られます:
{ "_id" : "Jesse", "votes" : 148 }
{ "_id" : "Mirek", "votes" : 135 }
{ "_id" : "Leszke", "votes" : 13 }
最初の $ group
>
ステージングし、結合された配列を別の方法で作成します:
db.collection.aggregate([
{ "$project": {
"combined": {
"$setUnion": [
{ "$map": {
"input": { "$literal": ["A"] },
"as": "el",
"in": {
"author": "$author",
"votes": "$votes"
}
}},
"$comments"
]
}
}},
{ "$unwind": "$combined" },
{ "$group": {
"_id": "$combined.author",
"votes": { "$sum": "$combined.votes" }
}},
{ "$sort": { "votes": -1 } }
])
これらは、 $ setUnion
>
さらに、 $ map
これはMongoDB2.6以降に導入されました。これにより簡単になりますが、ほとんど同じ原則に従って、これらの演算子がない以前のバージョンでも実行できます。
db.collection.aggregate([
{ "$project": {
"author": 1,
"votes": 1,
"comments": 1,
"type": { "$const": ["A","B"] }
}},
{ "$unwind": "$type" },
{ "$unwind": "$comments" },
{ "$group": {
"_id": {
"$cond": [
{ "$eq": [ "$type", "A" ] },
{
"id": "$_id",
"author": "$author",
"votes": "$votes"
},
"$comments"
]
}
}},
{ "$group": {
"_id": "$_id.author",
"votes": { "$sum": "$_id.votes" }
}},
{ "$sort": { "votes": -1 } }
])
$ const
文書化されていませんが、集約フレームワークが存在するすべてのバージョンのMongoDBに存在します(2.2以降)。 MongoDB2.6で $literal
が導入されました
これは基本的に同じ基礎となるコードにリンクしています。ここでは、配列のテンプレート要素を提供するため、または2つのアクション間の「バイナリ選択」を提供するために配列をアンワインドするために導入するために2つのケースで使用されています。