Ihr Code funktioniert nicht, weil $cond
ist kein Akkumulatoroperator. Nur diese
Akkumulator-Operatoren, können in einer $group
verwendet werden Bühne.
Angenommen, Ihre Datensätze enthalten nicht mehr als zwei mögliche Werte für source
wie Sie in Ihrer Frage erwähnen, könnten Sie ein bedingtes $project
hinzufügen Stage und ändern Sie die $group
Stufe als,
Code:
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"
]
}
}
}
])
Falls es mehr als zwei mögliche Werte für die Quelle geben kann, könnten Sie Folgendes tun:
Group
durch dieid
,firstName
,lastName
undcode
. Akkumulieren Sie die eindeutigen Werte vonsource
, unter Verwendung von $addToSet Betreiber.- Verwenden Sie $redact
um nur die Werte außer
email
zu behalten . Project
die Pflichtfelder, wennsource
Array ist leer (alle Elemente wurden entfernt), fügen Sie einen Wertemail
hinzu dazu.Unwind
das Quellfeld, um es als Feld und nicht als Array aufzulisten. (optional)
Code:
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"
}
}
}
}
])