|
The solution taken was to enforce a schema for each possible document. An example of this schema is below, the idea is to specify each option for the _id and apply a schema based on that value. In this ticket, we created a schema with the following format:
$jsonSchema: { oneOf: [ {"properties": {_id: {enum: ["chunksize"]}}, {value: {bsonType: "number", minimum: 1, maximum: 1024}}}, {"properties": {_id: {enum: ["balancer", "autosplit", "ReadWriteConcernDefaults", "audit"]}}}]}
|
This will ensure that updates/inserts where the _id is "chunksize" have a value which is a number between 1 and 1024. For _id "balancer", "autosplit", "ReadWriteConcernDefaults" and "audit", we are enforcing an empty schema which will allow any doc with that _id. Any other _id values will be rejected.
|
|
The config.settings collections isn't ideally formatted for enforcing schemas since the schemas are collection wide and we have different rules for each document.
The current setup of the config.settings collection is to have a document per setting item, with the _id telling which setting the document affects. For example (taken from public documentation) a cluster with a max chunk size set, and balancer and autosplitter settings would have the following documents:
{ "_id" : "chunksize", "value" : 64 }
|
{ "_id" : "balancer", "mode" : "full", "stopped" : false }
|
{ "_id" : "autosplit", "enabled" : true }
|
This means we need to enforce a different schema on each document based on the value of _id. Since mongoDB uses json schema version 4, we cannot use json schema if statements nor constants.
One option to enforce a jsonschema on this collection would be to enforce a schema for each possible document. An example of this schema is below,; the idea is to specify each option for the _id and apply a schema based on that value. The problem with this approach is that every allowed _id needs to be specified. In the example below, only documents with _id "chunksize", "balancer", or "autosplit" would be allowed. We wouldn't be enforcing a schema on "balancer" or "autosplit", but the _id must be specified for it to be allowed in the collection.
$jsonSchema: {
|
oneOf: [
|
{"properties": {_id: {enum: ["chunksize"]}}, {value: {bsonType: "int", minimum: 1, maximum: 1024}}},
|
{"properties": {_id: {enum: ["balancer", "autosplit"]}}}
|
]
|
}
|
Another option would be to change the format of the documents so that instead of having the _id be "chunksize" or "balancer" or "autosplit" we could have these as fields, so that we can enforce the schema on a document given that a certain field exists. Technically we can do this currently using the fields "value", "mode", and "enabled", but this could get confusing in the future if a new setting is added that also includes one of these fields (value doesn't seem like it is unique to chunk size settings).
|