Votre code ne fonctionne pas, car $cond
n'est pas un opérateur d'accumulateur. Seulement ces
opérateurs d'accumulateur, utilisables dans un $group
organiser.
En supposant que vos enregistrements ne contiennent pas plus de deux valeurs possibles de source
comme vous le mentionnez dans votre question, vous pouvez ajouter un $project
conditionnel mettre en scène et modifier le $group
étape comme,
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"
]
}
}
}
])
S'il peut y avoir plus de deux valeurs possibles pour la source, vous pouvez procéder comme suit :
Group
par l'id
,firstName
,lastName
etcode
. Accumulez les valeurs uniques desource
, en utilisant $addToSet opérateur.- Utilisez $redact
pour ne garder que les valeurs autres que
email
. Project
les champs obligatoires, si lesource
le tableau est vide (tous les éléments ont été supprimés), ajoutez une valeuremail
à elle.Unwind
le champ source pour le lister en tant que champ et non en tant que tableau. (facultatif)
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"
}
}
}
}
])