MongoDB SELECT COUNT GROUP BY


181

Je joue avec MongoDB en essayant de comprendre comment faire un simple

SELECT province, COUNT(*) FROM contest GROUP BY province

Mais je n'arrive pas à le comprendre en utilisant la fonction d'agrégation. Je peux le faire en utilisant une syntaxe de groupe vraiment étrange

db.user.group({
    "key": {
        "province": true
    },
    "initial": {
        "count": 0
    },
    "reduce": function(obj, prev) {
        if (true != null) if (true instanceof Array) prev.count += true.length;
        else prev.count++;
    }
});

Mais existe-t-il un moyen plus simple / plus rapide d'utiliser la fonction d'agrégation?

Réponses:


327

Ce serait le moyen le plus simple de le faire en utilisant aggregate:

db.contest.aggregate([
    {"$group" : {_id:"$province", count:{$sum:1}}}
])

1
Je reçois un message d'erreur lorsque j'essaye "errmsg" : "exception: A pipeline stage specification object must contain exactly one field.",?
Steven

comment les groupez-vous? Je veux trier le nombre par -1
Filip Bartuzi

4
@FilipBartuzi il y a un exemple dans la page de documentation, vous devrez ajouter une opération de tri au pipeline, comme{ $sort: { count: -1 } }
elaich

J'ai eu la même exception que @Steven et c'était parce que j'ai copié-collé juste la ligne 2 et omis les crochets environnants.
Peter Perháč

pls aidez si vous le pouvez pour les questions liées à mongoDB - stackoverflow.com/questions/61067856/…
newdeveloper

66

J'ai besoin d'une opération supplémentaire basée sur le résultat de la fonction d'agrégation. Enfin, j'ai trouvé une solution pour la fonction d'agrégation et l'opération basée sur le résultat dans MongoDB. J'ai une collection Requestavec champ request, source, status, requestDate.

Groupe de champs unique par et nombre:

db.Request.aggregate([
    {"$group" : {_id:"$source", count:{$sum:1}}}
])

Groupes de champs multiples par et nombre:

db.Request.aggregate([
    {"$group" : {_id:{source:"$source",status:"$status"}, count:{$sum:1}}}
])

Grouper plusieurs champs par et compter avec tri à l'aide du champ:

db.Request.aggregate([
    {"$group" : {_id:{source:"$source",status:"$status"}, count:{$sum:1}}},
    {$sort:{"_id.source":1}}
])

Plusieurs champs Group By & Count avec Tri en utilisant Count:

db.Request.aggregate([
    {"$group" : {_id:{source:"$source",status:"$status"}, count:{$sum:1}}},
    {$sort:{"count":-1}}
])

50

Si vous avez besoin de plusieurs colonnes pour regrouper, suivez ce modèle. Ici, je mène un décompte par statuset type:

  db.BusinessProcess.aggregate({
    "$group": {
        _id: {
            status: "$status",
            type: "$type"
        },
        count: {
            $sum: 1
        }
    }
   })

2
_id représente un paramètre par défaut pour encapsuler plusieurs champs?
Eugen Sunic

18

De plus, si vous devez restreindre le regroupement, vous pouvez utiliser:

db.events.aggregate( 
    {$match: {province: "ON"}},
    {$group: {_id: "$date", number: {$sum: 1}}}  
)

17

À partir de MongoDB 3.4, vous pouvez utiliser l' $sortByCountagrégation.

Regroupe les documents entrants en fonction de la valeur d'une expression spécifiée, puis calcule le nombre de documents dans chaque groupe distinct.

https://docs.mongodb.com/manual/reference/operator/aggregation/sortByCount/

Par exemple:

db.contest.aggregate([
    { $sortByCount: "$province" }
]);

2
Il vaut probablement la peine de noter ici qu'il $sortByCounts'agit en fait d'un "pseudo opérateur" comme plusieurs autres opérateurs d'étape d'agrégation introduits à partir de MongoDB 3.4. Tout ce qu'ils font vraiment, c'est d' étendre leurs étapes d'agrégation respectives. Dans ce cas, un $groupavec $sum: 1comme indiqué dans les réponses existantes et une $sort étape supplémentaire . Ils n'offrent aucun avantage autre que "taper moins de code" , qui peut ou non être plus descriptif (si vous êtes dans ce genre de choses). À mon humble avis, les étapes distinctes $groupet $sortdans le code sont beaucoup plus descriptives et en fait plus flexibles.
Neil Lunn


0

Commande shell Mongo qui a fonctionné pour moi:

db.getCollection(<collection_name>).aggregate([{"$match": {'<key>': '<value to match>'}}, {"$group": {'_id': {'<group_by_attribute>': "$group_by_attribute"}}}])
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.