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

MongoDB :Compter combien d'éléments avec une valeur donnée existent dans un tableau, c'est-à-dire dans un document ?

Le cadre d'agrégation est idéal pour cela. Envisagez d'exécuter le pipeline suivant pour obtenir le résultat souhaité.

pipeline = [
    {
        "$match": {
            "name": "james",
            "books.year": 1990
        }
    },
    {
        "$project": {
            "numberOfBooks": {
                "$size": {                  
                    "$filter": {
                        "input": "$books",
                        "as": "el",
                        "cond": { "$eq": [ "$$el.year", 1990 ] }
                    }                   
                }
            }
        }
    }
];
db.collection.pipeline(pipeline);

Le pipeline ci-dessus utilise le nouveau $filter disponible pour MongoDB 3.2 pour produire un tableau qui répond à la condition spécifiée, c'est-à-dire qu'il filtre les éléments externes qui ne répondent pas aux critères. Le $match pipeline est nécessaire pour filtrer les documents entrant dans le pipeline d'agrégation dès le début dans le cadre d'une stratégie d'optimisation du pipeline.

Le $size qui accepte une seule expression comme argument puis vous donne le nombre d'éléments dans le tableau résultant, vous avez ainsi le nombre de livres souhaité.

Pour une solution alternative qui n'utilise pas le $filter opérateur introuvable dans les versions antérieures, considérez l'opération de pipeline suivante :

pipeline = [
    {
        "$match": {
            "name": "james",
            "books.year": 1990
        }
    },
    {
        "$project": {
            "numberOfBooks": {
                "$size": {                  
                    "$setDifference": [
                        {
                            "$map": {
                                "input": "$books",
                                "as": "el",
                                "in": {
                                    "$cond": [
                                        { "$eq": [ "$$el.year", 1990 ] },
                                        "$$el",
                                        false
                                    ]
                                }
                            }
                        },
                        [false]
                    ]                   
                }
            }
        }
    }
];
db.collection.pipeline(pipeline);

Le $project L'étape du pipeline consiste à ajuster le tableau des livres afin que vous supprimiez les documents qui n'ont pas l'année 1990. Ceci est rendu possible grâce au $setDifference et $map les opérateurs.

Le $map L'opérateur crée essentiellement un nouveau champ de tableau qui contient des valeurs résultant de la logique évaluée dans une sous-expression pour chaque élément d'un tableau. Le $setDifference L'opérateur renvoie alors un ensemble avec des éléments qui apparaissent dans le premier ensemble mais pas dans le second ensemble ; c'est-à-dire effectue un complément relatif du deuxième ensemble par rapport au premier. Dans ce cas, il renverra le tableau final des livres contenant des éléments avec l'année 1990, puis le $size calcule le nombre d'éléments dans le tableau résultant, vous donnant ainsi le nombre de livres.

Pour une solution qui utilise le $unwind opérateur, en gardant à l'esprit que (grâce à cette réponse perspicace de @BlakesSeven dans les commentaires) :

et en dernier recours, exécutez le pipeline suivant :

pipeline = [
    {
        "$match": {
            "name": "james",
            "books.year": 1990
        }
    },
    { "$unwind": "$books" },
    {
        "$match": { "books.year": 1990 }
    },
    {
        "$group": {
            "_id": null
            "count": { "$sum": 1 }
        }
    }
]
db.collection.pipeline(pipeline)