MongoDB tidak menuntut bentuk dokumen tertentu secara bawaan, sehingga struktur koleksi yang keliru biasanya ketahuan setelah data yang salah masuk dan dipakai aplikasi. Validator koleksi menegakkan struktur tersebut di dalam server dengan aturan JSON Schema melalui operator $jsonSchema. Topik ini membangun validator pada koleksi dosen di basis data kampus, mendemonstrasikan penolakan dokumen yang melanggar, kemudian mengatur cakupan pemeriksaan validationLevel agar validator dapat diterapkan pada koleksi yang sudah berisi data.
Membuat koleksi dengan aturan JSON Schema#
Aturan validasi didefinisikan saat koleksi dibuat melalui opsi validator pada db.createCollection. Spesifikasi $jsonSchema beroperasi pada tingkat dokumen. Kunci bsonType menetapkan tipe dokumen terluar, kunci required mendaftar field yang wajib ada, sedangkan kunci properties merinci syarat setiap field, termasuk pattern untuk string dan enum untuk nilai yang terbatas. Opsi validator sebenarnya juga menerima ekspresi query biasa, tetapi JSON Schema adalah bentuk yang paling kaya dan paling mudah dibaca untuk aturan struktur.
use kampusswitched to db kampusdb.createCollection("dosen", {
validator: {
$jsonSchema: {
bsonType: "object",
required: [ "nama", "email" ],
properties: {
nama: {
bsonType: "string",
description: "nama dosen wajib berupa string"
},
email: {
bsonType: "string",
pattern: "^[^@]+@[^@]+\\.[^@]+$",
description: "email wajib memuat tanda @ dan titik domain"
},
jabatan: {
enum: [ "Asisten Ahli", "Lektor", "Lektor Kepala", "Profesor" ]
}
}
}
}
}){ ok: 1 }Validator tersebut menuntut setiap dokumen dosen memiliki nama dan email. Field email harus bertipe string dan cocok dengan pola alamat sederhana. Field jabatan bersifat opsional, tetapi nilainya, apabila ada, harus salah satu dari empat jabatan yang diizinkan. Dokumen yang tidak menyertakan jabatan tetap lolos karena field itu tidak tercantum pada required. Kunci description pada setiap properti bersifat dokumentatif agar schema mudah dibaca, sedangkan server hanya menegakkan kunci yang bersifat aturan. Perlu dicatat pula bahwa keunikan nilai, misalnya dua dosen tidak boleh berbagi email yang sama, bukan bagian dari $jsonSchema dan tetap menjadi tugas indeks unik.
Dokumen yang sesuai diterima, yang melanggar ditolak#
Penegakan validator berlangsung pada setiap operasi tulis, sehingga perbedaan dokumen yang sesuai dan yang melanggar terlihat langsung dari hasil penyisipannya.
db.dosen.insertOne({ nama: "Dr. Ali Rahman", email: "[email protected]", jabatan: "Lektor" }){
acknowledged: true,
insertedId: ObjectId('6ae89a7177c3a3c7d88de666')
}db.dosen.insertOne({ nama: "Siti Rahma" })Uncaught:
MongoServerError: Document failed validation
Additional information: {
failingDocumentId: ObjectId('6ae89a7177c3a3c7d88de667'),
details: {
operatorName: '$jsonSchema',
schemaRulesNotSatisfied: [
{
operatorName: 'required',
specifiedAs: { required: [ 'nama', 'email' ] },
missingProperties: [ 'email' ]
}
]
}
}Penyisipan kedua ditolak oleh server, dan pesan errornya menyebut aturan yang gagal beserta field yang hilang. Struktur pesan tersebut berasal dari $jsonSchema. Entri schemaRulesNotSatisfied memuat aturan required yang dilanggar beserta daftar missingProperties.
Penolakan tersebut bersifat per dokumen dan tidak menyentuh dokumen lain. Dokumen dosen yang sudah valid tetap tersimpan ketika satu penyisipan gagal, dan penyisipan berikutnya yang sesuai kembali diterima normal. Validator juga tidak menuntut urutan kunci tertentu pada dokumen, sehingga field yang sama dengan urutan penulisan berbeda tetap dianggap sesuai. Perilaku ini membuat validator aman dijalankan pada koleksi yang sedang aktif, selama struktur dokumen yang ditulis aplikasi memang sudah sesuai dengan aturannya.
try {
db.dosen.insertOne({ nama: "Rina Kartika", email: "rina.kartika", jabatan: "Lektor" })
} catch (e) {
print(`ditolak dengan kode ${e.code}: ${e.errmsg}`)
}ditolak dengan kode 121: Document failed validationPenyisipan ketiga juga ditolak karena nilai email tidak memuat titik domain, sehingga polanya tidak terpenuhi. Kode 121 yang muncul adalah DocumentValidationFailure, yaitu kode error resmi MongoDB untuk kegagalan validasi dokumen, dan kode yang sama muncul untuk setiap jenis pelanggaran validator.
validationLevel untuk koleksi yang sudah berisi data#
Koleksi yang sudah berisi dokumen lama tidak dapat langsung diperiksa dengan level ketat karena dokumen lamanya bisa saja belum sesuai. Parameter validationLevel mengatur cakupan itu. Level strict memeriksa setiap operasi tulis secara penuh. Level moderate memeriksa dokumen baru secara penuh, sedangkan dokumen lama yang tidak sesuai hanya diperiksa pada field yang diperbarui. Level off menonaktifkan validasi. Demonstrasi berikut menambahkan validator pada koleksi yang sudah berisi dokumen lama melalui perintah collMod.
db.dosen.drop()
db.createCollection("dosen")
db.dosen.insertOne({ nama: "Dokumen Lama", catatan: "belum memiliki email" })true
{ ok: 1 }
{
acknowledged: true,
insertedId: ObjectId('6ae89a7177c3a3c7d88de669')
}const hasilCollMod = db.runCommand({
collMod: "dosen",
validator: {
$jsonSchema: {
bsonType: "object",
required: [ "nama", "email" ],
properties: {
nama: { bsonType: "string" },
email: { bsonType: "string", pattern: "^[^@]+@[^@]+\\.[^@]+$" }
}
}
},
validationLevel: "moderate"
})
hasilCollMod.ok1Perintah collMod menambahkan validator tanpa memeriksa ulang dokumen yang sudah tersimpan, dan nilai ok: 1 menandai perintahnya berhasil. Dokumen lama yang tidak memiliki email tetap tersimpan apa adanya setelah validator aktif.
db.dosen.updateOne({ nama: "Dokumen Lama" }, { $set: { catatan: "diperiksa ulang" } }){
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 1,
upsertedCount: 0
}Pembaruan dokumen lama diterima karena level moderate hanya memeriksa field yang ikut diperbarui, sedangkan field email tidak disentuh oleh $set tersebut. Dengan level strict, pembaruan yang sama akan ditolak karena hasil dokumennya masih melanggar aturan required.
db.dosen.insertOne({ nama: "Rina Kartika", jabatan: "Dekan" })Uncaught:
MongoServerError: Document failed validation
Additional information: {
failingDocumentId: ObjectId('6ae89a7177c3a3c7d88de66a'),
details: {
operatorName: '$jsonSchema',
schemaRulesNotSatisfied: [
{
operatorName: 'required',
specifiedAs: { required: [ 'nama', 'email' ] },
missingProperties: [ 'email' ]
}
]
}
}Dokumen baru tetap diperiksa secara penuh di bawah level moderate, sehingga penyisipan tanpa email tetap ditolak dengan pesan yang sama seperti pada demonstrasi sebelumnya. Level ini hanya mengampuni dokumen lama, bukan dokumen yang baru masuk.
Konfigurasi validator yang tersimpan pada koleksi dapat diperiksa dengan db.getCollectionInfos.
const info = db.getCollectionInfos({ name: "dosen" })
({
level: info[0].options.validationLevel,
aksi: info[0].options.validationAction
}){ level: 'moderate', aksi: 'error' }Kesalahan umum#
Kesalahan pertama adalah menulis pola pattern dengan satu garis miring terbalik, misalnya "^[^@]+@[^@]+\.[^@]+$". Dalam string JavaScript, urutan \. dievaluasi menjadi karakter titik biasa, sehingga pola yang sampai ke server kehilangan maknanya dan validator menjadi lebih longgar tanpa pesan error apa pun. Pelanggaran semacam ini tidak terdeteksi melalui log, melainkan melalui pembacaan ulang schema dan pengujian penyisipan yang sengaja melanggar. Pola harus ditulis "\\." agar server menerima \. sebagai titik literal.
Kesalahan kedua adalah mengira collMod memeriksa ulang isi koleksi. Perintah itu hanya memasang aturan untuk operasi tulis berikutnya, sedangkan dokumen lama yang melanggar tetap tersimpan sampai diperbarui. Dokumen yang bermasalah dapat ditemukan terlebih dahulu dengan query $jsonSchema sebagai syarat find, sebelum strategi perbaikannya ditentukan.
Kesalahan ketiga adalah membiarkan validationAction: "warn" terpasang selamanya. Mode peringatan hanya mencatat pelanggaran di log server, sehingga data yang tidak sesuai terus masuk dan validator tampak gagal tanpa menyebabkan error apa pun. Mode ini memang ditujukan untuk masa transisi, dan sebaiknya disertai rencana perpindahan ke nilai error.
Ringkasan#
- Validator koleksi menegakkan struktur dokumen dengan
$jsonSchema, dipasang saatcreateCollectionatau melalui perintahcollMod. - Dokumen yang melanggar ditolak dengan kode
121, yaituDocumentValidationFailure, dan detailnya menyebut aturan serta field yang gagal. validationLevelberupastrict,moderate, atauoffmengatur cakupan pengecekan terhadap dokumen lama yang sudah tersimpan.validationActionberupaerrormenolak tulisan yang melanggar, sedangkanwarnhanya mencatat peringatan untuk masa transisi.
Referensi#
- Schema Validation — MongoDB Manual — Gambaran umum validasi skema, level, dan aksi validasi pada MongoDB.
- Specify JSON Schema Validation — MongoDB Manual
— Cara menuliskan validator
$jsonSchemapada koleksi. - $jsonSchema — MongoDB Manual
— Referensi operator
$jsonSchema, termasuk kuncirequired,properties, danpattern. - db.createCollection() — MongoDB Manual
— Dokumentasi pembuatan koleksi beserta opsi
validator. - collMod — MongoDB Manual — Dokumentasi perintah penambah atau pengubah validator pada koleksi yang sudah ada.
- Update Schema Validation — MongoDB Manual
— Pengaturan
validationLeveldanvalidationActionpada validator yang berjalan. - Error Codes — MongoDB Manual
— Daftar kode error MongoDB, termasuk kode 121
DocumentValidationFailure.