MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Requête MongoDB avec instruction group by conditionnelle

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 et code . Accumulez les valeurs uniques de source , en utilisant $addToSet opérateur.
  • Utilisez $redact pour ne garder que les valeurs autres que email .
  • Project les champs obligatoires, si le source le tableau est vide (tous les éléments ont été supprimés), ajoutez une valeur email à 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"
                    }
                }
            }
        }
    ])