Обновить вложенное поле, если путь к нему не постоянен - PullRequest
0 голосов
/ 05 апреля 2020

Я работаю над Django, который использует MongoDB. Одна из коллекций имеет следующую структуру:

{
    "inspectionType" : {
        "id" : "59a79e44d12b52042104c1e8",
        "name" : "Example Name",
        "inspMngrsRole" : [
            {
                "id" : "55937af6f3de6c004bc42862",
                "type" : "inspectorManager",
                "is_secret_shoper" : false
            }
        ],
        "scopes" : {
            "56fcf6736389b9007a114b10" : {
                "_cls" : "SomeClass",
                "id" : "56fcf6736389b9007a114b10",
                "name" : "Example Name",
                "category" : "Example Category"
            },
        }
    }
}

Мне нужно обновить поле "_cls" ("inspeType.scopes .._ cls") для всех документов в коллекции. Проблема в том, что scope_id является динамическим c и уникальным для каждой области. Можно ли использовать для этого db.collection.update? И как должен выглядеть путь к полю?

Обновление: Версия MongoDB: 3.6.7

1 Ответ

1 голос
/ 06 апреля 2020

Вы можете обновить с помощью агрегации (если вы используете версию MongoDB менее 4.2) плюс операцию обновления или метод updateMany (если используется версия 4.2 или новее) следующим образом:

# 1

var NEW_VALUE = "some new value"    // the value to be updated

db.collection.aggregate( [
  { 
      $addFields: { 
          "inspectionType.scopes": { $objectToArray: "$inspectionType.scopes" } 
      } 
  },
  { 
      $addFields: { 
          "inspectionType.scopes.v._cls": NEW_VALUE 
      } 
  },
  { 
      $addFields: { 
           "inspectionType.scopes": { $arrayToObject: "$inspectionType.scopes" } 
      } 
  }
] ).forEach( doc => db.scopes.updateOne( { _id: doc._id }, { $set: { "inspectionType.scopes": doc.inspectionType.scopes } } ) )


Начиная с версии 4.2 MongoDB updateMany может использовать конвейер агрегации для операции обновления; см. Обновление с агрегационным конвейером .

# 2

db.collection.updateMany(
  { },
  [
      { 
          $set: { 
              "inspectionType.scopes": { $objectToArray: "$inspectionType.scopes" } 
          } 
      },
      { 
          $set: { 
              "inspectionType.scopes.v._cls": NEW_VALUE 
          } 
      },
      { 
          $set: { 
               "inspectionType.scopes": { $arrayToObject: "$inspectionType.scopes" } 
          } 
      }
  ]
)
...