Сгруппируйте сборку mongodb и выведите результат как единый объект

Есть ли способ сгруппировать коллекцию, которая выглядит как

[
  {_id: "5bd258a7877e74059b6b65b2", year: 2017, title: "One"},
  {_id: "5bd258a7877e74059b6b65b3", year: 2017, title: "Two"},
  {_id: "5bd258a7877e74059b6b65b4", year: 2018, title: "Three"},
  {_id: "5bd258a7877e74059b6b65b5", year: 2018, title: "Four"}
]

и вывести результат как

{
  2017: [
    0: {_id: "5bd258a7877e74059b6b65b2", title: "One", …}
    1: {_id: "5bd258a7877e74059b6b65b3", title: "Two", …}
  ],
  2018: [
    0: {_id: "5bd258a7877e74059b6b65b4", title: "Three", …}
    1: {_id: "5bd258a7877e74059b6b65b5", title: "Four", …}
  ]
}

используя агрегации mongodb? Подобно тому, как работает lodash groupBy

2
0
376
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете сделать это с помощью следующей агрегации mongoDB:

db.collection.aggregate([{
    $group: {
      _id: "$year",
      docs: {
        $addToSet: "$$CURRENT"
      }
    }
  },
  {
    "$group": {
      "_id": null,
      "data": {
        "$push": {
          "k": {
            $toString: "$_id"
          },
          "v": "$docs"
        }
      }
    }
  },
  {
    "$replaceRoot": {
      "newRoot": {
        "$arrayToObject": "$data"
      }
    }
  }
])

Вы можете увидеть результат здесь

Идея состоит в том, чтобы сгруппировать данные таким образом, чтобы мы могли использовать $arrayToObject. Первая группа дает вам группировку по годам, а вторая - просто подготовка к $arrayToObject, для которой требуется объект key, value. И последнее - $replaceRoot.

Для этого требуется MongoDB 3.6 и выше, поскольку $arrayToObject представлен в этой версии. До этого приходилось использовать $push и т. д.

Другие вопросы по теме