Hình thức đơn giản nhất của việc này là giữ cho mọi thứ được khóa bằng "tham số" "tên":
db.collection.aggregate(
// Unwind the array
{ "$unwind": "$parameter"},
// Group on the "_id" and "name" and $sum "value"
{ "$group": {
"_id": {
"userId": "$userId",
"name": "$parameter.name"
},
"value": { "$sum": "$parameter.value" }
}},
// Put things into an array for "nice" processing
{ "$group": {
"_id": "$_id.userId",
"values": { "$push": {
"name": "$_id.name",
"value": "$value"
}}
}}
)
Nếu bạn thực sự cần có "giá trị" của tên làm giá trị trường, bạn có thể làm như sau. Nhưng vì bạn đang "chiếu" các trường / thuộc tính nên bạn phải chỉ định tất cả chúng trong mã của bạn . Bạn không thể "năng động" nữa và bạn đang mã hóa / tạo từng cái:
db.collection.aggregate([
// Unwind the array
{ "$unwind": "$parameter"},
// Group on the "_id" and "name" and $sum "value"
{ "$group": {
"_id": {
"userId": "$userId",
"name": "$parameter.name"
},
"value": { "$sum": "$parameter.value"}
}},
// Project out discrete "field" names with $cond
{ "$project": {
"name1": { "$cond": [
{ "$eq": [ "$_id.name", "name1" ] },
"$value",
0
]},
"name2": { "$cond": [
{ "$eq": [ "$_id.name", "name2" ] },
"$value",
0
]},
"name3": { "$cond": [
{ "$eq": [ "$_id.name", "name3" ] },
"$value",
0
]},
}},
// The $cond put "0" values in there. So clean up with $group and $sum
{ "$group": {
_id: "$_id.userId",
"name1": { "$sum": "$name1" },
"name2": { "$sum": "$name2" },
"name3": { "$sum": "$name3" }
}}
])
Vì vậy, trong khi các bước bổ sung cung cấp cho bạn kết quả mà bạn muốn (tốt với một dự án cuối cùng để thay đổi _id
tới userId
), đối với tâm trí của tôi, phiên bản ngắn là đủ khả thi, trừ khi bạn thực sự cần nó. Xem xét đầu ra từ đó cũng như:
{
"_id" : ObjectId("53245016ea402b31d77b0372"),
"values" : [
{
"name" : "name3",
"value" : 2
},
{
"name" : "name2",
"value" : 0
},
{
"name" : "name1",
"value" : 150
}
]
}
Vì vậy, đó sẽ là những gì tôi sẽ sử dụng, cá nhân. Nhưng sự lựa chọn của bạn.