sql >> Database teknologi >  >> NoSQL >> MongoDB

Find element baseret på to værdier

Fra den tidligere linkede dupe (mulig) , en løsning, der bruger $where ville følge:

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

Og den anden foreslåede tilgang, der bruger aggregeringsrammen $redact pipeline:

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

I ovenstående er betingelseslogikken for $redact sker ved brug af sætoperatorer $setIsSubset og $map .

$map operatør vil returnere et array med kun aktør-id'erne fra aktørerne array efter at have anvendt et udtryk til hvert element i arrayet. Så for eksempel udtrykket

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

hvis det anvendes på skuespillerrækken

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

vender tilbage

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

Dette resultat sammenlignes med et enkelt element array ["$directors._id"] ved hjælp af $setIsSubset operator, der tager to arrays og returnerer sand, når det første array er en delmængde af det andet, inklusive når det første array er lig med det andet array, og ellers false.

For eksempel,

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

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

Det boolske resultat fra operatøren bruges derefter som grundlag for $redact pipeline.

Forklaringerne på ydeevne gælder stadig:$where er et godt hack, når det er nødvendigt, men det bør undgås, når det er muligt.



  1. hvordan man bruger mapreduce i mongoose/mongodb forespørgsel underdokument?

  2. Autentificering med Spring Security + Spring data + MongoDB

  3. Brug af $unwind og $text i aggregeringsramme mongodb

  4. htmlspecialchars fjerner værdien inde i arrayet?