MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Verschachtelte MongoDB-Dokumentvalidierung für Unterdokumente

Ja, Sie können validieren Sie alle Unterdokumente in einem Dokument, indem Sie $elemMatch negieren , und Sie können sicherstellen, dass die Größe nicht 1 ist. Es ist aber sicher nicht schön! Und auch nicht gerade offensichtlich.

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

Das ist verwirrend, aber es funktioniert! Das bedeutet, dass nur Dokumente akzeptiert werden, deren Größe weder roles noch entspricht ist 1 noch roles hat ein Element mit einem name das ist kein string oder ein created_by das ist kein string .

Dies basiert auf der Tatsache, dass in logischer Hinsicht

Entspricht

Wir müssen letzteres verwenden, da MongoDB uns nur einen Existiert-Operator gibt.

Beweis

Gültige Dokumente funktionieren:

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

Wenn ein Feld in roles fehlt , es schlägt fehl:

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

Wenn ein Feld in roles den falschen Typ hat, schlägt es fehl:

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

Wenn roles hat Größe 1, es schlägt fehl:

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

Das einzige, was ich leider nicht herausfinden kann, ist, wie ich sicherstellen kann, dass roles ein Array ist. roles: {$type: 'array'} scheint alles fehlzuschlagen, nehme ich an, weil es tatsächlich überprüft, ob die Elemente vom Typ 'array' sind ?