sql >> Database >  >> NoSQL >> MongoDB

Zoek element op basis van twee waarden

Van de eerder gekoppelde dupe (mogelijk) , een oplossing met $where zou volgen:

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

En de andere voorgestelde benadering die gebruikmaakt van het aggregatieraamwerk $redact pijplijn:

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

In het bovenstaande is de conditielogica voor $redact wordt gedaan door het gebruik van set-operators $setIsSubset en $map .

De $map operator retourneert een array met alleen de actor-ID's van de actors array na het toepassen van een expressie op elk element in de array. Dus bijvoorbeeld de uitdrukking

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

indien toegepast op de actoren-array

[ 
    {
        "_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
    }
]

zal terugkeren

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

Dit resultaat wordt vergeleken met een array met één element ["$directors._id"] met behulp van de $setIsSubset operator die twee arrays neemt en true retourneert wanneer de eerste array een subset is van de tweede, inclusief wanneer de eerste array gelijk is aan de tweede array, en anders false.

Bijvoorbeeld,

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

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

Het booleaanse resultaat van de operator wordt vervolgens gebruikt als basis voor de $redact pijpleiding.

De verklaringen voor de prestaties gelden nog steeds:$where is een goede hack als het nodig is, maar het moet zoveel mogelijk worden vermeden.



  1. Selectiefout Docker en mongo-go-driver-server

  2. $lookup geneste array in mongodb

  3. Gegevens initialiseren op gedockte mongo

  4. Invoegen indien niet bestaat, anders MongoDB verwijderen