Không thể nhìn thấy ngay lập tức nhưng có thể. Những gì bạn cần làm ở đây là kết hợp tài liệu cấp cao nhất của bạn với mảng nhận xét mà không sao chép nó. Đây là cách tiếp cận để đầu tiên nối nội dung dưới dạng hai mảng thành một mảng số ít, sau đó $ unwind
để nhóm nội dung:
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 } }
])
Điều này cho kết quả:
{ "_id" : "Jesse", "votes" : 148 }
{ "_id" : "Mirek", "votes" : 135 }
{ "_id" : "Leszke", "votes" : 13 }
Ngay cả khi bỏ qua $ group
giai đoạn và tạo một mảng kết hợp theo một cách khác:
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 } }
])
Các toán tử đó sử dụng các toán tử như $ setUnion
và thậm chí $ map
được giới thiệu kể từ MongoDB 2.6. Điều này làm cho nó trở nên đơn giản hơn, nhưng nó vẫn có thể được thực hiện trong các phiên bản trước đó thiếu các toán tử đó, tuân theo các nguyên tắc giống nhau:
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
là không có tài liệu nhưng có mặt trong tất cả các phiên bản của MongoDB có khung tổng hợp (từ 2.2). MongoDB 2.6 Được giới thiệu $ đen
về cơ bản liên kết đến cùng một mã cơ bản. Nó được sử dụng trong hai trường hợp ở đây để cung cấp phần tử mẫu cho một mảng hoặc để giới thiệu một mảng để giải phóng để cung cấp "lựa chọn nhị phân" giữa hai hành động.