MongoDB 更新验证器

MongoDB update validator

我有一个看起来像这样的集合:

{
  "_id": "5c90e8736441c96cc8e5c703",
  "meta": {
    "schemaVersion": 1,
    "locHint": {
      "region": "150",
      "country": "GBR"
    }
  },
  "name": "My test study"
}

以及以下验证器:

{
  "$jsonSchema": {
    "bsonType": "object",
    "required": [
      "meta.schemaVersion"
      "meta.locHint.region",
      "meta.locHint.country",
      "name"
    ],
    "properties": {
      "meta.schemaVersion": {
        "bsonType": "int",
        "description": "Version counter used schema changes"
      },
      "meta.locHint.region": {
        "bsonType": "string",
        "pattern": "^[0-9]{3}$",
        "description": "meta.locHint.region is required to be a valid iso3166 region  (3 digits)"
      },
      "meta.locHint.country": {
        "bsonType": "string",
        "pattern": "^[A-Z]{3}$",
        "description": "meta.locHint.country is required to be a valid iso3166 alpha-3  (3 upper case letters)"
      },
      "name": {
        "bsonType": "string",
        "description": "name is required and must be a string"
      }
    }
  }
}

我想实现的是:将region重命名(更新)为m46Region,countryiso3166Country 并使用 MongoBee 迁移脚本更改 meta.locHint.country 的模式。

当我尝试这样做时,mongo 说我的文档无效并且不允许我重命名字段。

如何更新验证器?或者删除并重新创建它们?

我设法做到了,不确定这是否是正确的方法,但它完成了工作。

首先你必须关闭 validationLevel 并抑制 validationAction

中的错误
private def disableValidators(db: DB, collectionName: String): Unit = {
  val command = new BasicDBObject("collMod", collectionName)
    .append("validationLevel", "off")
    .append("validationAction", "warn")

  db.command(command)
}

添加新字段并重命名其他字段。

private def addRenameLocationHintFields(collection: DBCollection): Unit = {
  val findQuery = new BasicDBObject()
  val addFieldIso3166Subdivision = new BasicDBObject("$set", new BasicDBObject("meta.locHint.iso3166Subdivision", null))
  collection.updateMulti(findQuery, addFieldIso3166Subdivision)

  val renameRegion = new BasicDBObject("$rename", new BasicDBObject("meta.locHint.region", "meta.locHint.m49Region"))
  collection.updateMulti(findQuery, renameRegion)

  val renameCountry = new BasicDBObject("$rename", new BasicDBObject("meta.locHint.country", "meta.locHint.iso3166CountryA2"))
  collection.updateMulti(findQuery, renameCountry)
}

如果您已将字段编入索引,则需要删除并重新创建它们。

collection.dropIndex("locHint")
  collection.createIndex(
    BasicDBObjectBuilder
      .start()
      .add("meta.locHint.m49Region", 1)
      .add("meta.locHint.iso3166CountryA2", 1)
      .add("meta.locHint.iso3166Subdivision", 1)
      .add("_id", 1)
      .get()
  )

更新验证器,旧的集合验证器将被新的替换。

private def updateValidators(db: DB, collectionName: String): Unit = {
  val command = BasicDBObjectBuilder
    .start()
    .add("collMod", collectionName)
    .add(
      "validator",
      BasicDBObjectBuilder
      .start()
      .add(
        "$jsonSchema",
        BasicDBObjectBuilder
          .start()
          .add("bsonType", "object")
          .add(
            "required",
            Array(
              "meta.schemaVersion",
              "meta.locHint.m49Region",
              "meta.locHint.iso3166CountryA2",
              "name"
            )
          )
          .add(
            "properties",
            BasicDBObjectBuilder
              .start()
              .add(
                "meta.schemaVersion",
                BasicDBObjectBuilder
                  .start()
                  .add("bsonType", "int")
                  .add("description", "Version counter used schema changes")
                  .get()
              )
              .add(
                "meta.locHint.m49Region",
                BasicDBObjectBuilder
                  .start()
                  .add("bsonType", "string")
                  .add("pattern", "^[0-9]{3}$")
                  .add("description", "meta.locHint.m49Region is required to be a valid iso3166 region  (3 digits)")
                  .get()
              )
              .add(
                "meta.locHint.iso3166CountryA2",
                BasicDBObjectBuilder
                  .start()
                  .add("bsonType", "string")
                  .add("pattern", "^[A-Z]{2}$")
                  .add("description", "meta.locHint.iso3166CountryA2 is required to be a valid iso3166 alpha-2  (2 upper case letters)")
                  .get()
             )
              .add(
                "name",
                BasicDBObjectBuilder
                  .start()
                  .add("bsonType", "int")
                  .add("description", "Version of the terms of service that the user has accepted")
                  .get()
              )
              .get()
          )
        .get()
      )
      .get()
  )

  db.command(command.get())
}

重新启用验证器。

private def enableValidators(db: DB, collectionName: String): Unit = {
  val command = new BasicDBObject("collMod", collectionName)
    .append("validationLevel", "strict")
    .append("validationAction", "error")

  db.command(command)
}

这应该可以完成工作。