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.