Din kod fungerar inte eftersom $cond
är inte en ackumulatoroperatör. Endast dessa
ackumulatoroperatorer, kan användas i en $group
skede.
Förutsatt att dina poster inte innehåller fler än två möjliga värden för source
som du nämner i din fråga, kan du lägga till ett villkorligt $project
steg och ändra $group
steg som,
Kod:
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"
]
}
}
}
])
Om det kan finnas fler än två möjliga värden för källa, kan du göra följande:
Group
medid
,firstName
,lastName
ochcode
. Ackumulera de unika värdena försource
, med hjälp av $addToSet operatör.- Använd $redact
för att bara behålla andra värden än
email
. Project
de obligatoriska fälten, omsource
arrayen är tom (alla element har tagits bort), lägg till avalueemail
till det.Unwind
källfältet för att lista det som ett fält och inte en array.(valfritt)
Kod:
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"
}
}
}
}
])