问题
I have created the a collection with the below validation:
{
$jsonSchema: {
bsonType: 'object',
additionalProperties: false,
properties: {
_id: {
bsonType: 'objectId'
},
test: {
bsonType: 'string'
}
},
anyOf: [
{
bsonType: 'object',
properties: {
test1: {
bsonType: 'string'
}
},
additionalProperties: false
},
{
bsonType: 'object',
properties: {
test2: {
bsonType: 'string'
}
},
additionalProperties: false
}
]
}
}
The Validation Action was set to Error and Validation Level to Moderate.
When I try to insert a document containing the field test and test1, I am getting a validation error
Document:
db.dmt9.insert([{test:"123"},{test1:"456"}])
Error:
BulkWriteResult({
"writeErrors" : [
{
"index" : 0,
"code" : 121,
"errmsg" : "Document failed validation",
"op" : {
"_id" : ObjectId("5dd511de1f7b2047ed527044"),
"test" : "123"
}
}
],
"writeConcernErrors" : [ ],
"nInserted" : 0,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
Since I am inserting a document containing one of the fields inside the AnyOf, shouldn't the document be inserted successfully? If I try and change the Validation Action to Warning, the document is inserted however I can insert any other field.
Test with validation Action - Warning
rs0:PRIMARY> db.dmt9.insert([{test:"123"},{test1:"456"},{test9:123}])
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 3,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
Update 2: When I remove the field test I get this validator:
{
$jsonSchema: {
bsonType: 'object',
additionalProperties: false,
anyOf: [
{
bsonType: 'object',
properties: {
test1: {
bsonType: 'string'
}
},
additionalProperties: false
},
{
bsonType: 'object',
properties: {
test2: {
bsonType: 'string'
}
},
additionalProperties: false
}
],
properties: {
_id: {
bsonType: 'objectId'
}
}
}
}
and when i try to insert test1 again I still get the error message Document failed validation
rs0:PRIMARY> db.dmt8.insert([{test1:"123"}])
BulkWriteResult({
"writeErrors" : [
{
"index" : 0,
"code" : 121,
"errmsg" : "Document failed validation",
"op" : {
"_id" : ObjectId("5dd51b4766ba25a01fbcf8e6"),
"test1" : "123"
}
}
],
"writeConcernErrors" : [ ],
"nInserted" : 0,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
回答1:
{test:"123"}
fails validation because it doesn't conform to any of the schemas in anyOf
, which need test1
or test2
as the only key.
anyOf
applies each subschema to your instance, and asserts valid if at least one of the subschemas passes validation.
{test1: "123" }
fails because the root schemas additionalProperties: false
prevents any keys in your object not defined in the SAME schema object properties
or patternProperties
.
The solution is to have some duplication.
In THIS example (link is for in browser testing but draft-7 only), I've added root properties test1
and test2
. This will allow data where you have a key of test1
or test2
to pass, but given I don't know your requirements, I can't tell you how to modify the schema to allow an object with a key of test
to pass (as each of the anyOf
subschemas prevent it).
{
"type": "object",
"additionalProperties": false,
"properties": {
"_id": {},
"test": {},
"test1": {},
"test2": {}
},
"anyOf": [
{
"type": "object",
"properties": {
"test1": {}
},
"additionalProperties": false
},
{
"type": "object",
"properties": {
"test2": {}
},
"additionalProperties": false
}
]
}
If your intent is to check that one of the things you are inserting has test1
or test2
, then I'm afraid JSON Schema cannot help you. JSON Schema in the context of Mongo can only check each item individually, and is not afforded the ability to validate a collection of potentially inserted records.
In the above example schema, I've removed type checking because that is not relevant to this question, and bsonType differs from JSON Schema type anyway.
来源:https://stackoverflow.com/questions/58951911/mongo-json-schema-validator-anyof-not-working