Database, Collection, Document — tuzilishi, BSON nima
Muammodan boshlaylik
"Collection", "Document", "BSON" — bu so'zlar ko'p joyda uchraydi, lekin ularning orasidagi munosabat va nima uchun shunday atalishi tushuntirilmaydi.
SQL bilsangiz, "jadval", "qator", "ustun" tushunchalaringiz bor. MongoDB da ular boshqacha ataladi va biroz boshqacha ishlaydi. Bu darsda ikkisini parallel ko'ramiz — shu orqali tezroq tushunasiz.
Umumiy tuzilish
MongoDB ning to'liq tuzilishi quyidagicha:
MongoDB Server (mongod)
│
├── Database: "maktab"
│ ├── Collection: "talabalar"
│ │ ├── Document: { ism: "Jasur", yosh: 24 }
│ │ ├── Document: { ism: "Malika", yosh: 22 }
│ │ └── Document: { ism: "Bobur", yosh: 25 }
│ │
│ └── Collection: "o_qituvchilar"
│ ├── Document: { ism: "Kamolov", fan: "Matematika" }
│ └── Document: { ism: "Yusupova", fan: "Fizika" }
│
├── Database: "dokon"
│ ├── Collection: "mahsulotlar"
│ └── Collection: "buyurtmalar"
│
└── Database: "admin" ← MongoDB ning o'zi ishlatadi
Eng yuqori daraja — Server. Bir server ichida ko'p Database bo'lishi mumkin. Har database ichida ko'p Collection. Har collection ichida ko'p Document.
SQL bilan parallel
┌──────────────────────┬──────────────────────┐
│ SQL │ MongoDB │
├──────────────────────┼──────────────────────┤
│ Database │ Database │
│ Table (Jadval) │ Collection │
│ Row (Qator) │ Document │
│ Column (Ustun) │ Field (Maydon) │
│ Primary Key │ _id │
│ JOIN │ $lookup / Embedding │
│ Index │ Index │
│ Schema (qat'iy) │ Schema (moslashuv.) │
└──────────────────────┴──────────────────────┘
Nomlar o'zgardi, lekin g'oya o'xshash. Eng katta farq — SQL da schema qat'iy (har qator bir xil ustunlar), MongoDB da esa har document o'z tuzilishida bo'lishi mumkin.
Database
Database — bir-biriga bog'liq collectionlar guruhi.
Server
├── maktab ← ta'lim tizimi uchun
├── dokon ← e-commerce uchun
└── blog ← blog uchun
Har loyiha odatda o'z databasesiga ega. Bir server da ko'p loyiha ishlashi mumkin — ular bir-birining ma'lumotlarini ko'rmaydi.
Database yaratish
MongoDB da database yaratish uchun maxsus buyruq yo'q.
use yozganingizda — tanlaysiz yoki yangi yaratiladi:
use maktab // maktab database ga o'tish (yoki yaratish)
Lekin bu database hali mavjud emas — birinchi document qo'shilgach yaratiladi:
use maktab
db.talabalar.insertOne({ ism: "Jasur" })
// ← endi "maktab" database haqiqatan yaratildi
Maxsus databaselar
┌──────────────┬──────────────────────────────────────────────┐
│ admin │ Administrativ buyruqlar, foydalanuvchilar │
│ local │ Replica set ma'lumotlari, hech qachon │
│ │ replikatsiya qilinmaydi │
│ config │ Sharding konfiguratsiyasi │
└──────────────┴──────────────────────────────────────────────┘
Bu uchta databaseni o'zgartirishdan saqlaning — MongoDB o'zi ishlatadi.
Collection
Collection — bir xil turdagi documentlar to'plami.
SQL da jadval yaratish uchun CREATE TABLE va ustunlar kerak:
-- SQL
CREATE TABLE talabalar (
id SERIAL PRIMARY KEY,
ism VARCHAR(100),
yosh INT,
shahar VARCHAR(100)
);
MongoDB da collection yaratish — document qo'shish bilan avtomatik:
// MongoDB — collection oldindan yaratish shart emas
db.talabalar.insertOne({ ism: "Jasur", yosh: 24 })
// ← "talabalar" collection yaratildi, document qo'shildi
Collection ichidagi documentlar tuzilishi
SQL jadvalida har qator bir xil ustunlarga ega:
SQL: talabalar jadvali
┌────┬─────────┬──────┬────────────┐
│ id │ ism │ yosh │ shahar │
├────┼─────────┼──────┼────────────┤
│ 1 │ Jasur │ 24 │ Toshkent │
│ 2 │ Malika │ 22 │ Samarqand │
│ 3 │ Bobur │ 25 │ NULL │ ← shahar yo'q, NULL
└────┴─────────┴──────┴────────────┘
MongoDB collection da har document o'z tuzilishida:
MongoDB: talabalar collection
┌─────────────────────────────────────────────┐
│ { _id: ..., ism: "Jasur", yosh: 24, │
│ shahar: "Toshkent" } │
├─────────────────────────────────────────────┤
│ { _id: ..., ism: "Malika", yosh: 22, │
│ shahar: "Samarqand", │
│ telefon: ["+998901234567"] } │ ← telefon bor
├─────────────────────────────────────────────┤
│ { _id: ..., ism: "Bobur", yosh: 25 } │ ← shahar yo'q, telefon yo'q
│ │ lekin NULL ham yo'q
└─────────────────────────────────────────────┘
SQL da yo'q ustun NULL bilan to'ldiriladi — joy egallaydi.
MongoDB da yo'q maydon — shunchaki yo'q, hech qanday iz qoldirmaydi.
Collection yaratish — qo'lda
Odatda document qo'shib yaratiladi. Lekin bo'sh collection ham yaratish mumkin:
db.createCollection("arxiv")
// Opsiyalar bilan (masalan, validation — 17-darsda ko'ramiz)
db.createCollection("loglar", { ... })
Document
Document — MongoDB ning asosiy ma'lumot birligi. JSON formatiga o'xshaydi, lekin ichida BSON saqlanadi (buni quyida ko'ramiz).
Document tuzilishi
{
"_id": ObjectId("64a1f2c3b4e5f6a7b8c9d0e1"), // ← majburiy, unikal
"ism": "Jasur", // ← String
"yosh": 24, // ← Number
"faol": true, // ← Boolean
"tug_ilgan": ISODate("2000-03-15"), // ← Date
"telefon": ["+998901234567", "+998712345678"], // ← Array
"manzil": { // ← Ichma-ich object
"shahar": "Toshkent",
"tuman": "Chilonzor"
},
"izoh": null // ← Null
}
Document chegaralari
┌────────────────────────────────────────────────┐
│ Bitta document maksimal hajmi: 16 MB │
│ │
│ 16 MB da nima sig'adi? │
│ — 16,000,000 belgi matn │
│ — Kichik rasmlar (base64 da emas, GridFS) │
│ — O'rtacha loyiha uchun bu chegaraga │
│ yetilmaydi │
│ │
│ 16 MB dan katta fayllar uchun: GridFS │
└────────────────────────────────────────────────┘
_id maydon — har documentning shaxsiy identifikatori
Har document da _id majburiy. Bu SQL dagi primary key ga teng.
Siz _id qo'shmasangiz, MongoDB avtomatik ObjectId yaratadi:
db.talabalar.insertOne({ ism: "Jasur" })
// → { _id: ObjectId("64a1f2c3b4e5f6a7b8c9d0e1"), ism: "Jasur" }
// ↑ MongoDB o'zi qo'shdi
ObjectId tuzilishi
ObjectId — 24 ta hex belgi. Ichida timestamp bor, shuning uchun qachon yaratilganini bilish mumkin:
let id = ObjectId("64a1f2c3b4e5f6a7b8c9d0e1")
id.getTimestamp()
// ISODate("2023-07-02T10:30:43.000Z")
Har ObjectId global unikal — ikki turli server da ham bir xil ObjectId yaratilmaydi.
_id ni o'zingiz belgilash
// Raqam
db.kategoriyalar.insertOne({ _id: 1, nom: "Elektronika" })
// String
db.konfiguratsiya.insertOne({ _id: "site_settings", mavzu: "qorong'u" })
// LEKIN: _id bir collection ichida unikal bo'lishi shart
db.kategoriyalar.insertOne({ _id: 1, nom: "Kiyim" })
// ❌ Xato: E11000 duplicate key error — _id: 1 allaqachon bor
BSON nima?
MongoDB diskda va tarmoqda ma'lumotlarni BSON (Binary JSON) formatida saqlaydi.
JSON vs BSON
JSON (siz ko'radigan): BSON (MongoDB ichki formati):
───────────────────── ──────────────────────────────
Oddiy matn Ikkilik (binary) format
Faqat matn sifatida Tiplarni saqlaydi
Har tip string Int32, Int64, Double farqlaydi
Date yo'q native Date turi bor
ObjectId yo'q native ObjectId turi bor
Sekin parse Tez o'qish/yozish
Nima uchun BSON?
JSON: { "yosh": "24" } ← "24" bu string yoki raqammi?
BSON: { "yosh": 24 } ← aniq: bu Int32
JSON: { "sana": "2023-07-02" } ← string
BSON: { "sana": Date(...) } ← haqiqiy Date ob'ekti, sort ishlaydi
BSON ning afzalliklari:
- Tezlik — binary format tez parse bo'ladi
- Tiplar — Int32, Int64, Double, Date, ObjectId kabi tiplar
- Hajm — ba'zi hollarda JSON dan ixcham
Siz har doim JSON yozasiz → MongoDB BSON ga o'giradi → saqlaydi. O'qiganda BSON → JSON ga qaytaradi. Bu jarayon yashirin.
BSON maxsus tiplari
Mongosh da tez-tez ishlatiladiganlar:
// Date
new Date()
ISODate("2023-07-02T10:30:00.000Z")
// ObjectId
ObjectId("64a1f2c3b4e5f6a7b8c9d0e1")
// Moliyaviy hisob uchun aniq kasr
NumberDecimal("19.99")
Shu uchta yetarli — qolganlarini Mongoose avtomatik boshqaradi.
Ichma-ich document va array — SQL dan farq
Bu MongoDB ning eng kuchli tomoni.
Ichma-ich document (Embedded Document)
SQL da talaba va uning manzilini saqlash uchun ikki jadval:
-- SQL: ikki alohida jadval
CREATE TABLE talabalar (id INT, ism VARCHAR);
CREATE TABLE manzillar (talaba_id INT, shahar VARCHAR, tuman VARCHAR);
-- Ko'rish uchun JOIN kerak
SELECT t.ism, m.shahar
FROM talabalar t
JOIN manzillar m ON t.id = m.talaba_id;
MongoDB da hammasi bitta documentda:
// MongoDB: bitta document, JOIN shart emas
{
ism: "Jasur",
manzil: { // ← ichma-ich document
shahar: "Toshkent",
tuman: "Chilonzor",
ko_cha: "Bunyodkor 4"
}
}
// O'qish — JOIN yo'q, bir so'rov
db.talabalar.find({ "manzil.shahar": "Toshkent" })
// ↑ nuqta bilan ichki maydonga kirish
Array (Massiv)
SQL da bir talabaning ko'p telefon raqami — alohida jadval:
-- SQL
CREATE TABLE telefonlar (talaba_id INT, raqam VARCHAR);
-- Bir talaba uchun bir nechta qator
MongoDB da massiv:
// MongoDB: bitta document, massiv ichida
{
ism: "Jasur",
telefonlar: [ // ← massiv
"+998901234567",
"+998712345678"
]
}
// Massiv ichidan qidirish
db.talabalar.find({ telefonlar: "+998901234567" })
// ← MongoDB massiv ichida avtomatik qidiradi
Haqiqiy loyihadagi document misoli
E-commerce do'koni uchun buyurtma:
{
"_id": ObjectId("..."),
"buyurtma_raqam": "ORD-2024-00142",
"holat": "yetkazildi",
"yaratilgan": ISODate("2024-03-15T09:00:00Z"),
"mijoz": { // ← ichma-ich document
"ism": "Jasur Karimov",
"email": "jasur@gmail.com",
"telefon": "+998901234567"
},
"manzil": { // ← ichma-ich document
"shahar": "Toshkent",
"ko_cha": "Amir Temur 108",
"pochta": "100084"
},
"mahsulotlar": [ // ← array of embedded documents
{
"mahsulot_id": ObjectId("..."),
"nom": "iPhone 15",
"narx": 12500000,
"soni": 1
},
{
"mahsulot_id": ObjectId("..."),
"nom": "Chehol",
"narx": 150000,
"soni": 2
}
],
"jami": 12800000,
"to_lov_turi": "karta"
}
SQL da bu ma'lumot kamida 3 ta jadval va JOIN ni talab qilardi:
buyurtmalar, buyurtma_mahsulotlari, mijozlar.
MongoDB da — bitta document, bitta o'qish operatsiyasi.
Tez-tez uchraydigan xatolar
"_id" ni o'zgartirishga urinish
db.talabalar.updateOne(
{ ism: "Jasur" },
{ $set: { _id: ObjectId("...yangi...") } }
)
// ❌ Xato: Performing an update on the path '_id' would modify
// the immutable field '_id'
_id yaratilgach o'zgartirib bo'lmaydi. Bu MongoDB ning qat'iy
qoidasi. Agar kerak bo'lsa — yangi document yarating, eskisini
o'chiring.
Nested document ga noto'g'ri so'rov
// ❌ Xato — butun object solishtiradi, ichki maydon emas
db.talabalar.find({ manzil: { shahar: "Toshkent" } })
// Bu faqat manzil AYNAN { shahar: "Toshkent" } bo'lganda ishlaydi
// Tuman, ko'cha bo'lsa — topilmaydi
// ✅ To'g'ri — nuqta notation bilan
db.talabalar.find({ "manzil.shahar": "Toshkent" })
// ↑ qo'shtirnoq ichida!
Sabab: "manzil.shahar" — bu maydon yo'li (field path).
Qo'shtirnoqsiz yozsangiz, JavaScript ob'ekt sifatida o'qiydi,
MongoDB to'g'ri talqin qila olmaydi.
Bo'sh collection ni ko'rmaslik
show collections
// Natijada "arxiv" ko'rinmaydi
// Chunki:
db.createCollection("arxiv") // yaratildi
db.arxiv.insertOne(...) // hali qo'shilmagan
// Bo'sh collection show collections da ko'rinadi,
// lekin show dbs da database ko'rinmaydi.
Xulosa
MongoDB tuzilishi:
Server → Database → Collection → Document → Field
↕ ↕ ↕ ↕ ↕
SQL: DB → Table → Row → Column
- Database — bir-biriga bog'liq collectionlar guruhi
- Collection — bir turdagi documentlar to'plami, schema moslashuvchan
- Document — asosiy birlik, JSON ko'rinishida, ichida BSON saqlanadi
- _id — har document unikal identifikatori, ObjectId yoki o'zingiz
- BSON — binary JSON: tezroq, tiplar aniq, Date va ObjectId native
- Ichma-ich documentlar va massivlar — SQL da bir nechta jadval kerak bo'lgan joyda bitta document hal qiladi
Keyingi dars: 5-dars — Ma'lumot turlari: String, Number, Boolean, Date, ObjectId, Array, Object, Null