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 ?