sql >> Base de Datos >  >> NoSQL >> MongoDB

Encuentre documentos con matrices que contengan un documento con un campo en particular

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