MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

MongoDB-Abfrage mit bedingter Group by-Anweisung

Ihr Code funktioniert nicht, weil $cond ist kein Akkumulatoroperator. Nur diese Akkumulator-Operatoren, können in einer $group verwendet werden Bühne.

Angenommen, Ihre Datensätze enthalten nicht mehr als zwei mögliche Werte für source wie Sie in Ihrer Frage erwähnen, könnten Sie ein bedingtes $project hinzufügen Stage und ändern Sie die $group Stufe als,

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"
                    ]
                }
            }
        }
    ])

Falls es mehr als zwei mögliche Werte für die Quelle geben kann, könnten Sie Folgendes tun:

  • Group durch die id , firstName , lastName und code . Akkumulieren Sie die eindeutigen Werte von source , unter Verwendung von $addToSet Betreiber.
  • Verwenden Sie $redact um nur die Werte außer email zu behalten .
  • Project die Pflichtfelder, wenn source Array ist leer (alle Elemente wurden entfernt), fügen Sie einen Wert email hinzu dazu.
  • Unwind das Quellfeld, um es als Feld und nicht als Array aufzulisten. (optional)

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"
                    }
                }
            }
        }
    ])