Mongo Json 模式验证器 AnyOf 不工作
Mongo Json Schema Validator AnyOf not working
我创建了一个具有以下验证的集合:
{
$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" : [ ]
})
更新二:
当我删除现场测试时,我得到了这个验证器:
{
$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 示例中(link 用于浏览器测试,但仅限 draft-7),我添加了根属性 test1
和 test2
。这将允许您拥有 test1
或 test2
键的数据通过,但鉴于我不知道您的要求,我无法告诉您如何修改架构以允许对象具有要传递的 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
或 test2
,那么恐怕 JSON 架构无法帮助您。 JSON Mongo 上下文中的架构只能单独检查每个项目,并且无法验证可能插入的记录的集合。
在上面的示例模式中,我删除了类型检查,因为这与这个问题无关,而且 bsonType 与 JSON 模式类型不同。
我创建了一个具有以下验证的集合:
{
$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" : [ ]
})
更新二: 当我删除现场测试时,我得到了这个验证器:
{
$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 示例中(link 用于浏览器测试,但仅限 draft-7),我添加了根属性 test1
和 test2
。这将允许您拥有 test1
或 test2
键的数据通过,但鉴于我不知道您的要求,我无法告诉您如何修改架构以允许对象具有要传递的 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
或 test2
,那么恐怕 JSON 架构无法帮助您。 JSON Mongo 上下文中的架构只能单独检查每个项目,并且无法验证可能插入的记录的集合。
在上面的示例模式中,我删除了类型检查,因为这与这个问题无关,而且 bsonType 与 JSON 模式类型不同。