sql >> Databasteknik >  >> NoSQL >> MongoDB

MongoDB kapslad dokumentvalidering för underdokument

Ja, du kan validera alla underdokument i ett dokument genom att negera $elemMatch , och du kan se till att storleken inte är 1. Det är säkert inte vackert! Och inte direkt självklart heller.

> 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 }

Detta är förvirrande, men det fungerar! Vad det betyder är att bara acceptera dokument där varken storleken på roles är 1 eller roles har ett element med ett name det är inte en string eller en created_by det är inte en string .

Detta är baserat på det faktum att i logiska termer,

Motsvarar

Vi måste använda den senare eftersom MongoDB bara ger oss en existerande operatör.

Bevis

Giltiga dokument fungerar:

> 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 })

Om ett fält saknas i roles , det misslyckas:

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

Om ett fält i roles har fel typ, det misslyckas:

> 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"
    }
})

Om roles har storlek 1 den misslyckas:

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

Det enda jag tyvärr inte kan lista ut är hur man säkerställer att roller är en array. roles: {$type: 'array'} verkar misslyckas med allt, antar jag eftersom det faktiskt kontrollerar att elementen är av typen 'array' ?



  1. mongodb - hämta array-delmängd

  2. Hur uppdaterar man egenskapen i flera objekt i en array för ett dokument i Meteor collection/minimongo?

  3. Finns det något orm-liknande bibliotek för mongodb i scala?

  4. Mongo:samla $geoNear och $text inga resultat