Сгладить объект в object.name , object.value в агрегации Mongodb

#mongodb #aggregation-framework

#mongodb #агрегация-фреймворк

Вопрос:

У меня есть запись в коллекции, подобная этой. В городах имя ключа или значения не являются постоянными

 [
{
        "id" : "xxx",
        "countryName" : "xxx",
        "cities" : {
            "melbourne" : {
                "id" : "xxx",
                "cityName" : "xxx",
                "population" : 124
            },
            "brisbane" : {
                "column1" : "xxx",
                "column2" : "xxx"
            }
            .....
        }
    }
]
  

Мне нужен ответ типа

 {
cities.melbourne : {"id" : "xxx", "cityName" : "xxx", "population" : 124 },
cities.brisbane : { "column1" : "xxx", "column2" : "xxx" },
......}
  

Комментарии:

1. cities это объект, верно! Поскольку это объект, вы можете легко использовать точечную аннотацию, как вы упомянули. Вам не нужно сглаживать объект.

2. Почему вы хотите, чтобы ключи объекта имели dot(.) такое значение. Как упоминалось выше, у вас уже есть данные в доступном формате.

Ответ №1:

Вы можете сделать, как показано ниже

 db.collection.aggregate([
  {
    "$project": { //Converting cities to array
      "cities": {
        "$objectToArray": "$cities"
      }
    }
  },
  { //Flattening
    "$unwind": "$cities"
  },
  {
    "$replaceRoot": {
      "newRoot": { //Reshaping to the desired structure
        $arrayToObject: [
          [
            {
              "k": {
                "$concat": [
                  "cities",
                  ".",
                  "$cities.k"
                ]
              },
              "v": "$cities.v"
            }
          ]
        ]
      }
    }
  }
])
  

воспроизвести

Вывод:

 [
  {
    "cities.melbourne": {
      "cityName": "xxx",
      "id": "xxx",
      "population": 124
    }
  },
  {
    "cities.brisbane": {
      "column1": "xxx",
      "column2": "xxx"
    }
  }
]
  

Ответ №2:

Вы можете получить ожидаемый результат, используя операторы агрегации $objectToArray и $arrayToObject для преобразования входного документа.

 db.collection.aggregate([
  { 
    $addFields: { cities: { $objectToArray: "$cities" } } 
  },
  { 
    $unwind: "$cities" 
  },
  { 
    $addFields: { "cities.k": { $concat: [ "cities", ".", "$cities.k" ] } } 
  },
  { 
    $group: { _id: "$_id", cities: { $push: "$cities" } } 
  },
  { 
    $replaceWith: { $arrayToObject: "$cities" }  
  }
])