Нормализована структура массива в MongoDB

#arrays #mongodb #mongodb-query #aggregation-framework

Вопрос:

Объяснение : как мы можем объединить time и sv . преобразовать нормализованную структуру массива

 {
    "data": [
      {
        "time": "1998-08-31T03",
        "sv": {
          "05": {
            "13": 0,
            "14": 1
          }
        }
      }
    ]
  }
 

Например, ожидаемый документ будет.

 
{
 "data" : {
    "1998-08-31T03:05:13Z": 0,
    "1998-08-31T03:05:14Z": 1,
}
}

 

Ответ №1:

  • $reduce для повторения цикла data массива
  • $objectToArray преобразование sv объекта в массив ключ-значение
  • $map для повторения цикла sv массива
  • $objectToArray преобразование минутного объекта в массив ключ-значение
  • $map для повторения цикла массива минут
  • $concat для объединения частей даты в требуемом формате
  • $arrayToObject преобразование пары ключ-значение в объект
  • $concatArrays для объединения элементов data
  • $reduce для повторения цикла data массива
  • $reduce для повторения цикла вложенных data элементов
  • $mergeObjects для объединения объектов дат
 db.collection.aggregate([
  {
    $project: {
      data: {
        $reduce: {
          input: "$data",
          initialValue: [],
          in: {
            $concatArrays: [
              "$value",
              {
                $map: {
                  input: { $objectToArray: "$this.sv" },
                  as: "s",
                  in: {
                    $map: {
                      input: { $objectToArray: "$s.v" },
                      as: "s1",
                      in: {
                        $arrayToObject: [
                          [
                            {
                              k: {
                                $concat: ["$this.time", ":", "$s.k", ":", "$s1.k", "Z"]
                              },
                              v: "$s1.v"
                            }
                          ]
                        ]
                      }
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  {
    $project: {
      data: {
        $reduce: {
          input: "$data",
          initialValue: {},
          in: {
            $mergeObjects: [
              "$value",
              {
                $reduce: {
                  input: "$this",
                  initialValue: {},
                  in: { $mergeObjects: ["$value", "$this"] }
                }
              }
            ]
          }
        }
      }
    }
  }
])
 

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

Ответ №2:

 db.collection.aggregate([
  {
    $unwind: "$data"
  },
  {
    $addFields: {
      "data.sv": {
        $objectToArray: "$data.sv"
      }
    }
  },
  {
    $unwind: "$data.sv"
  },
  {
    $addFields: {
      "data.sv.v": {
        $objectToArray: "$data.sv.v"
      }
    }
  },
  {
    $unwind: "$data.sv.v"
  },
  {
    $addFields: {
      "data": {
        $arrayToObject: [
          [
            {
              k: {
                $concat: [
                  "$data.time",
                  ":",
                  "$data.sv.k",
                  ":",
                  "$data.sv.v.k",
                  "Z"
                ]
              },
              v: "$data.sv.v.v"
            }
          ]
        ]
      }
    }
  },
  {
    $group: {
      _id: null,
      data: {
        $mergeObjects: "$data"
      }
    }
  }
])
 

MongoPlayground