MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

MongoDB вложена валидация на документи за поддокументи

Да, можетес валидира всички поддокументи в документ чрез отричане на $elemMatch и можете да се уверите, че размерът не е 1. Със сигурност обаче не е красиво! И също не е съвсем очевидно.

> db.createCollection('users', {
...   validator: {
...     name: {$type: 'string'},
...     roles: {$exists: 'true'},
...     $nor: [
...       {roles: {$size: 1}},
...       {roles: {$elemMatch: {
...         $or: [
...           {name: {$not: {$type: 'string'}}},
...           {created_by: {$not: {$type: 'string'}}},
...         ]
...       }}}
...     ],
...   }  
... })
{ "ok" : 1 }

Това е объркващо, но работи! Това означава, че приема само документи, където нито размерът на roles е 1, нито roles има елемент с name това не е string или created_by това не е string .

Това се основава на факта, че от гледна точка на логиката,

Е еквивалентен на

Трябва да използваме последното, тъй като MongoDB ни дава само съществуващ оператор.

Доказателство

Валидни документи работят:

> db.users.insert({
...   name: 'hello',
...   roles: [],
... })
WriteResult({ "nInserted" : 1 })

> db.users.insert({
...   name: 'hello',
...   roles: [
...     {name: 'foo', created_by: '2222'},
...     {name: 'bar', created_by: '3333'},
...   ]
... })
WriteResult({ "nInserted" : 1 })

Ако поле липсва от roles , не успява:

> db.users.insert({
...   name: 'hello',
...   roles: [
...     {name: 'foo', created_by: '2222'},
...     {created_by: '3333'},
...   ]
... })
WriteResult({
    "nInserted" : 0,
    "writeError" : {
        "code" : 121,
        "errmsg" : "Document failed validation"
    }
})

Ако поле в roles има грешен тип, не успява:

> db.users.insert({
...   name: 'hello',
...   roles: [
...     {name: 'foo', created_by: '2222'},
...     {name: 'bar', created_by: 3333},
...   ]
... })
WriteResult({
    "nInserted" : 0,
    "writeError" : {
        "code" : 121,
        "errmsg" : "Document failed validation"
    }
})

Ако roles има размер 1, той е неуспешен:

> db.users.insert({
...   name: 'hello',
...   roles: [
...     {name: 'foo', created_by: '2222'},
...   ]
... })
WriteResult({
    "nInserted" : 0,
    "writeError" : {
        "code" : 121,
        "errmsg" : "Document failed validation"
    }
})

Единственото нещо, което не мога да разбера за съжаление, е как да гарантирам, че ролите са масив. roles: {$type: 'array'} изглежда проваля всичко, предполагам, защото всъщност проверява дали елементите са от тип 'array' ?



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Подготовка на MongoDB сървър за производство

  2. MongoDB пълнотекстово търсене

  3. Настройка на MongoDB с node.js:Грешка:неуспешно свързване към [localhost:27017]

  4. Пребройте броя коментари в публикацията в Meteor

  5. mongodb mongoose единица за maxDistance