Utilisation de $where
opérateur.
db.collection.find(function() {
return this.docs.length === this.docs.filter(function(doc) {
return typeof(doc.foo) !== "undefined" && doc.foo !== null ;}).length
})
Une autre façon de procéder consiste à exécuter deux requêtes :une pour récupérer le _id
de tous ces documents qui ne correspondent pas à vos critères en utilisant le distinct()
méthode :
var unwantedIds = db.collection.distinct( "_id", { "docs": { "$elemMatch": { "foo": { "$exists": false } } } } );
Utilisez ensuite le $nin
opérateur pour renvoyer tous les documents qui correspondent à vos critères.
db.collection.find({ "_id": { "$nin": unwantedIds } } )
Vous pouvez également utiliser le .aggregate()
méthode mais cela ne fonctionne que si vous êtes sur la version 3.2 ou plus récente car vous devez utiliser le $filter
La première étape du pipeline est le $match
étape où vous filtrez les documents où le champ "foo" est absent. Cela réduit le nombre total de documents qui seront traités dans le tuyau. La prochaine et dernière étape est le $redact
organiser. Dans cette étape, vous devez utiliser le $size
pour retourner la taille du champ "docs" et la taille du tableau des sous-documents dans lesquels "foo" est présent et retourner tous les documents où les deux valeurs sont égales.
db.collection.aggregate([
{ "$match": { "docs.foo": { "$exists": true } } },
{ "$redact": {
"$cond": [
{ "$eq": [
{ "$size": "$docs" },
{ "$size": {
"$filter": {
"input": "$docs",
"as": "doc",
"cond": {
"$ne": [
{ "$ifNull": [ "$$doc.foo", null ] },
null
]
}
}
}}
]},
"$$KEEP",
"$$PRUNE"
]
}}
])