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 ?