Подтвердить что ты не робот

Mongo подсчитывает количество каждого значения для набора документов

У меня есть несколько таких документов:

{
  "user": '1'
},
{ "user": '1'
},
{
  "user": '2'
},
{
  "user": '3'
}

Я хотел бы получить набор всех разных пользователей и их соответствующих счетчиков, отсортированных в порядке убывания. Поэтому мой вывод будет примерно таким:

{
  '1': 2,
  '2': 1,
  '3': 1
}

Я думаю, что это можно сделать с помощью Mongo aggregate(), но у меня много проблем, чтобы понять, как правильно это сделать.

4b9b3361

Ответ 1

Вы можете получить результат (не в нужном формате) с помощью aggregation

db.collection.aggregate(
   {$group : { _id : '$user', count : {$sum : 1}}}
).result

вывод для ваших образцов документов:

"0" : {
    "_id" : "2",
    "count" : 1
},
"1" : {
    "_id" : "3",
    "count" : 1
},
"2" : {
    "_id" : "1",
    "count" : 2
}

Ответ 2

Для тех, кто читает это в январе 2019 года, принятый ответ в настоящее время не работает в Robo3T (возвращает ошибку pipeline.length - 1).

Вы должны:

а) заключить запрос в набор квадратных скобок []

б) удалить .result с конца

https://github.com/Studio3T/robomongo/issues/1519#issuecomment-441348191

Вот обновление принятого ответа от @disposer, которое работает для меня в Robo3T.

db.getCollection('collectionName').aggregate(
    [ {$group : { _id : '$user', count : {$sum : 1}}} ]
)

Ответ 3

С MongoDb 3.6 и новее вы можете использовать оператор $arrayToObject и конвейер $replaceRoot, чтобы получить желаемый результат. Вам необходимо запустить следующий агрегатный конвейер:

db.collection.aggregate([
    {  "$group": {
        "_id": "$user",
        "count": { "$sum": 1 }
    } },
    { "$sort": { "_id": 1 } },
    {  "$group": {
        "_id": null,
        "counts": {
            "$push": {
                "k": "$_id",
                "v": "$count"
            }
        }
    } },
    { "$replaceRoot": {
        "newRoot": { "$arrayToObject": "$counts" }
    } }    
])

который дает

{
    "1" : 2,
    "2" : 1,
    "3" : 1
}