[英]Validate embedded document in mongodb
我想在MongoDB中验证我的文档。 如所描述的在这里 ,可以在过程中指定的验证查询createCollection
命令。
我的应用程序是一个简单的待办事项列表,因此收集list
包含许多这样的文档:
{
"name": "the list name",
"color: "red",
"items": [
{
"title": "item1",
"isDone": false,
"text": "the item description"
}
]
}
如何确定所有文档都具有这种形状?
编辑:我正在使用MongoDB 3.4
你不能
没有避免新财产的方法。 如果需要此要求,则应考虑迁移SQL解决方案。
否则,您的文档将至少包含那些成员,并且这些成员将被验证。
我假设所有字段都是必填字段,所以没有颜色的列表和没有标题的项目都不能添加。
我认为颜色也是一个枚举。
{
validator: {
name: { $type: 'string', $exists: true },
color: { $in: ['red', 'green', 'blue'], $exists: true },
items: { $exists: true },
$or: [
{ items: { $size: 0 } },
{
$and: [
{ 'items.0': { $exists: true } },
{
items: {
$not: {
$elemMatch: {
$not: { $type: 'object' }
}
}
}
},
{
items: {
$not: {
$elemMatch: {
$or: [
{ title: { $not: { $type: 'string' } } },
{ title: { $not: { $exists: true } } },
{ isDone: { $not: { $type: 'bool' } } },
{ isDone: { $not: { $exists: true } } },
{ text: { $not: { $type: 'string' } } },
{ text: { $not: { $exists: true } } }
]
}
}
}
}
]
}
]
}
}
说明
该解决方案基于二阶逻辑 。 实际上,断言“所有元素都必须匹配A”等于“没有元素应该匹配!A”,或者,如果您有许多查询,“所有元素必须匹配A和B”变为“没有元素应该匹配!A或B”。 !B”,在哪里!
表示以下谓词的否定。
详细说明
前两个查询项目断言所有文档都具有name
和color
,第三个查询items
属性始终存在。 注意:在第三个查询属性中,没有$type
检查,因为mongodb 以奇怪的方式处理array
类型。
需要下面的$or
操作,因为item
属性可以为空或可以填充一些数据。
$or
第一个子句检查数组是否为空。 如果数组不为空,则应进行三项检查:
因此,第一个$and
运算符元素检查是否存在至少一个元素。 第二个检查所有数组元素都是对象。 第三个断言所有对象都具有指定的形状。
在mongodb中,有一个运算符用于检查所有数组元素是否与查询匹配。 因此,应使用二阶逻辑将检查移交。
实际上, $and
的最后两个子句检查没有元素与所描述的查询匹配。 每个子查询都是所需查询的否定项。
例
失败
{ name: 'foo' }
{ color: 'red' }
{ color: 'unknown color' }
{ name: 'foo', color: 'red' }
{ name: 'foo', color: 'red', item: 3 }
{ name: 'foo', color: 'red', item: [ 3 ] }
{ name: 'foo', color: 'red', item: [ { } ] }
{ name: 'foo', color: 'red', item: [ { title: 'ww' } ] }
{ name: 'foo', color: 'red', item: [ { title: 'ww', isDone: false } ] }
{ name: 'foo', color: 'red', item: [ { title: 44, isDone: false, text: 'the text' } ] }
通过
{ name: 'foo', color: 'red', items: [ ] },
{ name: 'foo', color: 'red', items: [ ] },
{ name: 'foo', color: 'red', items: [ { title: 'the title', isDone: false, text: 'the text' }, { title: 'the title1', isDone: true, text: 'the text' } ] }
该解决方案在MongoDB 3.2上仍然有效
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.