Dal dupe precedentemente collegato (possibile)
, una soluzione che utilizza $where
seguirebbe:
db.collection.find({
"$where": function() {
self = this;
return this.actors.filter(function(actor) {
return self.director._id === actor._id;
}).length > 0
}
})
E l'altro approccio suggerito che utilizza il framework di aggregazione $redact
pipeline:
db.collection.aggregate([
{
"$redact": {
"$cond": [
{
"$setIsSubset": [
["$director._id"],
{
"$map": {
"input": "$actors",
"as": "el",
"in": "$$el._id"
}
}
]
},
"$$KEEP",
"$$PRUNE"
]
}
}
])
In quanto sopra, la logica della condizione per $redact
avviene tramite l'uso di operatori di insiemi $setIsSubset
e $map
.
Il $map
l'operatore restituirà un array con solo gli ID attore da actors
array dopo aver applicato un'espressione a ciascun elemento nell'array. Quindi, ad esempio, l'espressione
{
"$map": {
"input": "$actors",
"as": "el",
"in": "$$el._id"
}
}
se applicato all'array attori
[
{
"_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
}
]
tornerà
[ "artist:3", "artist:16", "artist:282" ]
Questo risultato viene confrontato con un array a elemento singolo ["$directors._id"]
utilizzando $setIsSubset
operatore che accetta due array e restituisce true quando il primo array è un sottoinsieme del secondo, incluso quando il primo array è uguale al secondo array, e false in caso contrario.
Ad esempio,
{
"$setIsSubset": [
[ "artist:12" ],
[ "artist:3", "artist:16", "artist:282" ]
]
} // false
{
$setIsSubset: [
[ "artist:282" ],
[ "artist:3", "artist:16", "artist:282" ]
]
} // true
Il risultato booleano dell'operatore viene quindi utilizzato come base per $redact
pipeline.
Le spiegazioni per le prestazioni sono ancora valide:$where
è un buon hack quando necessario, ma dovrebbe essere evitato quando possibile.