MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Query MongoDB con gruppo condizionale per istruzione

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 e code . Accumula i valori univoci di source , utilizzando $addToSet operatore.
  • Utilizza $redact per mantenere solo i valori diversi da email .
  • Project i campi obbligatori, se il source l'array è vuoto (tutti gli elementi sono stati rimossi), aggiungi un valore email 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"
                    }
                }
            }
        }
    ])