sql >> Database teknologi >  >> NoSQL >> MongoDB

MongoDB indlejret dokumentvalidering for underdokumenter

Ja, du kan valider alle underdokumenter i et dokument ved at negere $elemMatch , og du kan sikre dig, at størrelsen ikke er 1. Det er dog bestemt ikke kønt! Og heller ikke ligefrem indlysende.

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

Det er forvirrende, men det virker! Hvad det betyder er kun at acceptere dokumenter, hvor hverken størrelsen af ​​roles er 1 eller roles har et element med et name det er ikke en string eller en created_by det er ikke en string .

Dette er baseret på det faktum, at i logiske termer,

Svarer til

Vi er nødt til at bruge sidstnævnte, da MongoDB kun giver os en eksisterende operatør.

Bevis

Gyldige dokumenter virker:

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

Hvis et felt mangler fra roles , det mislykkes:

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

Hvis et felt i roles har den forkerte type, fejler den:

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

Hvis roles har størrelse 1 den fejler:

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

Det eneste, jeg desværre ikke kan finde ud af, er, hvordan man sikrer, at roller er en række. roles: {$type: 'array'} ser ud til at fejle alt, formoder jeg, fordi det faktisk kontrollerer, at elementerne er af typen 'array' ?



  1. MongoDB:forespørgselsresultat matcher enhver værdi i array

  2. MongoDB replika-hjerteslagsanmodningstid overskredet

  3. Mongo tæller virkelig langsomt, når der er millioner af poster

  4. sql-forespørgsel til mongodb?