问题表现
插入或者更新数据的时候,MongoDB 返回"code" : 121,"errmsg" : "Document failed validation"
问题原因
MongoDB 是无模式(schemaless)的数据库,一个集合内可以插入各种不同字段内容的数据,如对一个集合可以插入拥有不同字段,不同类型的文档记录:
schemaless 的特性让 MongoDB 使用起来很便利,同时也给运维带来了很大的麻烦,特别是字段类型没有做强校验的时候,可能会导致程序出现 bug(如上例,同样是 age 字段,有一个 int 类型,还有一个 string 类型,如果程序没有做强校验就会出问题)。
MongoDB 在 3.2 版本开始引入了 schema validation,可以给集合设置指定验证规则,如在创建集合的时候指定
代码语言:javascript复制validation:
db.createCollection("col2",{validator:{$and:{name:{$type:"string"}},{age:{$type:"int"}}}})
尝试插入不符合规则的文档,报 "Document failed validation"。
尝试插入包含 name 和 age 的文档,发现仍然有报错,这是因为 json 格式只有 number 类型,并没有细分 int、double 之类的数字,mongo shell 在保存数据的时候,全部存为了 double 类型,所以模式校验出错。
要插入 int 类型的数字,需要指定 NumberInt() 的方法,插入成功
怎么解决
1. 既然集合创建了 validation,建议在插入记录的时候,严格按照 validation 的规则进行。
要查看集合的 validation 规则,可以执行db.getCollectionInfos({name:"collectionname"})
,如
2. 如果确定不需要使用 validation 的规则,可以设置 validation level 为 off,不校验规则(关闭前一定要和开发核实清楚,避免程序出 BUG):db.runCommand({ collMod: "col2",validationLevel:"off"})