Mongodb Совокупный запрос для суммирования всех значений на основе полей внутри объектов в массиве

У меня есть коллекция data в MongoDB, которая выглядит так:

документ 1-

{
    metadata:[
        {
            "title": "High",
            "val": 12
        },
        {
            "title": "Medium",
            "val": 15
        },
        {
            "title": "Low",
            "val": 2
        }
    ]
}

документ2 -

{
    metadata:[
        {
            "title": "High",
            "val": 10
        },
        {
            "title": "Medium",
            "val": 12
        },
        {
            "title": "Low",
            "val": 20
        }
    ]
}

& скоро..

Я хочу агрегировать поле val на основе значения title. Вывод должен выглядеть так -

{
    "High": 22,
    "Medium": 27,
    "Low": 22
}

Как мне этого добиться? Заранее спасибо.

Использование JavaScript и MongoDB
Использование JavaScript и MongoDB
Сегодня я собираюсь вкратце рассказать о прототипах в JavaScript, а также представить и объяснить вам работу с базой данных MongoDB.
1
0
1 699
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете сначала $раскрутить массив metadata. Затем используйте $group и $cond для суммирования ваших значений.

db.collection.aggregate([
  {
    "$unwind": "$metadata"
  },
  {
    $group: {
      _id: null,
      High: {
        $sum: {
          $cond: [
            {
              $eq: [
                "$metadata.title",
                "High"
              ]
            },
            "$metadata.val",
            0
          ]
        }
      },
      Medium: {
        $sum: {
          $cond: [
            {
              $eq: [
                "$metadata.title",
                "Medium"
              ]
            },
            "$metadata.val",
            0
          ]
        }
      },
      Low: {
        $sum: {
          $cond: [
            {
              $eq: [
                "$metadata.title",
                "Low"
              ]
            },
            "$metadata.val",
            0
          ]
        }
      }
    }
  }
])

Вот игровая площадка Mongo для справки.

Спасибо!! есть ли способ добиться этого, когда мы не знаем значения полей Высокий, Средний, Низкий, путем разделения на основе уникальных значений заголовка?

Ritik Saxena 11.12.2020 06:34

@Ray, это был слишком старый пост, для последней версии это возможно, я только что ответил там посмотри

turivishal 11.12.2020 07:19

@turivishal да, вы правы, ваш ответ должен быть принятым :)

ray 11.12.2020 07:32
Ответ принят как подходящий
  • $unwind деконструировать metadata массив
  • $grpup на title и составить сумму val
  • $group с помощью null, преобразовать массив в объект из ключа и значения с помощью $arrayToObject и объединить объекты с помощью $mergeObjects
db.collection.aggregate([
  { $unwind: "$metadata" },
  {
    $group: {
      _id: "$metadata.title",
      sum: { $sum: "$metadata.val" }
    }
  },
  {
    $group: {
      _id: null,
      metadata: {
        $mergeObjects: {
          $arrayToObject: [
            [{ k: "$_id", v: "$sum" }]
          ]
        }
      }
    }
  }
])

Детская площадка

Я получаю эту ошибку, когда пытаюсь выполнить этот запрос для фактических данных — $arrayToObject требует объект с ключами «k» и «v», где значение «k» должно быть строкового типа. Найденный тип: ноль

Ritik Saxena 11.12.2020 07:37

было бы какое-то нулевое или пустое значение в полях title или val. Вы можете убедиться, где это?

turivishal 11.12.2020 07:49

разобрался. ошибка была с моей стороны. Спасибо!! :)

Ritik Saxena 11.12.2020 07:55

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