在mongodb

时间:2017-04-02 22:59:18

标签: mongodb validation

我想在MongoDB中验证我的文档。如here所述,可以在createCollection命令期间指定验证器查询。

我的应用程序是一个简单的待办事项列表,因此集合list包含许多这样的文档:

{
   "name": "the list name",
   "color: "red",
   "items": [
     {
       "title": "item1",
       "isDone": false,
       "text": "the item description"
     }
   ]
} 

我怎么能确定所有文件都有这种形状?

编辑:我正在使用MongoDB 3.4

1 个答案:

答案 0 :(得分:0)

你不能。

没有办法避免新的财产。如果需要,则应考虑迁移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 } } }
                  ]
                }
              }
            }
          }
        ]
      }
    ]
  }
}

<强> 解释

解决方案基于second-order logic。 实际上,断言所有元素必须匹配A&#34;等于&#34;没有元素匹配!A&#34;或者,如果您有许多疑问,&#34;所有元素必须匹配A和B&#34;变为&#34;没有元素应该匹配!A或!B&#34;,其中!表示否定后面的谓词。

长解释

前两个查询项断言所有文档都有namecolor,第三个查询项始终存在items属性。 注意:在第三个查询属性中,没有$type检查,因为mongodb会处理array类型in a odd way

需要$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