Usando o
$where
operador. db.collection.find(function() {
return this.docs.length === this.docs.filter(function(doc) {
return typeof(doc.foo) !== "undefined" && doc.foo !== null ;}).length
})
Outra maneira de fazer isso é executar duas consultas:uma para recuperar o
_id
de todos os documentos que não correspondem aos seus critérios usando o distinct()
método:var unwantedIds = db.collection.distinct( "_id", { "docs": { "$elemMatch": { "foo": { "$exists": false } } } } );
Em seguida, use o
$nin
operador para devolver todos os documentos que correspondam aos seus critérios. db.collection.find({ "_id": { "$nin": unwantedIds } } )
Você também pode usar o
.aggregate()
mas isso só funciona se você estiver na versão 3.2 ou mais recente porque você precisa usar o $filter
O primeiro estágio no pipeline é o
$match
etapa em que você filtra os documentos em que o campo "foo" está ausente. Isso reduz o número total de documentos que serão processados no canal. O próximo e último estágio é o $redact
palco. Nesta etapa você precisa usar o $size
operador para retornar o tamanho do campo "docs" e o tamanho da matriz dos subdocumentos em que "foo" está presente e retornar todos os documentos em que os dois valores são iguais. 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"
]
}}
])