I managed to do it, not sure if it is the right way, but it did the job.
First you have to turn off validationLevel and suppress the errors in validationAction
private def disableValidators(db: DB, collectionName: String): Unit = {
val command = new BasicDBObject("collMod", collectionName)
.append("validationLevel", "off")
.append("validationAction", "warn")
db.command(command)
}
Add the new field and rename the other fields.
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)
}
If you had indexed your fields, you'll need to drop and recreate them.
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()
)
Update the validators, the old collection validators will be replaced by the new ones.
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())
}
Enable back the validators.
private def enableValidators(db: DB, collectionName: String): Unit = {
val command = new BasicDBObject("collMod", collectionName)
.append("validationLevel", "strict")
.append("validationAction", "error")
db.command(command)
}
That should do the job.