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'
?