MongoDB ВИБІРУЙТЕ ГРУПУ КОМАНТУ


180

Я граю з 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++;
    }
});

Але чи є простіший / швидший спосіб використання функції сукупності?

Відповіді:


326

Це було б простішим способом зробити це за допомогою 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}}
])

50

Якщо вам потрібно кілька стовпців для групування, дотримуйтесь цієї моделі. Тут я веду підрахунок statusта type:

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

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

2
Напевно, тут варто відзначити, що $sortByCountнасправді є "псевдооператором", як ще кілька операторів стадії агрегації, запроваджені з MongoDB 3.4. Все, що вони дійсно роблять, - це розширити їхні відповідні етапи агрегації. В цьому випадку $groupз , $sum: 1як показано на існуючих відповідей і додаткової $sort стадії. Вони не пропонують жодної переваги, крім "введення меншого коду" , що може бути, а може бути і не більш описовим (якщо ви займаєтесь цією справою). IMHO, окремі $groupта $sortетапи коду набагато більш описові та дійсно більш гнучкі.
Ніл


0

Команда оболонки Монго, яка працювала на мене:

db.getCollection(<collection_name>).aggregate([{"$match": {'<key>': '<value to match>'}}, {"$group": {'_id': {'<group_by_attribute>': "$group_by_attribute"}}}])
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.