JSON 模式验证的技巧
本页介绍 JSON 模式验证的最佳实践,从而帮助避免出现常见问题。
_id
字段和 additionalProperties: false
当您在 JSON 模式中指定 additionalProperties: false
时,MongoDB 会拒绝以下文档:文档所包含字段未包括在模式的 properties
对象中。
由于所有对象都包含自动生成的 _id
字段,因此当您设置 additionalProperties: false
时,必须在 properties
对象中包含 _id
字段。否则,所有文档都会被拒绝。
例如,对于此验证,所有文档均无效:
{ "$jsonSchema": { "required": [ "_id", "storeLocation" ], "properties": { "storeLocation": { "bsonType": "string" } }, "additionalProperties": false } }
此验证确保 storeLocation
是字符串。但是,properties
对象不包含 _id
字段。
要允许集合中存在文档,必须更新 properties
对象以包含 _id
字段:
{ "$jsonSchema": { "required": [ "_id", "storeLocation" ], "properties": { "_id": { "bsonType": "objectId" }, "storeLocation": { "bsonType": "string" } }, "additionalProperties": false } }
字段值的验证null
您的应用程序配置可能将缺失的字段值设置为 null
,并不是在发送到集合的对象中不包含这些字段。
如果您的模式验证字段的数据类型,要插入该字段具有 null
值的文档,您必须显式允许 null
作为有效的 BSON 类型。
例如,此模式验证不允许 storeLocation
为 null
的文档:
db.createCollection("sales", { validator: { "$jsonSchema": { "properties": { "storeLocation": { "bsonType": "string" } } } } } )
利用前面的验证,拒绝了此文档:
db.store.insertOne( { storeLocation: null } )
或者,此模式验证允许 storeLocation
的值为 null
:
db.createCollection("store", { validator: { "$jsonSchema": { "properties": { "storeLocation": { "bsonType": [ "null", "string" ] } } } } } )
利用前面的验证,允许了此文档:
db.store.insertOne( { storeLocation: null } )
注意
空字段与缺失字段的比较
null
字段值与缺失的字段不同。如果文档中缺少一个字段,MongoDB 将不会验证此字段。
使用加密字段进行验证
如果您对集合启用了客户端字段级加密或可Queryable Encryption,则验证会受到以下限制:
对于 CSFLE,当运行
collMod
时,libmongocrypt 库会优先选择命令中指定的 JSON 加密模式。这样就可以在还没有模式的集合上设置模式。对于 Queryable Encryption,任何包含加密字段的 JSON schema 都会导致查询分析错误。