Mundarija (28)
- Bu darsda
- 1. Nega bu kerak?
- 2. Hujjat modeli: baza → kolleksiya → hujjat
- 2.1 Uch qavat
- 2.2 Kanondagi vazifa hujjati
- 3. BSON: diskdagi hujjat
- 3.1 Nega oddiy JSON emas
- 3.2 16 MB chegara
- 4. _id va ObjectId
- 4.1 _id majburiy
- 4.2 ObjectId ichida nima bor
- 5. Sxemasizlik: erkinlik va narxi
- 5.1 Kolleksiya hech narsani tekshirmaydi
- 5.2 Narxi qayerda chiqadi
- 6. Vositalar: Docker, mongosh, Compass, Atlas
- 6.1 Docker'da MongoDB
- 6.2 Ulanish satri
- 6.3 mongosh — terminal qobig'i
- 6.4 Compass va Atlas
- 7. Loyiha qadami: kanon tajribasi, loyihaga kirmaydi
- 8. Ko'p uchraydigan xatolar
- 9. Mashqlar
- 1-mashq (oson): to'ldiring
- 2-mashq (o'rta): ObjectId'dan vaqt
- 3-mashq (qiyin): qatorlardan hujjat
- 10. Real ishda
- Xulosa
- Manbalar
MongoDB nima: hujjat, kolleksiya, BSON va ObjectId — tuzilishi va vositalari
Qisqacha: MongoDB ma'lumotni jadval qatorlarida emas, hujjatlarda saqlaydi. Hujjat — JSON'ga o'xshash obyekt, ichida massiv va ichma-ich obyektlar bo'lishi mumkin. Tuzilma uch qavatli: baza → kolleksiya → hujjat. Diskda hujjat BSON (ikkilik JSON) bo'lib yotadi, u sana, ObjectId va aniq son turlarini ham biladi. Har hujjatda
_idbor; sukut bo'yicha u ObjectId — 12 bayt, birinchi 4 bayti yaratilgan vaqt. Kolleksiya sxemani tekshirmaydi: kanonda bir xil kolleksiyagamatn: 42ham jim kirdi.
Bu darsda
- Postgres'dagi to'rt jadvallik vazifani Mongo'da bitta hujjat sifatida o'qiysiz.
- Baza, kolleksiya va hujjat qanday bog'langanini tushuntira olasiz.
- BSON JSON'dan nimasi bilan farq qilishini va
_id/ObjectId ichida nima borligini bilasiz. - ObjectId'dan yaratilgan vaqtni o'zingiz chiqarasiz.
- mongosh bilan bazani ko'rasiz va sxemasizlikning narxini kanon misolida ko'rasiz.
Oldin bilishingiz kerak: DB turlari xaritasi va SQL vs NoSQL, Volume va bind mount, JSONB, Relatsion model.
1. Nega bu kerak?
DB turlari xaritasi darsida bazalarni turlarga ajratdik. U yerda hujjat (document) baza haqida bir paragraf bor edi: "vazifa va uning egasi bitta hujjatda, ichma-ich". Endi shu turning eng mashhurini — MongoDB ni ochib ko'ramiz.
vazifalar ilovasida bitta vazifani ekranga chiqarish uchun Postgres'da to'rt jadvalga murojaat qilamiz: vazifalar, izohlar, vazifa_teglari, teglar. Keyin JOIN yoki json_agg bilan ularni yig'amiz (N+1 muammosi darsidagi "bitta so'rov").
O'xshatish: kutubxonada kitob haqidagi ma'lumot to'rt shkafda saqlansa — bittasida nomi, boshqasida o'quvchilar sharhi, uchinchisida yorliqlari. Kerak bo'lganda to'rt shkafdan yig'asiz. Hujjat baza esa hamma narsani bitta papkaga solib qo'yadi: papkani oldingiz — hammasi qo'lingizda.
Bu yaxshimi? Ba'zan ha, ba'zan yo'q. Bu qismning 11 ta darsi shu savolga o'lchov bilan javob beradi. Avval asosini ko'ramiz: MongoDB ichida nima bor va qanday vositalar bilan ishlaymiz.
Maslahat: Bu darslarda
vazifalar-apiMongo'ga ko'chmaydi — u Postgres'da qoladi. Mongo'ni taqqoslash va alohida bilim sifatida o'rganamiz. Kanon Postgres'dagi o'sha namunani (8 foydalanuvchi, 48 vazifa) Mongo'ga ko'chirdi, shuning uchun natijalarni ikki baza o'rtasida solishtirish mumkin.
2. Hujjat modeli: baza → kolleksiya → hujjat
2.1 Uch qavat
MongoDB serveri ichida bir nechta baza (database) bo'ladi. Har bazada kolleksiyalar (collection) — bir turdagi hujjatlar guruhi. Har kolleksiyada hujjatlar (document).
flowchart TD
S["MongoDB serveri"] --> B1["baza: vazifalar"]
S --> B2["baza: admin"]
B1 --> K1["kolleksiya: vazifalar"]
B1 --> K2["kolleksiya: foydalanuvchilar"]
K1 --> H1["hujjat: pgId 1"]
K1 --> H2["hujjat: pgId 2"]
K2 --> H3["hujjat: Aziz"]Diagrammaga qarang: Postgres'dagi "baza → jadval → qator" ga juda o'xshaydi. Farqi — eng pastki qavatda. Qator — tekis, har ustunda bitta qiymat. Hujjat — daraxt: ichida massiv, massiv ichida obyekt bo'lishi mumkin.
| Postgres | MongoDB | Farqi |
|---|---|---|
| baza | baza | bir xil g'oya |
| jadval | kolleksiya | kolleksiya ustunlarni bilmaydi |
| qator | hujjat | hujjat ichma-ich bo'la oladi |
| birlamchi kalit | _id |
har hujjatda majburiy |
Kolleksiya oldindan yaratilmaydi. Birinchi hujjat yozilganda Mongo uni o'zi ochadi. Baza ham shunday. CREATE TABLE ning to'g'ridan-to'g'ri o'xshashi yo'q.
2.2 Kanondagi vazifa hujjati
Kanon Postgres holat 11 namunasini Mongo'ga ko'chirdi (ko'chirish kodi — keyingi darsda). Teglar va izohlar vazifaning ichiga joylandi, egasi esa foydalanuvchilar kolleksiyasiga ishora qiladi. Mana 1-vazifa — drayver findOne bilan olib, JSON qilib chop etgan (Node 24.21.0, mongodb 7.7.0, MongoDB 8.3.13; kanon chiqishi 700 belgida kesilgan, biz uni izohlar boshida to'xtatdik):
{
"_id": "6add9a837ffcaf2b9d405510",
"pgId": 1,
"egasi": "6add9a837ffcaf2b9d405508",
"matn": "JavaScript kursining 26-qismini boshlash #o'qish",
"bajarildi": false,
"ustuvorlik": "yuqori",
"muddat": "2026-10-31T18:59:00.000Z",
"yaratilgan": "2026-10-01T03:30:00.000Z",
"tartib": 1,
"versiya": 1,
"teglar": [
"o'qish"
],
"izohlar": [
{
"muallif": "6add9a837ffcaf2b9d405508",
"matn": "Docker darslaridan boshladim",
"yaratilgan": "2026-10-01T15:00:00.000Z"
},Nimaga qarang:
teglar— oddiy satrlar massivi. Postgres'da buvazifa_teglari+teglarjadvallari edi.izohlar— obyektlar massivi. Postgres'da alohidaizohlarjadvali.egasi— boshqa hujjatning_idsi. Bu ishora (reference): Postgres'dagi tashqi kalitga o'xshaydi, lekin baza uni tekshirmaydi.pgId— kanon Postgres'dagi id'ni saqlab qo'ydi, solishtirish uchun.
Hujjat ichiga joylash — embed, boshqa hujjatga ishora qilish — reference. Qachon qaysi biri — Populate va embed vs reference darsining asosiy savoli.
Tekshirib ko'ring: Postgres'da 1-vazifani teglari va izohlari bilan olish uchun nechta jadvalga murojaat kerak? Mongo'da-chi?
Javob
Postgres'da to'rtta: vazifalar, izohlar, vazifa_teglari, teglar (JOIN yoki ichki so'rovlar bilan). Mongo'da — bitta hujjat, bitta findOne. Lekin izohlar muallifining ismi kerak bo'lsa, Mongo'da ham foydalanuvchilar ga ikkinchi murojaat kerak: hujjatda faqat muallif _id si bor.
3. BSON: diskdagi hujjat
3.1 Nega oddiy JSON emas
JSON'da atigi oltita tur bor: satr, son, mantiqiy, null, massiv, obyekt. Sana yo'q — sana satr bo'lib yoziladi. Son bitta — butun va kasr farqi yo'q.
MongoDB hujjatni BSON (Binary JSON) formatida saqlaydi. U ikkilik (binary) format: diskda va tarmoqda ixcham, tez o'qiladi va JSON'dan ko'proq tur biladi:
| BSON turi | Misol | Nega kerak |
|---|---|---|
| Date | ISODate('2026-10-01T03:30:00.000Z') |
sana sana bo'lib saqlanadi, satr emas |
| ObjectId | ObjectId('6add9a83…') |
12 baytli noyob id |
| int32 / int64 / double | 1, NumberLong(…), 0.5 |
butun va kasr sonlar farqlanadi |
| Decimal128 | NumberDecimal('35000.00') |
pul uchun aniq kasr |
| Binary | rasm, hash bayti | baytlar to'g'ridan |
Chiqishda "yaratilgan": "2026-10-01T03:30:00.000Z" satrga o'xshaydi. Bu JSON.stringify ning ishi. Aslida Node'ga Date keldi — kanon shuni alohida tekshirdi:
_id: 6add9a837ffcaf2b9d405510 | ichidagi vaqt: 2026-10-25T05:58:27.000Z | turi: object true
hujjat hajmi (BSON): 258 bayt o'rtacha; to'plam: 12403 baytturi: object true — typeof "object" va instanceof Date true. Ya'ni Postgres'dagi timestamptz Mongo'da haqiqiy sana bo'lib qoldi. Vazifa hujjati o'rtacha 258 bayt, 48 ta hujjatli kolleksiya — 12 403 bayt (kanon chiqishida "to'plam" — kolleksiyaning o'zbekcha nomi).
3.2 16 MB chegara
Bitta BSON hujjatning maksimal hajmi — 16 MB. 258 baytli vazifa uchun bu juda katta zaxira. Lekin hujjat ichidagi massiv cheksiz o'saversa (masalan, 100 000 izoh), chegaraga yetadi. Bu "cheksiz massiv" anti-naqshini sxema dizayn naqshlari darsida o'lchaymiz.
4. _id va ObjectId
4.1 _id majburiy
Har hujjatda _id maydoni bor va u kolleksiya ichida noyob. Siz bermasangiz — drayver o'zi ObjectId yaratib qo'yadi. Istasangiz o'zingiz berasiz: son, satr, hatto obyekt. Kanonning katta to'plamida _id — Postgres'dagi son id (_id: 1, _id: 2, …).
_id bo'yicha indeks doim bor, uni o'chirib bo'lmaydi.
4.2 ObjectId ichida nima bor
ObjectId — 12 bayt, ekranda 24 ta o'n oltilik belgi:
6add9a83 7ffcaf2b9d 405510
└ vaqt ┘ └tasodifiy┘ └hisob┘
4 bayt 5 bayt 3 bayt- 4 bayt — vaqt: Unix soniyalari (1970-yildan beri), hujjat yaratilgan payt.
- 5 bayt — tasodifiy qiymat: har jarayon uchun bir marta tanlanadi.
- 3 bayt — hisoblagich: har yangi ObjectId'da bittaga oshadi.
Shu tuzilma tufayli ObjectId'ni bazaga so'ramasdan yaratish mumkin — drayver o'zi yasaydi va ikki mashinada ham takrorlanish ehtimoli juda kichik. Bonus: ObjectId'lar vaqt bo'yicha o'sib boradi, _id bo'yicha saralash taxminan "yaratilgan tartibi" ni beradi (bir soniya ichida aniq emas).
Vaqtni o'zimiz chiqarib ko'ramiz. Brauzerda ham ishlaydi:
// ObjectId — 24 belgi; birinchi 8 tasi — vaqt (soniya)
const id = "6add9a837ffcaf2b9d405510";
const soniya = parseInt(id.slice(0, 8), 16);
console.log(soniya); // 1792907907
console.log(new Date(soniya * 1000).toISOString());
// 2026-10-25T05:58:27.000Zmongosh'dagi getTimestamp() aynan shu ishni qiladi. Kanon chiqishi (MongoDB 8.3.13, mongosh 2.13.0):
const id = db.vazifalar.findOne({pgId: 1})._id;
printjson({hex: id.toHexString(), vaqt: id.getTimestamp()}){
hex: '6add9a837ffcaf2b9d405510',
vaqt: ISODate('2026-10-25T05:58:27.000Z')
}Bizning hisob bilan bir xil. Endi muhim kuzatuv: vazifaning o'z yaratilgan maydoni — 2026-10-01T03:30:00Z, ObjectId vaqti esa 2026-10-25T05:58:27Z. Nega farq?
ObjectId vaqti — hujjat Mongo'ga yozilgan payt, ya'ni kanon ko'chirish skriptini ishga tushirgan soniya. Vazifa esa Postgres'da ancha oldin yaratilgan. Shuning uchun ObjectId vaqtini biznes sana (vazifa qachon qo'shilgan) sifatida ishlatmang — ko'chirish, import yoki tiklashdan keyin u yolg'on gapiradi. Sanani alohida maydonda saqlang.
Diqqat: Darsdagi ObjectId'lar (
6add9a83…) kanon mashinasida yaratilgan. Siz o'zingizda ishga tushirsangiz, boshqa qiymat chiqadi — ObjectId va undagi vaqt deterministik emas. Shuning uchun keyingi darslarda chiqishdagi id'larga e'tibor bermang, tuzilmasiga qarang.
Tekshirib ko'ring: Ikki hujjatning
_idsi6add9a83…va6add9a84…bilan boshlanadi. Qaysi biri oldin yaratilgan va farq qancha?
Javob
Birinchi 8 belgi — soniyalar. 6add9a84 − 6add9a83 = 1, demak ikkinchisi taxminan 1 soniya keyin yaratilgan. Lekin "taxminan": vaqt soniya aniqligida, va ikki xil mashinaning soati bir xil bo'lmasligi mumkin.
5. Sxemasizlik: erkinlik va narxi
5.1 Kolleksiya hech narsani tekshirmaydi
Postgres'da matn ustuni text turida va NOT NULL — boshqa narsa kirmaydi (CREATE TABLE va cheklovlar). MongoDB kolleksiyasi esa sukut bo'yicha sxemasiz (schemaless): istalgan shakldagi hujjat kiradi.
Kanon buni sinadi — vazifalar kolleksiyasiga butunlay boshqa shakldagi hujjat yozdi, keyin matn maydonining BSON turi bo'yicha guruhladi:
await db.collection("vazifalar")
.insertOne({ matn: 42, nimadir: ["boshqa", "shakl"] });
await db.collection("vazifalar").aggregate([
{ $group: { _id: { $type: "$matn" }, n: { $sum: 1 } } },
{ $sort: { _id: 1 } },
]).toArray();Natija (kanon chiqishi):
turlar: [{"_id":"int","n":1},{"_id":"string","n":48}]48 ta hujjatda matn — satr, bittasida — butun son. Hech qanday xato yo'q. $group va $type ni Aggregation pipeline darsida batafsil ko'ramiz; hozir faqat natijaga qarang.
5.2 Narxi qayerda chiqadi
Bu erkinlik yozishda qulay — migratsiya yo'q, yangi maydon qo'shish oson. Narxi o'qishda to'lanadi: ilova matn.toUpperCase() qilsa, 42 li hujjatda TypeError yiqiladi. Yoki aggregation $size ni massiv bo'lmagan maydonda chaqirib xato beradi — kanon buni haqiqatan tutdi (Aggregation pipeline darsida, xato matni bilan).
DB turlari xaritasi darsidagi gapni eslang: "sxema baribir bor — faqat u bazada emas, kodingizda". Mongo dunyosida sxemani ikki joyda qo'yish mumkin:
- Ilovada — Mongoose kutubxonasi bilan (Mongoose: schema va model). Eng keng tarqalgan yo'l.
- Bazada — kolleksiyaga
$jsonSchemavalidator qo'shish. Bu MongoDB hujjatida bor (Schema Validation); kanon uni sinamadi, shuning uchun bu darsda faqat nomini aytamiz.
Tekshirib ko'ring: "Mongo sxemasiz, demak loyihalash kerak emas" — to'g'rimi?
Javob
Yo'q. Sxemasizlik — tekshiruv bazada yo'qligini bildiradi, sxema yo'qligini emas. Ilova baribir ma'lum shaklni kutadi. Shakl yozilmagan bo'lsa, u kodning har yeriga sochilib ketadi va xato o'qish paytida chiqadi. Shuning uchun Mongo loyihalarida ham sxema yoziladi — Mongoose'da yoki $jsonSchema da.
6. Vositalar: Docker, mongosh, Compass, Atlas
6.1 Docker'da MongoDB
Kanon MongoDB 8'ni Docker'da ko'tardi (Image, container va registry darsidagi buyruqlar). Kanon skriptidagi buyruq (qatorlar telefon uchun bo'lingan):
docker run -d --name kanon27-mongo \
-p 127.0.0.1:27018:27017 \
-v kanon27-mongo-data:/data/db \
mongo:8 --replSet rs0 --bind_ip_all-p 127.0.0.1:27018:27017— konteyner ichidagi 27017 (Mongo'ning sukut porti) kompyuterning 27018 portiga, faqat lokal manzilda.-v …:/data/db— ma'lumot volume'da, konteyner o'chsa ham qoladi (Volume va bind mount).--replSet rs0— bitta tugunli replica set. Tranzaksiya va change streams uchun kerak; Replica set, tranzaksiyalar va change streams darsida ochamiz. Hozir uni "Mongo'ning to'liq rejimi" deb qabul qiling.
Replica set bir marta ishga tushiriladi (kanon skriptidan):
docker exec kanon27-mongo mongosh --quiet --eval \
'rs.initiate({_id:"rs0",
members:[{_id:0, host:"127.0.0.1:27017"}]}).ok'Image mongo:8 — kanonda server 8.3.13, mongosh 2.13.0, database-tools 100.19.1 edi. Konteynerda autentifikatsiya yo'q — faqat lokal sinov uchun. Prodakshn sozlamasi (foydalanuvchi, parol, rollar) — MongoDB xavfsizligi darsida.
6.2 Ulanish satri
Ilova bazaga ulanish satri orqali ulanadi. Kanon satri:
const satr = "mongodb://127.0.0.1:27018/vazifalar"
+ "?replicaSet=rs0&directConnection=true";
const u = new URL(satr);
console.log(u.protocol); // mongodb:
console.log(u.host); // 127.0.0.1:27018
console.log(u.pathname); // /vazifalar
console.log(u.searchParams.get("replicaSet")); // rs0mongodb: — sxema, 127.0.0.1:27018 — server, /vazifalar — sukut baza, qolgani — sozlamalar. directConnection=true nega kerakligini keyingi darsda kanon xatosi bilan ko'ramiz: usiz drayver konteyner ichidagi manzilga ketib qoladi.
Bulut xizmatlari mongodb+srv:// sxemasini beradi: server ro'yxatini DNS'dan oladi. Bu hujjat bo'yicha; kanon sinamadi.
6.3 mongosh — terminal qobig'i
mongosh (MongoDB Shell) — Mongo'ning rasmiy terminal mijozi, psql'ning o'xshashi (psql chuqur). Ichida JavaScript ishlaydi: db — joriy baza, db.vazifalar — kolleksiya.
Kanon konteyner ichidagi mongosh'ni shunday chaqirdi:
docker exec -it kanon27-mongo mongosh \
"mongodb://127.0.0.1:27017/vazifalar?directConnection=true"Interaktiv rejimda vazifalar> taklifi chiqadi. Kanon har buyruqni --eval bilan yubordi — chiqishlar shundan. Kolleksiyalar ro'yxati va hujjatlar soni:
db.getCollectionNames()
db.vazifalar.countDocuments()[ 'vazifalar', 'foydalanuvchilar' ]
48Bitta hujjat, faqat kerakli maydonlar bilan. Ikkinchi argument — projection: 1 — ko'rsat, 0 — yashir:
db.vazifalar.findOne(
{pgId: 1},
{_id: 0, matn: 1, teglar: 1, yaratilgan: 1}
){
matn: "JavaScript kursining 26-qismini boshlash #o'qish",
yaratilgan: ISODate('2026-10-01T03:30:00.000Z'),
teglar: [ "o'qish" ]
}mongosh sanani ISODate(…) deb ko'rsatadi — bu BSON Date. Maydon nomlari qo'shtirnoqsiz, satrlar bittalik qo'shtirnoqda (apostrofli satr — ikkitalikda). Node konsolidagi format bilan ma'nosi bir xil.
Massiv maydon bo'yicha qidirish. teglar massiv, lekin filtrda oddiy satr yozamiz:
db.vazifalar.find({teglar: "ish"}, {_id: 0, pgId: 1})
.sort({pgId: 1}).limit(3).toArray()[ { pgId: 6 }, { pgId: 12 }, { pgId: 20 } ]{teglar: "ish"} — "teglar massivida ish elementi bor" degani. Mongo massivga tenglikni element bo'yicha tekshiradi. Postgres'da buning uchun 'ish' = ANY(teglar) yoki JOIN kerak edi (Massivlar, range, domain).
Bazaning hajmi:
db.stats().dataSize1358913 589 bayt — ikki kolleksiyadagi hujjatlar hajmi (siqilmagan). Diskdagi hajm boshqacha — WiredTiger saqlash dvigateli ma'lumotni siqadi. 500 000 vazifalik katta to'plamda bu farqni Aggregation pipeline darsida Postgres bilan solishtiramiz.
6.4 Compass va Atlas
- MongoDB Compass — rasmiy grafik dastur: hujjatlarni ko'rish, so'rov yozish, indekslar va explain'ni chizib ko'rsatish. pgAdmin'ning o'xshashi. Kanonda GUI o'rnatilmadi — sinalmagan.
- MongoDB Atlas — MongoDB kompaniyasining bulut xizmati (managed): server, zaxira, monitoring ularda. Bepul kichik klaster bor. Atlas Search va Vector Search uzoq vaqt faqat shu yerda edi. MongoDB 8.2 dan ular o'z serveringizda (Community Edition) ham sinov (preview) holatida bor — hujjatga ko'ra, 2026-10 holatiga (MongoDB xavfsizligi va operatsiyasi darsida tanishuv). Kanonda hisob ochilmadi — sinalmagan; tafsilot uchun mongodb.com/docs/atlas (2026-10-25 holatiga).
Maslahat: O'rganish uchun Docker yetadi: bepul, internet shart emas, xohlagan payt o'chirib qayta qurasiz. Atlas — real loyihada server boshqarishni xohlamasangiz.
7. Loyiha qadami: kanon tajribasi, loyihaga kirmaydi
Bu darsda vazifalar-api o'zgarmaydi. Kanon qilgan ish:
kanon27-mongokonteynerini yuqoridagi buyruq bilan ko'tardi (bitta tugunlirs0).- Postgres holat 11 namunasini (8 foydalanuvchi, 48 vazifa) Mongo'ga ko'chirdi: teglar va izohlar ichida, egasi — ishora.
- mongosh bilan kolleksiyalar, hujjat soni (48), projection, massiv qidiruvi va ObjectId vaqtini tekshirdi.
- Sxemasizlikni sinadi:
matn: 42jim kirdi.
Nega loyihaga kirmaydi? vazifalar ma'lumoti bog'langan (foydalanuvchi, vazifa, izoh, teg), hisobotlar va bir vaqtdagi yozuvlar bor — DB turlari xaritasi darsidagi tanlov hali ham to'g'ri. Mongo'ni taqqoslash uchun o'rganamiz: ish joyingizda Mongo'li loyiha chiqishi juda ehtimol.
8. Ko'p uchraydigan xatolar
| Xato | Oqibat | To'g'risi |
|---|---|---|
| ObjectId vaqtini "yaratilgan sana" deb ishlatish | Ko'chirish yoki importdan keyin sana yolg'on | Sanani alohida maydonda saqlang |
Sanani satr qilib yozish ("2026-10-01") |
Sana bo'yicha saralash va diapazon noto'g'ri ishlaydi | new Date(…) — BSON Date |
| "Sxemasiz — tekshirmasa ham bo'ladi" | Noto'g'ri turdagi hujjat o'qishda ilovani yiqitadi | Mongoose yoki $jsonSchema |
Kolleksiya nomida xato (db.vazifa) |
Xato yo'q — bo'sh natija; yozsangiz yangi kolleksiya ochiladi | db.getCollectionNames() bilan tekshiring |
| Porti 0.0.0.0 ga ochilgan, parolsiz Mongo | Internetdan hamma o'qiydi va o'chiradi | 127.0.0.1 va auth (xavfsizlik darsi) |
To'rtinchi qator Postgres'dan o'tgan o'quvchini ko'p chalg'itadi. Postgres relation "vazifa" does not exist deb baqiradi. Mongo esa jim: yo'q kolleksiyadan o'qish — bo'sh natija, yozish — yangi kolleksiya.
9. Mashqlar
Mashqlar kurs/mashqlar/27/42-mongodb-tuzilishi/ da. 2- va 3-mashq yechimlari Node 24 da tekshirilgan (biz ishga tushirdik, bazasiz).
1-mashq (oson): to'ldiring
- Mongo'da jadvalning o'xshashi —
- Hujjat diskda saqlanadigan ikkilik format —
- ObjectId necha baytdan iborat?
- ObjectId'ning birinchi necha bayti vaqt?
- Bitta hujjatning maksimal hajmi (MB) —
Yechim
- kolleksiya (collection) — hujjatlar guruhi, ustunlarni bilmaydi.
- BSON — sana, ObjectId, int/double, Decimal128 turlarini biladi.
- 12 bayt — ekranda 24 ta o'n oltilik belgi.
- 4 bayt — Unix soniyalari; qolgani tasodifiy qiymat (5) va hisoblagich (3).
- 16 MB — undan katta hujjatni yozib bo'lmaydi.
2-mashq (o'rta): ObjectId'dan vaqt
objectIdVaqti(hex) funksiyasini yozing: 24 belgili ObjectId satridan Date qaytarsin. Satr 24 ta o'n oltilik belgi bo'lmasa — TypeError tashlasin. Ikkita kanon id'si bilan sinang: 6add9a837ffcaf2b9d405510 (vazifa) va 6add9e3f1a1fac541a4002c0 (xavfsizlik darsida yaratilgan hujjat). Ular orasida necha soniya o'tgan?
Ishora: tekshiruv uchun /^[0-9a-f]{24}$/i (regex asoslari), vaqt uchun parseInt(…, 16).
Yechim
function objectIdVaqti(hex) {
if (!/^[0-9a-f]{24}$/i.test(hex)) {
throw new TypeError(`ObjectId emas: ${hex}`);
}
return new Date(parseInt(hex.slice(0, 8), 16) * 1000);
}
const a = objectIdVaqti("6add9a837ffcaf2b9d405510");
const b = objectIdVaqti("6add9e3f1a1fac541a4002c0");
console.log(a.toISOString());
console.log(b.toISOString());
console.log("farq:", (b - a) / 1000, "soniya");
try {
objectIdVaqti("123");
} catch (x) {
console.log(x.name, x.message);
}Konsolda:
2026-10-25T05:58:27.000Z
2026-10-25T06:14:23.000Z
farq: 956 soniya
TypeError ObjectId emas: 123956 soniya — 15 daqiqa 56 soniya: kanon ko'chirish skriptidan keyin xavfsizlik tajribasini ishga tushirgan oraliq. b - a — ikki Date ayirmasi millisekundlarda.
3-mashq (qiyin): qatorlardan hujjat
Postgres'dan uch xil qator keldi: vazifalar, izohlar, vazifa-teg bog'lanishlari. hujjatYasa(vazifalar, izohlar, teglar) funksiyasini yozing: har vazifaga teglar (satrlar massivi, alifbo tartibida) va izohlar ({ muallif, matn } massivi, id tartibida) qo'shilgan hujjatlar massivini qaytarsin. Izohsiz va tegsiz vazifada bo'sh massivlar bo'lsin. Postgres'dagi id ni pgId nomi bilan saqlang.
Ishora: Map bilan guruhlash — N+1 muammosi darsidagi batch usuli.
Yechim
const vazifalar = [
{ id: 1, matn: "Non olish #uy" },
{ id: 2, matn: "Hisobot #ish #tolov" },
{ id: 3, matn: "Kitob o'qish" },
];
const izohlar = [
{ id: 11, vazifa_id: 2, muallif: 1, matn: "Ertaga" },
{ id: 10, vazifa_id: 2, muallif: 2, matn: "Tez" },
{ id: 12, vazifa_id: 1, muallif: 1, matn: "Olindi" },
];
const teglar = [
{ vazifa_id: 2, nom: "tolov" },
{ vazifa_id: 2, nom: "ish" },
{ vazifa_id: 1, nom: "uy" },
];
function guruhla(qatorlar, kalit) {
const m = new Map();
for (const q of qatorlar) {
if (!m.has(q[kalit])) m.set(q[kalit], []);
m.get(q[kalit]).push(q);
}
return m;
}
function hujjatYasa(vazifalar, izohlar, teglar) {
const iz = guruhla([...izohlar].sort((a, b) => a.id - b.id),
"vazifa_id");
const tg = guruhla(teglar, "vazifa_id");
return vazifalar.map(({ id, ...qolgan }) => ({
pgId: id,
...qolgan,
teglar: (tg.get(id) ?? []).map((t) => t.nom).sort(),
izohlar: (iz.get(id) ?? [])
.map(({ muallif, matn }) => ({ muallif, matn })),
}));
}
for (const h of hujjatYasa(vazifalar, izohlar, teglar)) {
console.log(JSON.stringify(h));
}Konsolda:
{"pgId":1,"matn":"Non olish #uy","teglar":["uy"],"izohlar":[{"muallif":1,"matn":"Olindi"}]}
{"pgId":2,"matn":"Hisobot #ish #tolov","teglar":["ish","tolov"],"izohlar":[{"muallif":2,"matn":"Tez"},{"muallif":1,"matn":"Ertaga"}]}
{"pgId":3,"matn":"Kitob o'qish","teglar":[],"izohlar":[]}Kanon ko'chirishda xuddi shu ishni SQL tomonda qildi: array_agg(… ORDER BY t.nom) va json_agg(… ORDER BY i.id) (keyingi darsda kodi bilan). Bu yerda JavaScript'da — natija bir xil shakl. ?? [] — izohsiz vazifa uchun; usiz undefined.map xatosi chiqadi.
10. Real ishda
- MongoDB — eng mashhur hujjat bazasi: kontent tizimlari, katalog, log va hodisalar, mobil ilovalar backend'i. Node ekotizimida (MERN — Mongo, Express, React, Node) uzoq yillar standart juftlik bo'lgan, eski va yangi loyihalarda tez-tez uchraydi.
- Intervyu savollari: "ObjectId ichida nima bor?", "Mongo sxemasizmi?", "16 MB chegara nima uchun muhim?", "embed va reference farqi".
- Kompaniyalar ko'pincha Atlas'dan foydalanadi — server boshqaruvi ularda. Lokal ishlash va testda esa Docker konteyneri.
- Compass — qo'llab-quvvatlash va tahlil uchun qulay; dasturchilar kundalik ishda mongosh va drayverdan foydalanadi.
Xulosa
- MongoDB: server → baza → kolleksiya → hujjat; kolleksiya va baza birinchi yozuvda o'zi yaratiladi.
- Hujjat — ichma-ich obyekt va massivlar; diskda BSON (Date, ObjectId, int/double, Decimal128 bilan), maksimal 16 MB.
_idmajburiy va noyob; sukut — ObjectId: 4 bayt vaqt + 5 tasodifiy + 3 hisoblagich. Uning vaqti — yozilgan payt, biznes sana emas.- Kolleksiya sukut bo'yicha sxemani tekshirmaydi — kanonda
matn: 42jim kirdi; tekshiruv Mongoose'da yoki$jsonSchemada. - Vositalar: Docker'da
mongo:8, mongosh (psql o'xshashi), Compass (GUI), Atlas (bulut) — oxirgi ikkisi kanonda sinalmagan.
Keyingi dars: MongoDB native driver — rasmiy mongodb paketi bilan Node'dan ulanish, Postgres ma'lumotini ko'chirish, find, kursor va update operatorlari.
Manbalar
- MongoDB 8 hujjati — Documents (BSON,
_id, 16 MB chegara): https://www.mongodb.com/docs/manual/core/document/ - MongoDB hujjati — ObjectId: https://www.mongodb.com/docs/manual/reference/bson-types/#objectid
- MongoDB hujjati — Schema Validation (
$jsonSchema): https://www.mongodb.com/docs/manual/core/schema-validation/ - mongosh hujjati: https://www.mongodb.com/docs/mongodb-shell/
- MongoDB Compass va Atlas: https://www.mongodb.com/docs/compass/ , https://www.mongodb.com/docs/atlas/ (2026-10-25 holatiga; kanonda sinalmagan)
- IlmHamroh kanon tajribasi (2026-10-25): MongoDB 8.3.13 (Docker
mongo:8, bitta tugunlirs0), mongosh 2.13.0, mongodb 7.7.0, Node 24.21.0, Windows 11. Mashq yechimlari — biz ishga tushirdik (Node 24.21.0).
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!