sql >> Database >  >> NoSQL >> MongoDB

MongoDB geneste documentvalidatie voor subdocumenten

Ja, u kunt valideer alle subdocumenten in een document door $elemMatch . te negeren , en je kunt ervoor zorgen dat de maat niet 1 is. Mooi is het zeker niet! En ook niet helemaal duidelijk.

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

Dit is verwarrend, maar het werkt! Wat het betekent is dat je alleen documenten accepteert waarvan noch de grootte van roles is 1 noch roles heeft een element met een name dat is geen string of een created_by dat is geen string .

Dit is gebaseerd op het feit dat in logische termen,

Is gelijk aan

We moeten de laatste gebruiken omdat MongoDB ons alleen een bestaande operator geeft.

Bewijs

Geldige documenten werken:

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

Als een veld ontbreekt in roles , het mislukt:

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

Als een veld in roles heeft het verkeerde type, het mislukt:

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

Als roles heeft maat 1 het mislukt:

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

Het enige dat ik helaas niet kan achterhalen, is hoe ik ervoor kan zorgen dat rollen een array is. roles: {$type: 'array'} lijkt alles te falen, neem ik aan omdat het eigenlijk controleert of de elementen van het type 'array' zijn ?



  1. Functie voor automatisch aanvullen implementeren met behulp van MongoDB-zoekopdracht

  2. Paginering implementeren met MongoDB, Express.js &Slush

  3. Is er een manier om Mongo-codecs automatisch te maken?

  4. Mongoose-schemareferentie en ongedefinieerd type 'ObjectID'