Z poprzednio połączonego dupe (możliwe)
, rozwiązanie wykorzystujące $where
nastąpi:
db.collection.find({
"$where": function() {
self = this;
return this.actors.filter(function(actor) {
return self.director._id === actor._id;
}).length > 0
}
})
I inne sugerowane podejście, które wykorzystuje strukturę agregacji $redaguj
potok:
db.collection.aggregate([
{
"$redact": {
"$cond": [
{
"$setIsSubset": [
["$director._id"],
{
"$map": {
"input": "$actors",
"as": "el",
"in": "$$el._id"
}
}
]
},
"$$KEEP",
"$$PRUNE"
]
}
}
])
Powyższa logika warunku dla $redaguj
odbywa się za pomocą operatorów zestawów $setIsSubset
i $map
.
$map
operator zwróci tablicę zawierającą tylko identyfikatory aktorów z aktorów
array po zastosowaniu wyrażenia do każdego elementu w tablicy. Na przykład wyrażenie
{
"$map": {
"input": "$actors",
"as": "el",
"in": "$$el._id"
}
}
jeśli zastosowano na tablicy aktorów
[
{
"_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
}
]
wróci
[ "artist:3", "artist:16", "artist:282" ]
Ten wynik jest porównywany z jednoelementową tablicą ["$directors._id"]
za pomocą $setIsSubset
operator, który pobiera dwie tablice i zwraca prawdę, gdy pierwsza tablica jest podzbiorem drugiej, również wtedy, gdy pierwsza tablica jest równa drugiej tablicy, a w przeciwnym razie fałsz.
Na przykład
{
"$setIsSubset": [
[ "artist:12" ],
[ "artist:3", "artist:16", "artist:282" ]
]
} // false
{
$setIsSubset: [
[ "artist:282" ],
[ "artist:3", "artist:16", "artist:282" ]
]
} // true
Wynik logiczny operatora jest następnie używany jako podstawa $redact
potok.
Wyjaśnienia dotyczące wydajności nadal są aktualne:$where
to dobry hack, gdy jest to konieczne, ale należy go unikać, gdy tylko jest to możliwe.