sql >> Databasteknik >  >> NoSQL >> MongoDB

Hitta element baserat på två värden

Från den tidigare länkade dup (möjligt) , en lösning som använder $where skulle följa:

db.collection.find({
    "$where": function() {
        self = this;
        return this.actors.filter(function(actor) {
            return self.director._id === actor._id;
        }).length > 0
    }
})

Och det andra föreslagna tillvägagångssättet som använder aggregeringsramverket $redact pipeline:

db.collection.aggregate([
    { 
        "$redact": { 
            "$cond": [
                { 
                    "$setIsSubset": [ 
                        ["$director._id"], 
                        {
                            "$map": {
                                "input": "$actors",
                                "as": "el",
                                "in": "$$el._id"
                            }
                        }
                    ] 
                },
                "$$KEEP",
                "$$PRUNE"
            ]
        }
    }
])

I ovanstående, villkorslogiken för code>$redact görs med hjälp av setoperatorer $setIsSubset och $map .

$map Operatören returnerar en array med bara aktörs-id:n från aktörerna array efter att ha tillämpat ett uttryck på varje element i arrayen. Så till exempel uttrycket

{
    "$map": {
        "input": "$actors",
        "as": "el",
        "in": "$$el._id"
    }
}

om det tillämpas på skådespelaruppsättningen

[ 
    {
        "_id" : "artist:3",
        "first_name" : "James",
        "last_name" : "Stewart",
        "birth_date" : "1908",
        "role" : "John Ferguson"
    }, 
    {
        "_id" : "artist:16",
        "first_name" : "Kim",
        "last_name" : "Novak",
        "birth_date" : "1925",
        "role" : "Madeleine Elster"
    }, 
    {
        "_id" : "artist:282",
        "first_name" : "Arthur",
        "last_name" : "Pierre",
        "birth_date" : null,
        "role" : null
    }
]

kommer tillbaka

[ "artist:3", "artist:16", "artist:282" ]

Detta resultat jämförs med en enstaka elementarray ["$directors._id"] med $setIsSubset operator som tar två arrayer och returnerar true när den första arrayen är en delmängd av den andra, inklusive när den första arrayen är lika med den andra arrayen, och annars false.

Till exempel,

{ 
    "$setIsSubset": [ 
        [ "artist:12" ], 
        [ "artist:3", "artist:16", "artist:282" ] 
    ] 
}       // false

{ 
    $setIsSubset: [ 
        [ "artist:282" ], 
        [ "artist:3", "artist:16", "artist:282" ] 
    ] 
}       // true

Det booleska resultatet från operatören används sedan som grund för $redact pipeline.

Förklaringarna till prestanda gäller fortfarande:$where är ett bra hack när det behövs, men det bör undvikas när det är möjligt.



  1. Fråga mellan datum i MongoDB

  2. Profilering av MongoDB-databasen för att se de utförda frågorna

  3. Mongorestore, från meteorproduktionsserver till lokal

  4. Hur man hittar med id i golang och mongodb