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?

Steven
la source

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}}}
])
Anand Jayabalan
la source
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}}
])
csharpbd
la source
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
        }
    }
   })
KitkatJohn
la source
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}}}  
)
andre
la source
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" }
]);
MattM
la source
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"}}}])
Riha
la source