Utilizzando $where
operatore.
db.collection.find(function() {
return this.docs.length === this.docs.filter(function(doc) {
return typeof(doc.foo) !== "undefined" && doc.foo !== null ;}).length
})
Un altro modo per farlo è eseguire due query:una per recuperare il _id
di tutti quei documenti che non corrispondono ai tuoi criteri utilizzando distinct()
metodo:
var unwantedIds = db.collection.distinct( "_id", { "docs": { "$elemMatch": { "foo": { "$exists": false } } } } );
Quindi usa il $nin
operatore per restituire tutti quei documenti che corrispondono ai tuoi criteri.
db.collection.find({ "_id": { "$nin": unwantedIds } } )
Puoi anche utilizzare .aggregate()
metodo, ma funziona solo se si utilizza la versione 3.2 o successiva perché è necessario utilizzare il $filter
La prima fase della pipeline è il $match
fase in cui si filtrano quei documenti in cui il campo "pippo" è assente. Ciò riduce il numero totale di documenti che verranno elaborati a valle. La fase successiva e ultima è il $redact
palcoscenico. In questa fase devi usare il $size
operatore per restituire la dimensione del campo "docs" e la dimensione dell'array dei documenti secondari in cui è presente "foo" e restituire tutti quei documenti in cui i due valori sono uguali.
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"
]
}}
])