как пометить поле в MongoDB и составить сумму по дате

#mongodb #mongoose #mongodb-query #aggregation-framework

#mongodb #мангуст #mongodb-запрос #агрегация-фреймворк

Вопрос:

Необходимо отформатировать дату и внести сумму за день, но иногда a b значения or недоступны. в итоге получите один документ с указанием даты и суммы. Я использую MongoDB 4.2.

 Data Structure:
{
  "data": {
    "11-10-2001": {
      "a": 17.281150000000001,
      "b": 11.864060000000006
    },
    "13-10-2020": {
      "b": 2.7616699999999994
    },
    "12-10-2001": {
      "b": 4.0809599999999997
    },
    "09-10-2001": {
      "b": 4.1286300000000005
    },
    "17-10-2001": {
      "a": 15.140560000000123,
      "b": 5.017139999999998
    },
    "18-10-2001": {
      "b": 1.975189999999997,
      "a": 7.093789999999976
    }
  }
}
 

Ожидаемый результат один документ, содержащий день и сумму:

 {
  {
    day: 11-10-2001,
    sum : 29.145
  },
  {
    day: 13-10-201,
    sum : 2.7616699
  },
  {
    day: 12-10-2001,
    sum  : 4.0809599999999997
  },
  {
    day: 17-10-2001,
    sum  : 20.114
  },
  {
    day: 18-10-2001,
    sum  : 9.145
  }
}
 

Ответ №1:

Вы можете попробовать,

  • $map для повторения цикла data объекта после преобразования в массив с помощью $objectToArray
  • добавьте ключ day и sum $reduce в цикл объекта number после преобразования в массив с использованием $objectToArray , $add чтобы суммировать значение number
  • $unwind деконструировать массив данных
  • $replaceRoot для замены data объекта на root
 db.collection.aggregate([
  {
    $addFields: {
      data: {
        $map: {
          input: { $objectToArray: "$data" },
          in: {
            day: "$this.k",
            sum: {
              $reduce: {
                input: { $objectToArray: "$this.v" },
                initialValue: 0,
                in: { $add: ["$this.v", "$value"] }
              }
            }
          }
        }
      }
    }
  },
  { $unwind: "$data" },
  { $replaceRoot: { newRoot: "$data" } }
])
 

Игровая площадка

Ответ №2:

Вы можете сделать следующее

 db.collection.aggregate([
  {
    $project: { data: { "$objectToArray": "$data" } }
  },
  {
    $unwind: "$data"
  },
  {
    "$replaceRoot": { "newRoot": "$data" }
  },
  {
    $addFields: { v: { "$objectToArray": "$v" } }
  },
  {
    $addFields: {
      v: {
        $reduce: {
          input: "$v",
          initialValue: 0,
          in: {
            $add: [ "$this.v", "$value" ]
          }
        }
      }
    }
  },
  {
    $group: {
      _id: null,
      data: {
        $push: {
          day: "$k",
          sum: "$v"
        }
      }
    }
  }
])
 

Рабочая игровая площадка Mongo