MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Consulta MongoDB com grupo condicional por instrução


Seu código não funciona porque $cond não é um operador de acumulador. Apenas estes operadores de acumulador, podem ser usados ​​em um $group palco.

Supondo que seus registros não contenham mais de dois valores possíveis de source como você menciona em sua pergunta, você pode adicionar um $project condicional preparar e modificar o $group estágio como,

Código:
    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"
                    ]
                }
            }
        }
    ])

Caso haja mais de dois valores possíveis para a fonte, você pode fazer o seguinte:
  • Group pelo id , firstName , lastName e code . Acumule os valores exclusivos de source , usando o $addToSet operador.
  • Use $redact para manter apenas os valores diferentes de email .
  • Project os campos obrigatórios, se o source array está vazio (todos os elementos foram removidos), adicione um valor email para ele.
  • Unwind o campo de origem para listá-lo como um campo e não como uma matriz.(opcional)

Código:
    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"
                    }
                }
            }
        }
    ])