MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Trova documenti con array che contengono un documento con un campo particolare

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