Dường như bạn đã đi đúng hướng, chỉ có các cách tiếp cận khác nhau để xóa các giá trị false
đó từ điều kiện. Bạn không thể để nó không trả lại gì, nhưng bạn sẽ loại bỏ những giá trị mà bạn không muốn.
Nếu bạn thực sự muốn "bộ" và bạn có sẵn MongoDB 2.6 hoặc cao hơn, thì về cơ bản bạn lọc ra false
các giá trị sử dụng $ setDifference
:
db.entities.aggregate([
{ "$unwind": "$entities" },
{ "$group": {
"_id": "$_id",
"A": {
"$addToSet": {
"$cond": [
{ "$eq": [ "$entities.type", "A" ] },
"$entities.val",
false
]
}
},
"B": {
"$addToSet": {
"$cond": [
{ "$eq": [ "$entities.type", "B" ] },
"$entities.val",
false
]
}
}
}},
{ "$project": {
"A": {
"$setDifference": [ "$A", [false] ]
},
"B": {
"$setDifference": [ "$B", [false] ]
}
}}
])
Hoặc chỉ bằng một bước sử dụng $ map
toán tử bên trong $ project
:
db.entities.aggregate([
{"$project": {
"A": {
"$setDifference": [
{
"$map": {
"input": "$entities",
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el.type", "A" ] },
"$$el.val",
false
]
}
}
},
[false]
]
},
"B": {
"$setDifference": [
{
"$map": {
"input": "$entities",
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el.type", "B" ] },
"$$el.val",
false
]
}
}
},
[false]
]
}
}}
])
Hoặc nếu không thì ở lại với $ unwind
và $ match
toán tử để lọc các toán tử này:
db.entities.aggregate([
{ "$unwind": "$entities" },
{ "$group": {
"_id": "$_id",
"A": {
"$push": {
"$cond": [
{ "$eq": [ "$entities.type", "A" ] },
"$entities.val",
false
]
}
},
"B": {
"$push": {
"$cond": [
{ "$eq": [ "$entities.type", "B" ] },
"$entities.val",
false
]
}
}
}},
{ "$unwind": "$A" },
{ "$match": { "A": { "$ne": false } } },
{ "$group": {
"_id": "$_id",
"A": { "$push": "$A" },
"B": { "$first": "$B" }
}},
{ "$unwind": "$B" },
{ "$match": { "B": { "$ne": false } } },
{ "$group": {
"_id": "$_id",
"A": { "$first": "$A" },
"B": { "$push": "$B" }
}}
])
Sử dụng $ push
cho mảng bình thường hoặc $ addToSet
cho các bộ duy nhất.