Il tuo codice non funziona, perché $cond
non è un operatore di accumulatori. Solo questi
operatori accumulatori, possono essere usati in un $group
palcoscenico.
Supponendo che i tuoi record contengano non più di due possibili valori di source
come dici nella tua domanda, potresti aggiungere un $project
condizionale stage e modifica il $group
fase come,
Codice:
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"
]
}
}
}
])
Nel caso in cui possano esserci più di due valori possibili per l'origine, puoi procedere come segue:
Group
dall'id
,firstName
,lastName
ecode
. Accumula i valori univoci disource
, utilizzando $addToSet operatore.- Utilizza $redact
per mantenere solo i valori diversi da
email
. Project
i campi obbligatori, se ilsource
l'array è vuoto (tutti gli elementi sono stati rimossi), aggiungi un valoreemail
ad esso.Unwind
il campo sorgente per elencarlo come campo e non come array.(opzionale)
Codice:
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"
}
}
}
}
])