Del dupe previamente vinculado (posible)
, una solución que usa $where
seguiría:
db.collection.find({
"$where": function() {
self = this;
return this.actors.filter(function(actor) {
return self.director._id === actor._id;
}).length > 0
}
})
Y el otro enfoque sugerido que utiliza el marco de agregación $redactar
canalización:
db.collection.aggregate([
{
"$redact": {
"$cond": [
{
"$setIsSubset": [
["$director._id"],
{
"$map": {
"input": "$actors",
"as": "el",
"in": "$$el._id"
}
}
]
},
"$$KEEP",
"$$PRUNE"
]
}
}
])
En lo anterior, la lógica de condición para $redactar
se realiza mediante el uso de operadores de conjuntos código>$setIsSubset
y $map
.
El $map
El operador devolverá una matriz con solo la identificación del actor de los actores
matriz después de aplicar una expresión a cada elemento de la matriz. Entonces, por ejemplo, la expresión
{
"$map": {
"input": "$actors",
"as": "el",
"in": "$$el._id"
}
}
si se aplica en la matriz de actores
[
{
"_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
}
]
regresará
[ "artist:3", "artist:16", "artist:282" ]
Este resultado se compara con una matriz de un solo elemento ["$directors._id"]
usando el $setIsSubset
operador que toma dos matrices y devuelve verdadero cuando la primera matriz es un subconjunto de la segunda, incluso cuando la primera matriz es igual a la segunda matriz, y falso en caso contrario.
Por ejemplo,
{
"$setIsSubset": [
[ "artist:12" ],
[ "artist:3", "artist:16", "artist:282" ]
]
} // false
{
$setIsSubset: [
[ "artist:282" ],
[ "artist:3", "artist:16", "artist:282" ]
]
} // true
El resultado booleano del operador se usa como base para $redact
canalización.
Las explicaciones del rendimiento aún se mantienen:$where
es un buen truco cuando es necesario, pero debe evitarse siempre que sea posible.