Schema Validation — $jsonSchema, validator

~20 daq · MongoDB · Schema Dizayn

Muammodan boshlaylik

MongoDB "schemaless" — har qanday ma'lumot kiritsa bo'ladi. Bu moslashuvchan, lekin xavfli.

// Bularning hammasi xatosiz kiritiladi
db.users.insertOne({ ism: "Jasur", yosh: 25 })
db.users.insertOne({ name: "Ali",  age: 30  })    // xato maydon nomlari
db.users.insertOne({ ism: 12345,   yosh: "yigirma" })  // noto'g'ri turlar

Keyin db.users.find() chaqirsangiz — har xil ko'rinishdagi documentlar keladi. So'rovlar noto'g'ri natija beradi.

Schema Validation — MongoDB ga qoidalar o'rnatish: qaysi maydonlar majburiy, qaysi tur bo'lishi kerak, qaysi qiymatlar ruxsat etilgan.


Oddiy validator

db.createCollection("users", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["ism", "email"],
      properties: {
        ism: {
          bsonType: "string"
        },
        email: {
          bsonType: "string"
        },
        yosh: {
          bsonType: "int",
          minimum: 0,
          maximum: 120
        }
      }
    }
  }
})
// ✅ To'g'ri — xatosiz kiritiladi
db.users.insertOne({ ism: "Jasur", email: "jasur@mail.com" })

// ❌ email yo'q — majburiy maydon
db.users.insertOne({ ism: "Ali" })
// MongoServerError: Document failed validation

// ❌ yosh — noto'g'ri tur
db.users.insertOne({ ism: "Vali", email: "v@mail.com", yosh: "yigirma" })
// MongoServerError: Document failed validation

bsonType — maydon turlari

string    — matn
int       — butun son
double    — kasr son
bool      — true / false
date      — sana
objectId  — MongoDB ID
array     — massiv
object    — ichki ob'ekt

enum — ruxsat etilgan qiymatlar

rol: {
  bsonType: "string",
  enum: ["admin", "foydalanuvchi", "moderator"]
}
// ✅ To'g'ri
db.users.insertOne({ ism: "Jasur", email: "j@mail.com", rol: "admin" })

// ❌ Ro'yxatda yo'q
db.users.insertOne({ ism: "Jasur", email: "j@mail.com", rol: "superuser" })
// MongoServerError: Document failed validation

To'liqroq misol

db.createCollection("mahsulotlar", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["nom", "narx", "kategoriya"],
      properties: {

        nom: {
          bsonType: "string",
          minLength: 2,
          maxLength: 100
        },

        narx: {
          bsonType: "double",
          minimum: 0
        },

        kategoriya: {
          bsonType: "string",
          enum: ["elektronika", "kiyim", "oziq-ovqat"]
        },

        soni: {
          bsonType: "int",
          minimum: 0
        }

      }
    }
  }
})
// ✅ To'g'ri
db.mahsulotlar.insertOne({
  nom: "iPhone 15",
  narx: 12000000.0,
  kategoriya: "elektronika",
  soni: 50
})

// ❌ narx manfiy
db.mahsulotlar.insertOne({
  nom: "Nok",
  narx: -500.0,
  kategoriya: "oziq-ovqat"
})
// MongoServerError: Document failed validation

// ❌ kategoriya ro'yxatda yo'q
db.mahsulotlar.insertOne({
  nom: "Kreslo",
  narx: 300000.0,
  kategoriya: "mebel"   // enum da yo'q
})
// MongoServerError: Document failed validation

Massiv ichini tekshirish

db.createCollection("buyurtmalar", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["mahsulotlar"],
      properties: {
        mahsulotlar: {
          bsonType: "array",
          minItems: 1,           // kamida 1 ta element
          items: {
            bsonType: "object",
            required: ["nom", "miqdor"],
            properties: {
              nom:    { bsonType: "string" },
              miqdor: { bsonType: "int", minimum: 1 }
            }
          }
        }
      }
    }
  }
})
// ✅ To'g'ri
db.buyurtmalar.insertOne({
  mahsulotlar: [
    { nom: "Olma", miqdor: 2 }
  ]
})

// ❌ Bo'sh massiv
db.buyurtmalar.insertOne({ mahsulotlar: [] })
// minItems: 1 — xato

validationLevel

Mavjud loyihaga validator qo'shganda — eski documentlar buzilmasin.

db.createCollection("users", {
  validator: { $jsonSchema: { ... } },
  validationLevel: "strict"    // default — hammasi tekshiriladi
})
// Mavjud collection ga validator qo'shish
db.runCommand({
  collMod: "users",
  validator: { $jsonSchema: { ... } },
  validationLevel: "moderate"  // faqat yangi documentlar tekshiriladi
})
"strict"   → yangi loyiha — hammasi tekshirilsin
"moderate" → mavjud loyiha — eski yozuvlar tekshirilmasin

Tez-tez uchraydigan xatolar

int va double aralashishi

// ❌ — bsonType: "int" belgilangan, lekin JavaScript da 25.0 → double
db.users.insertOne({ ism: "Jasur", email: "j@mail.com", yosh: 25.0 })
// MongoServerError: Document failed validation

// ✅ — to'liq butun son
db.users.insertOne({ ism: "Jasur", email: "j@mail.com", yosh: 25 })

Node.js da 25 integer, 25.0 double — ikkisi bir ko'rinishda yozilsa ham farq bor.

required maydon null bo'lishi

// ❌ — email required, lekin null berildi
db.users.insertOne({ ism: "Jasur", email: null })
// MongoServerError: Document failed validation

// ✅ — null ham qabul bo'lsin
email: {
  bsonType: ["string", "null"]   // string yoki null
}

Xulosa

  • $jsonSchema — collection ga qoidalar o'rnatish
  • required — majburiy maydonlar ro'yxati
  • bsonType — maydon turi (string, int, bool, date...)
  • enum — faqat ro'yxatdagi qiymatlar
  • minimum / maximum / minLength / maxLength — qiymat chegaralari
  • validationLevel: "moderate" — mavjud loyihaga validator qo'shganda eski yozuvlar saqlansin

Keyingi dars: 18-dars — Aggregation Pipeline nima, qanday ishlaydi