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 :
Grouppar l'id,firstName,lastNameetcode. Accumulez les valeurs uniques desource, en utilisant $addToSet opérateur.- Utilisez $redact
pour ne garder que les valeurs autres que
email. Projectles champs obligatoires, si lesourcele tableau est vide (tous les éléments ont été supprimés), ajoutez une valeuremailà elle.Unwindle 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"
}
}
}
}
])