Вашият код не работи, защото $cond
не е акумулаторен оператор. Само тези
акумулиращи оператори, могат да се използват в $group
сцена.
Ако приемем, че вашите записи съдържат не повече от две възможни стойности на source
както споменахте във въпроса си, можете да добавите условен $project
етап и модифицирайте $group
етап като,
Код:
db.customer.aggregate([
{
$group: {
"_id": {
"id": "$id",
"firstName": "$firstName",
"lastName": "$lastName",
"code": "$code"
},
"sourceA": { $first: "$source" },
"sourceB": { $last: "$source" }
}
},
{
$project: {
"source": {
$cond: [
{ $eq: ["$sourceA", "email"] },
"$sourceB",
"$sourceA"
]
}
}
}
])
В случай че може да има повече от две възможни стойности за източник, можете да направите следното:
Group
чрезid
,firstName
,lastName
иcode
. Натрупвайте уникалните стойности наsource
, използвайки $addToSet оператор.- Използвайте $redact
за да запазите само стойностите, различни от
email
. Project
задължителните полета, акоsource
масивът е празен (всички елементи са премахнати), добавете стойностemail
към него.Unwind
полето източник, за да го посочи като поле, а не като масив. (по избор)
Код:
db.customer.aggregate([
{
$group: {
"_id": {
"id": "$id",
"firstName": "$firstName",
"lastName": "$lastName",
"code": "$code"
},
"sourceArr": { $addToSet: { "source": "$source" } }
}
},
{
$redact: {
$cond: [
{ $eq: [{ $ifNull: ["$source", "other"] }, "email"] },
"$$PRUNE",
"$$DESCEND"
]
}
},
{
$project: {
"source": {
$map: {
"input":
{
$cond: [
{ $eq: [{ $size: "$sourceArr" }, 0] },
[{ "source": "item" }],
"$sourceArr"]
},
"as": "inp",
"in": "$$inp.source"
}
}
}
}
])