sql >> Databasteknik >  >> NoSQL >> MongoDB

mongoDB:hur man vänder $unwind

Det finns ett speciellt knep för hur detta hanteras, men för det första om du har MongoDB 2.6 eller senare tillgängligt så kan du faktiskt göra vad du vill utan att använda $unwind . Detta kan vara mycket praktiskt för prestanda om du bearbetar många dokument.

Nyckeloperatorerna här är $map som behandlar arrayer på plats och $allElementsTrue operatör som kommer att utvärdera dina "resultat"-fält. Användningen av "karta" här tillåter både testning av den inre "test"-arrayen för att se var "resultat"-fälten där alla uppfyller det sanna villkoret. I det yttre arrayfallet kan detta "resultat" placeras i dessa dokument som du behöver, och naturligtvis följer den fullständiga utvärderingen av dokumentet samma regler:

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

Sättet att göra detta i tidigare versioner kräver att du $grupp tillbaka i två steg för att "återbygga" arrayerna medan du gör testerna på dessa "resultat"-fält igen. Den andra skillnaden här är också att använda $min operator som false kommer att betraktas som ett lägre värde än true och utvärderar till samma "allElements"-koncept:

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



  1. Mongodb:beräknad connectToField inuti graphlookup

  2. Guide till Upsert i MongoDB

  3. Startar mongod fork, FEL:underordnad process misslyckades, avslutades med fel nummer 1

  4. Hur kan jag få topp n hinkar för en aggregation och alla andra hinkar kombinerade till en annan hink?