【发布时间】:2016-09-21 06:10:56
【问题描述】:
我最近开始使用 MongoDB(版本 3.2.9)并想尝试它的验证功能,因为我喜欢数据库级别的一致性。
我知道我可以而且应该只在业务逻辑中进行此验证,就像我已经做的那样。 但是有一层额外的安全保护感觉很好。
我尝试添加一个集合category,其中_id 类型为'int'、name 类型为'string' 和desc 类型为'string'。
这些值应该都存在,但没有给出内容的限制。
现在,在manual 之后,我得到了以下代码:
db.createCollection('category', {
validator: { $or:
[
{ _id: { $and: [ { $exists: true },
{ $type: 'int' } ] } },
{ name: { $and: [ { $exists: true },
{ $type: 'string' } ] } },
{ desc: { $and: [ { $exists: true },
{ $type: 'string' } ] } }
]
}
})
然而,有了这个简单的结构,MongoDB 抱怨:
{ "ok" : 0, "errmsg" : "unknown operator: $and", "code" : 2 }
现在,我找到了this similar question,但只是尝试将多个约束直接放在$or 数组中:
db.createCollection('category', {
validator: { $or:
[
{ _id: { $exists: true } },
{ _id: { $type: 'int' } },
{ name: { $exists: true } },
{ name: { $type: 'string' } },
{ desc: { $exists: true } },
{ desc: { $type: 'string' } }
]
}
})
但现在,虽然它确实创建了应有的集合,但我现在可以执行以下任何insert 命令:
db.category.insert({})
db.category.insert({_id: 17, name: '', desc: 'valid'})
db.category.insert({_id: 42, name: 42, desc: ''})
db.category.insert({_id: 43, name: '', desc: 42})
db.category.insert({_id: '', name: 42, desc: 42})
db.category.find() 现在返回
{ "_id" : ObjectId("57e19650b10ab85eca323684") }
{ "_id" : 17, "name" : "", "desc" : "valid" }
{ "_id" : 42, "name" : 42, "desc" : "" }
{ "_id" : 43, "name" : "", "desc" : 42 }
{ "_id" : "", "name" : 42, "desc" : 42 }
作为最后的手段,我尝试将 $or 运算符更改为 $and,因为它需要所有规则都有效,而不仅仅是至少一个。
db.createCollection('category', {
validator: { $and:
[
{ _id: { $exists: true } },
{ _id: { $type: 'int' } },
{ name: { $exists: true } },
{ name: { $type: 'string' } },
{ desc: { $exists: true } },
{ desc: { $type: 'string' } }
]
}
})
这种方法对我来说似乎是最合理的,但它根本不起作用。不管上面提到的inserts我尝试使用哪一个,请注意,5 个中只有一个有效,没有一个有效,都给我同样的错误:
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 121,
"errmsg" : "Document failed validation"
}
})
如上所述,对db.version() 的调用返回3.2.9,并且我在Windows 机器上运行默认的MongoDB 64 位分发版,仅将--dbpath 参数设置为以前的空目录。
【问题讨论】:
标签: mongodb validation