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

mongoDB:como reverter $ unwind


Há um truque específico para lidar com isso, mas primeiro, se você tiver o MongoDB 2.6 ou superior disponível, poderá fazer o que quiser sem usar $unwind . Isso pode ser muito útil para o desempenho se você estiver processando muitos documentos.

Os principais operadores aqui são $map que processa arrays no local e o $allElementsTrue operador que avaliará seus campos de "resultado". O uso de "map" aqui permite tanto o teste do array "tests" interno para ver onde os campos "result" ali atendem à condição verdadeira. No caso da matriz externa, esse "resultado" pode ser colocado nesses documentos conforme você precisar e, é claro, a avaliação completa do documento segue as mesmas regras:
db.test.aggregate([
    { "$project": {
        "name": 1,
        "result": {
            "$allElementsTrue": {
                "$map": {
                    "input": "$acts",
                    "as": "act",
                    "in": {
                        "$allElementsTrue": {
                            "$map": {
                                 "input": "$$act.tests",
                                 "as": "test",
                                 "in": "$$test.result"
                            }
                        }
                    }
                }
            }
        },
        "acts": {
            "$map": {
                 "input": "$acts",
                 "as": "act",
                 "in": {
                    "name": "$$act.name",
                    "result": {
                        "$allElementsTrue": {
                            "$map": {
                                "input": "$$act.tests",
                                "as": "test",
                                "in": "$$test.result"
                            }
                        }
                    },
                    "tests": "$$act.tests"
                 }
            }
        }
    }}
])

A maneira de fazer isso em versões anteriores exige que você $grupo de volta em duas etapas para "reconstruir" as matrizes enquanto faz os testes nesses campos de "resultado" novamente. A outra diferença aqui também é usar o $min operador como false será considerado um valor menor que true e avalia para o mesmo conceito "allElements":
db.test.aggregate([
    { "$unwind": "$acts" },
    { "$unwind": "$acts.tests" },
    { "$group": {
        "_id": {
            "_id": "$_id",
            "name": "$name",
            "actName": "$acts.name"
        },
        "result": { "$min": "$acts.tests.result" },
        "tests": {
           "$push": {
               "name": "$acts.tests.name",
               "result": "$acts.tests.result"
           }
        }
    }},
    { "$group": {
        "_id": "$_id._id",
        "name": { "$first": "$_id.name" },
        "result": { "$min": "$result" },
        "acts": {
            "$push": {
                "name": "$_id.actName",
                "result": "$result",
                "tests": "$tests"
            }
        }
    }}
])