Ya, Anda bisa memvalidasi semua sub-dokumen dalam dokumen dengan meniadakan $elemMatch
, dan Anda dapat memastikan bahwa ukurannya tidak 1. Pasti tidak cantik! Dan juga tidak terlalu jelas.
> 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 }
Ini membingungkan, tetapi berhasil! Artinya hanya menerima dokumen di mana tidak ada ukuran roles
bukan 1 atau roles
memiliki elemen dengan name
itu bukan string
atau created_by
itu bukan string
.
Ini didasarkan pada fakta bahwa dalam istilah logika,
Setara dengan
Kita harus menggunakan yang terakhir karena MongoDB hanya memberi kita operator yang ada.
Bukti
Dokumen yang valid berfungsi:
> 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 })
Jika bidang hilang dari roles
, gagal:
> db.users.insert({
... name: 'hello',
... roles: [
... {name: 'foo', created_by: '2222'},
... {created_by: '3333'},
... ]
... })
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 121,
"errmsg" : "Document failed validation"
}
})
Jika sebuah bidang di roles
salah ketik, gagal:
> 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"
}
})
Jika roles
memiliki ukuran 1 gagal:
> db.users.insert({
... name: 'hello',
... roles: [
... {name: 'foo', created_by: '2222'},
... ]
... })
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 121,
"errmsg" : "Document failed validation"
}
})
Sayangnya, satu-satunya hal yang saya tidak tahu adalah bagaimana memastikan bahwa peran adalah array. roles: {$type: 'array'}
sepertinya gagal semuanya, saya kira karena itu sebenarnya memeriksa bahwa elemen-elemennya bertipe 'array'
?