MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Localizar documentos com matrizes que contêm um documento com um campo específico


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"
        ]
    }}
])