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

Projeto seletivo agregado do MongoDB


Você parecia no caminho certo, existem apenas abordagens diferentes para remover esses valores de false do condicional. Você não pode fazer com que ele não retorne nada, mas você pode se livrar dos valores que não deseja.

Se você realmente deseja "conjuntos" e tem o MongoDB 2.6 ou superior disponível, basicamente filtra o false valores usando $setDifference :
db.entities.aggregate([
    { "$unwind": "$entities" },
    { "$group": {
        "_id": "$_id",
        "A": { 
            "$addToSet": {
                "$cond": [
                    { "$eq": [ "$entities.type", "A" ] },
                    "$entities.val",
                    false
                ]
            }
        },
        "B": { 
            "$addToSet": {
                "$cond": [
                    { "$eq": [ "$entities.type", "B" ] },
                    "$entities.val",
                    false
                ]
            }
        }
    }},
    { "$project": {
        "A": {
            "$setDifference": [ "$A", [false] ]
        },
        "B": {
            "$setDifference": [ "$B", [false] ]
        }
    }}
])

Ou apenas uma etapa usando o $map operador dentro de $project :
db.entities.aggregate([
    {"$project": {
        "A": {
             "$setDifference": [
                 {
                     "$map": {
                         "input": "$entities",
                         "as": "el",
                         "in": {
                             "$cond": [
                                 { "$eq": [ "$$el.type", "A" ] },
                                 "$$el.val",
                                 false
                             ]
                         }
                     }
                 },
                 [false]
             ]
         },
        "B": {
             "$setDifference": [
                 {
                     "$map": {
                         "input": "$entities",
                         "as": "el",
                         "in": {
                             "$cond": [
                                 { "$eq": [ "$$el.type", "B" ] },
                                 "$$el.val",
                                 false
                             ]
                         }
                     }
                 },
                 [false]
             ]
         }
    }}
])

Ou então fique com o $unwind e $match operadores para filtrá-los:
db.entities.aggregate([
    { "$unwind": "$entities" },
    { "$group": {
        "_id": "$_id",
        "A": { 
            "$push": {
                "$cond": [
                    { "$eq": [ "$entities.type", "A" ] },
                    "$entities.val",
                    false
                ]
            }
        },
        "B": { 
            "$push": {
                "$cond": [
                    { "$eq": [ "$entities.type", "B" ] },
                    "$entities.val",
                    false
                ]
            }
        }
    }},
    { "$unwind": "$A" },
    { "$match": { "A": { "$ne": false } } },
    { "$group": {
        "_id": "$_id",
        "A": { "$push": "$A" },
        "B": { "$first": "$B" }
    }},
    { "$unwind": "$B" },
    { "$match": { "B": { "$ne": false } } },
    { "$group": {
        "_id": "$_id",
        "A": { "$first": "$A" },
        "B": { "$push": "$B" }
    }}
])

Usando $push para matrizes normais ou $addToSet para conjuntos exclusivos.