Usando el $where
operador.
db.collection.find(function() {
return this.docs.length === this.docs.filter(function(doc) {
return typeof(doc.foo) !== "undefined" && doc.foo !== null ;}).length
})
Otra forma de hacer esto es ejecutar dos consultas:una para recuperar el _id
de todos aquellos documentos que no coincidan con sus criterios usando el distinct()
método:
var unwantedIds = db.collection.distinct( "_id", { "docs": { "$elemMatch": { "foo": { "$exists": false } } } } );
Luego usa el $nin
operador para devolver todos aquellos documentos que coincidan con sus criterios.
db.collection.find({ "_id": { "$nin": unwantedIds } } )
También puede usar .aggregate()
pero esto solo funciona si está en la versión 3.2 o más reciente porque necesita usar el $filter
La primera etapa en la canalización es $match
etapa en la que filtra aquellos documentos donde el campo "foo" está ausente. Esto reduce el número total de documentos que se procesarán en el futuro. La siguiente y última etapa es $redact
escenario. En esta etapa necesitas usar el $size
operador para devolver el tamaño del campo "docs" y el tamaño de la matriz de los subdocumentos donde está presente "foo" y devolver todos aquellos documentos donde los dos valores son iguales.
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"
]
}}
])