MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Rechercher des documents avec des tableaux contenant un document avec un champ particulier

Utilisation de $where opérateur.

db.collection.find(function() { 
    return this.docs.length === this.docs.filter(function(doc) {
        return typeof(doc.foo) !== "undefined" && doc.foo !== null ;}).length 
})

Une autre façon de procéder consiste à exécuter deux requêtes :une pour récupérer le _id de tous ces documents qui ne correspondent pas à vos critères en utilisant le distinct() méthode :

var unwantedIds = db.collection.distinct( "_id", { "docs": { "$elemMatch": { "foo": { "$exists": false } } } } );

Utilisez ensuite le $nin opérateur pour renvoyer tous les documents qui correspondent à vos critères.

db.collection.find({ "_id": { "$nin": unwantedIds } } )

Vous pouvez également utiliser le .aggregate() méthode mais cela ne fonctionne que si vous êtes sur la version 3.2 ou plus récente car vous devez utiliser le $filter

La première étape du pipeline est le $match étape où vous filtrez les documents où le champ "foo" est absent. Cela réduit le nombre total de documents qui seront traités dans le tuyau. La prochaine et dernière étape est le $redact organiser. Dans cette étape, vous devez utiliser le $size pour retourner la taille du champ "docs" et la taille du tableau des sous-documents dans lesquels "foo" est présent et retourner tous les documents où les deux valeurs sont égales.

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