我已经使用以下验证创建了一个集合:
{
$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
}
]
}
}
[验证操作设置为错误,验证级别设置为中等。
当我尝试插入包含字段[[test和test1的文档时,出现验证错误
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" : [ ]
})
由于我要插入一个包含AnyOf内部字段之一的文档,所以不应该成功插入该文档吗?如果尝试将“验证操作”更改为“警告”,则会插入文档,但是我可以插入其他任何字段。
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" : [ ] })
当我删除现场测试时,我得到了这个验证器:更新2:
{
$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'
}
}
}
}
并且当我再次尝试插入test1时,我仍然收到错误消息“文档验证失败”
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" : [ ] })
{test:"123"}
]验证失败,因为它不符合anyOf
中的任何模式,后者需要test1
或test2
作为唯一键。[anyOf
]将每个子模式应用于您的实例,并在至少一个子模式通过验证时断言有效。
[{test1: "123" }
失败,因为根模式additionalProperties: false
阻止了对象中未在SAME模式对象properties
或patternProperties
中定义的任何键。
解决方案是重复一些。
在THIS示例中(链接用于浏览器测试,但仅适用于draft-7),我添加了根属性test1
和test2
。这将允许您传递键为test1
或test2
的数据,但是由于我不知道您的要求,因此我无法告诉您如何修改架构以允许键为[[ C0]通过(因为每个test
子计划都阻止它)。
anyOf
[如果您打算检查要插入的内容中是否包含{ "type": "object", "additionalProperties": false, "properties": { "_id": {}, "test": {}, "test1": {}, "test2": {} }, "anyOf": [ { "type": "object", "properties": { "test1": {} }, "additionalProperties": false }, { "type": "object", "properties": { "test2": {} }, "additionalProperties": false } ] }
或test1
,那么恐怕JSON Schema无法帮助您。 Mongo上下文中的JSON模式只能单独检查每个项目,并且无法验证可能插入的记录的集合。在上面的示例架构中,我删除了类型检查,因为这与该问题无关,并且bsonType无论如何都与JSON架构类型不同。