MongoDB SELECT COUNT GROUP BY

181

Я играю с MongoDB, пытаясь выяснить, как сделать простой

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

Но я не могу понять это с помощью агрегатной функции. Я могу сделать это, используя какой-то очень странный групповой синтаксис

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++;
    }
});

Но есть ли более простой / быстрый способ использования агрегатной функции?

Стивен
источник

Ответы:

327

Это был бы более простой способ сделать это, используя aggregate:

db.contest.aggregate([
    {"$group" : {_id:"$province", count:{$sum:1}}}
])
Ананд Джаябалан
источник
1
Когда я пытаюсь это сделать, я получаю сообщение об ошибке "errmsg" : "exception: A pipeline stage specification object must contain exactly one field.",?
Стивен
как вы сортируете группу? Я хочу отсортировать счет -1
Филипп Бартузи
4
@FilipBartuzi есть пример на странице документации, вам нужно будет добавить операцию сортировки в конвейер, как{ $sort: { count: -1 } }
elaich
Я получил то же исключение, что и @Steven, и это потому, что я вставил копию только в строку 2 и опустил окружающие квадратные скобки.
Петер Перхач
Пожалуйста, помогите, если можете, для связанных вопросов в mongoDB - stackoverflow.com/questions/61067856/…
newdeveloper
66

Мне нужна дополнительная операция на основе результата агрегатной функции. Наконец, я нашел какое-то решение для агрегатной функции и операции, основанной на результате в MongoDB. У меня есть коллекция Requestс полем request, source, status, requestDate.

Единичная группа полей по количеству:

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

Группировка по нескольким полям по количеству:

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

Группировка нескольких полей по количеству полей с сортировкой по полю:

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

Сгруппировать несколько полей по количеству полей с сортировкой по количеству:

db.Request.aggregate([
    {"$group" : {_id:{source:"$source",status:"$status"}, count:{$sum:1}}},
    {$sort:{"count":-1}}
])
csharpbd
источник
50

Если вам нужно сгруппировать несколько столбцов, следуйте этой модели. Здесь я веду отсчет по statusи type:

  db.BusinessProcess.aggregate({
    "$group": {
        _id: {
            status: "$status",
            type: "$type"
        },
        count: {
            $sum: 1
        }
    }
   })
KitkatJohn
источник
2
_id представляет параметр по умолчанию для инкапсуляции нескольких полей?
Евгений Сунич
18

Кроме того, если вам нужно ограничить группировку, вы можете использовать:

db.events.aggregate( 
    {$match: {province: "ON"}},
    {$group: {_id: "$date", number: {$sum: 1}}}  
)
Андрэ
источник
17

Начиная с MongoDB 3.4, вы можете использовать $sortByCountагрегацию.

Группирует входящие документы на основе значения указанного выражения, а затем вычисляет количество документов в каждой отдельной группе.

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

Например:

db.contest.aggregate([
    { $sortByCount: "$province" }
]);
MattM
источник
2
Вероятно, здесь стоит отметить, что $sortByCountна самом деле это «псевдооператор», как еще несколько операторов стадии агрегации, представленных в MongoDB 3.4. Все, что они на самом деле делают, - это расширяются на соответствующие стадии агрегации В этом случае $groupс , $sum: 1как показано на существующих ответов и дополнительной $sort стадии. Они не предлагают никаких преимуществ, кроме «ввода меньшего количества кода» , который может быть, а может и не быть более наглядным (если вы любите подобные вещи). ИМХО, отдельные $groupи $sortэтапы в коде гораздо более наглядны и действительно более гибки.
Нил Ланн
0

Команда оболочки Mongo, которая работала для меня:

db.getCollection(<collection_name>).aggregate([{"$match": {'<key>': '<value to match>'}}, {"$group": {'_id': {'<group_by_attribute>': "$group_by_attribute"}}}])
Ржига
источник