6.3-bob: MongoDB chuqur — aggregation pipeline, indekslar, relations
6-QISM — Ma'lumotlar bazasi (Database) · 3-mavzu
1. Kirish va motivatsiya
6.2-bobda MongoDB'ning asosiy CRUD'ini o'rgandik. Endi uning kuchli, professional imkoniyatlariga o'tamiz — bularsiz "MongoDB bilaman" deyish qiyin: aggregation pipeline (murakkab ma'lumot tahlili, guruhlash, hisoblash), indekslar (qidiruvni tezlashtirish — chuqur), va relations (embed vs reference — to'g'ri modellashtirish). Bu uchtasi — MongoDB'ni "o'yinchoq"dan "professional vosita"ga aylantiradi.
Oddiy find 6.2-bob yetmaydigan vaziyatlar ko'p: "har kategoriya bo'yicha o'rtacha narx", "eng ko'p sotilgan 10 mahsulot", "har oyning daromadi", "foydalanuvchilarni davlat bo'yicha guruhlab sanash". Bularni find qila olmaydi — aggregation pipeline kerak (SQL'dagi GROUP BY, agregat funksiyalarning MongoDB ekvivalenti). Bu — ma'lumotni bosqichma-bosqich qayta ishlash quvuri (pipeline — 5.4: stream ruhida).
Indeks — qidiruv tezligining kaliti (6.2: 2.15'da tegingan). Indekssiz MongoDB millionlab hujjatni birma-bir ko'rib chiqadi (sekin); indeks bilan — to'g'ridan topadi (tez). Va relations — eng muhim dizayn qarori: bog'liq ma'lumotni birga saqlash (embed) yoki alohida + ishora (reference)? Bu tanlov ilovaning tezligi va moslashuvchanligini belgilaydi.
O'xshatish (aggregation): pipeline — zavod konveyeri. Xom ma'lumot (hujjatlar) bir uchidan kiradi, har bosqich (stage) uni qayta ishlaydi: filtrlaydi ($match — yaroqsizni chiqaradi), guruhlaydi ($group — bo'lib hisoblaydi), tartiblaydi ($sort), shaklini o'zgartiradi ($project). Oxirida — tayyor natija. Har bosqich oldingisining chiqishini oladi (5.4: stream).
Nega muhim?
- Murakkab tahlil —
findqila olmaydigan hisobot/guruhlash (aggregation). - Tezlik — indekssiz katta DB sekin; indeks — production'da hayotiy.
- To'g'ri dizayn — embed vs reference noto'g'ri tanlovi — qayta yozish.
- Professional daraja — bu uchtasiz MongoDB yuzaki qoladi.
2. Nazariya — chuqur tushuntirish
2.1. Aggregation pipeline nima
Aggregation pipeline — ma'lumotni bosqichlar (stages) ketma-ketligi orqali qayta ishlash (mongodb docs). Har bosqich hujjatlarni o'zgartiradi va keyingisiga uzatadi:
Collection [$match] [$group] [$sort] [$project] Natija
filtrla guruhla tartibla shaklla
Har bosqich OLDINGISINING chiqishini oladi (quvur — 5.4 ruhida)db.orders.aggregate([
{ $match: { holat: "tugallandi" } }, // 1. faqat tugallangan
{ $group: { _id: "$userId", jami: { $sum: "$summa" } } }, // 2. user bo'yicha jami
{ $sort: { jami: -1 } }, // 3. kamayish bo'yicha
{ $limit: 10 }, // 4. top 10
]);
findvsaggregate:find6.2-bob — oddiy filtrlash/o'qish.aggregate— murakkab qayta ishlash (guruhlash, hisoblash, birlashtirish). SQL'da:find≈SELECT ... WHERE;aggregate≈SELECT ... GROUP BY ... JOIN.
2.2. $match — filtrlash (eng oldinda)
$match — hujjatlarni filtrlaydi (find'dagi shart kabi — 6.2: 2.8):
{ $match: { holat: "faol", narx: { $gte: 1000 } } }
$matchni ENG OLDINGA qo'ying (mongodb docs): u hujjat sonini kamaytiradi — keyingi bosqichlar kamroq ma'lumot bilan ishlaydi (tez). Va boshida bo'lsa — indeksdan foydalanadi 2.9-bob. Bu — pipeline optimizatsiyasining asosiy qoidasi.
2.3. $group — guruhlash va hisoblash (eng muhim)
$group — hujjatlarni guruhlaydi va har guruh uchun hisoblaydi (SQL GROUP BY — mongodb docs):
{
$group: {
_id: "$kategoriya", // NIMA bo'yicha guruhlash (kategoriya)
jami: { $sum: "$narx" }, // har guruhda narxlar yig'indisi
ortacha: { $avg: "$narx" }, // o'rtacha
soni: { $sum: 1 }, // har guruhda nechta (har hujjatga +1)
eng_qimmat: { $max: "$narx" }, // maksimal
}
}Agregat funksiyalar:
$sum(yig'indi),$avg(o'rtacha),$min/$max,$count,$push(massivga yig'ish),$first/$last._id— guruhlash kaliti (_id: null— hammasini bitta guruhga).$group"bloklovchi" (barcha ma'lumotni kutadi — katta ma'lumotda ehtiyot — 2.10).
2.4. $project — shaklni o'zgartirish
$project — chiqish hujjatining shaklini belgilaydi (qaysi maydon, hisoblangan maydon):
{
$project: {
ism: 1, // qoldir
email: 1,
_id: 0, // olib tashla
toliqIsm: { $concat: ["$ism", " ", "$familiya"] }, // hisoblangan
yilNarx: { $multiply: ["$narx", 12] }, // hisoblash
}
}
$project—select(6.2: 2.9) ning kuchli versiyasi: maydonlarni tanlash + yangi hisoblangan maydonlar. Pipeline'da kerakmas maydonlarni erta olib tashlash — tezlikni oshiradi.
2.5. $lookup — collection'larni birlashtirish (JOIN)
$lookup — boshqa collection'dan ma'lumot qo'shadi (SQL JOIN — 6.2: 2.13 populate'ga o'xshash, lekin pipeline ichida):
{
$lookup: {
from: "users", // qaysi collection'dan
localField: "userId", // bu collection'dagi maydon
foreignField: "_id", // u collection'dagi maydon
as: "user", // natija qaysi maydonga (massiv)
}
}
// keyin $unwind bilan massivni yoyish: { $unwind: "$user" }
$lookupSEKIN bo'lishi mumkin (mongodb docs): u har hujjat uchun boshqa collection'da qidiradi. Ko'p ishlatish — performance muammosi. Yechim: ko'p birga-o'qiladigan ma'lumotni embed qiling 2.11-bob —$lookupkerak bo'lmaydi. JOIN — SQL'ning kuchi; MongoDB'da uni minimallashtiring.
2.6. Boshqa muhim bosqichlar
$sort — tartiblash ({ narx: -1 })
$limit — N ta ({ $limit: 10 })
$skip — o'tkazib yuborish (sahifalash)
$unwind — massivni alohida hujjatlarga yoyish ([a,b] 2 hujjat)
$count — hujjatlar soni
$addFields — yangi maydon qo'shish (boshqalarini saqlab)
$facet — bir vaqtda bir necha pipeline (ko'p hisobot birga)2.7. Pipeline tartibi (optimizatsiya)
To'g'ri tartib (tez):
$match (filtrla — kam qoldiradi) $sort $group $project
erta filtrlash = keyingi bosqichlar kam ma'lumot bilan (2.2)
Noto'g'ri:
$group (hammasini guruhla) $match (keyin filtrla)
avval hammasini qayta ishladi, keyin tashladi (isrof)Oltin qoida:
$matchva$sort— boshida (indeksdan foydalanadi — 2.9, hujjat sonini kamaytiradi).$group,$unwind— keyin (ulardan keyin indeks ishlamaydi — mongodb docs).
2.8. Indeks nima va qanday ishlaydi (chuqur)
Indeks — ma'lum maydon(lar) bo'yicha saralangan ma'lumotnoma (kitobning alfavit indeksi kabi):
Indekssiz qidiruv (collection scan):
{ email: "ali@a.uz" } BUTUN collection'ni birma-bir ko'rish (million hujjat — sekin!)
Indeks bilan (index scan):
email indeksi to'g'ridan "ali@a.uz" ni topish (B-tree — log vaqt — 3.6: tree)
1,000,000 hujjatda ham bir necha qadam (juda tez)Indeks — B-tree (3.6: balanslangan daraxt) tuzilmasi. Qidiruvni
O(n)(hammasini ko'rish) danO(log n)(daraxt bo'yicha) ga keltiradi (3.1: Big-O). Bu — katta DB'da hayot-mamot farqi (sekunddan millisekundga).
2.9. Indeks turlari
// Yagona indeks (bitta maydon)
userSchema.index({ email: 1 }); // 1: o'sish; -1: kamayish
// Birikma (compound) indeks (bir necha maydon)
orderSchema.index({ userId: 1, createdAt: -1 }); // userId + sana bo'yicha
// Noyob (unique) indeks
userSchema.index({ email: 1 }, { unique: true }); // takror email rad
// Matn (text) indeks — qidiruv uchun
productSchema.index({ nom: "text", tavsif: "text" }); // $text qidiruv
// TTL indeks — vaqt o'tgach o'chirish (5.18: OTP, sessiya)
otpSchema.index({ createdAt: 1 }, { expireAfterSeconds: 120 });Birikma indeks tartibi — ESR qoidasi (mongodb): Equality (aniq moslik) Sort (tartiblash) Range (oraliq). Masalan
{ userId: 1 (equality), createdAt: -1 (sort) }. Tartib muhim — noto'g'ri tartib indeksni befoyda qiladi.
2.10. Indeks narxi (har doim emas)
Indeks tekin emas — afzallik va narx balansi:
Indeks foydasi: qidiruv tez (o'qish — 2.8)
Indeks narxi:
- Yozish sekinroq (har insert/update'da indeks ham yangilanadi)
- Joy oladi (disk/RAM)
- Ko'p indeks — sekinlik, isrof
Tez-tez QIDIRILADIGAN maydonga indeks (email, userId, sana)
Kam ishlatiladiganga — kerak emasexplain() bilan tekshiring:
db.users.find({...}).explain("executionStats")— so'rov indeksdan foydalandimi (IXSCAN) yoki butun collection'ni ko'rdimi (COLLSCAN— yomon). Bu — 6.13 (query optimization) da chuqur.
2.11. Relations: Embed (birga saqlash)
MongoDB'da bog'liq ma'lumotni saqlashning birinchi yo'li — embed (ichiga joylash — 6.1: 2.10 denormalizatsiya):
// Foydalanuvchi va manzili — BIRGA (embed)
{
_id: 1, ism: "Ali",
manzil: { shahar: "Toshkent", kocha: "Amir Temur" }, // ichma-ich
telefonlar: [{ raqam: "+998901112233", tur: "ish" }], // massiv
}Embed afzalligi: bitta o'qishda hammasi keladi (JOIN/lookup yo'q — tez); atomik yangilash (bitta hujjat). Kamchiligi: hujjat kattalashadi; takror (agar boshqa joyda ham kerak bo'lsa). MongoDB hujjat chegarasi — 16MB (juda katta massivni embed qilmang).
2.12. Relations: Reference (ishora)
Ikkinchi yo'l — reference (boshqa collection'ga ishora — 6.1: 2.5 FK, 6.2: 2.13):
// Buyurtma — user'ga ishora (reference)
{ _id: 10, userId: ObjectId("1"), summa: 50000 } // userId — User'ga ishora
// User alohida collection'da; populate/lookup bilan birlashtiriladi (6.2: 2.13)Reference afzalligi: ma'lumot takrorlanmaydi (user bir joyda); mustaqil o'sadi (cheksiz buyurtma); ko'p joyda ulashiladi. Kamchiligi: birlashtirishga qo'shimcha so'rov (populate/$lookup — sekinroq).
2.13. Embed vs Reference — qachon qaysi biri (eng muhim qaror)
EMBED qiling (birga saqlang) — agar:
Bog'liq ma'lumot HAR DOIM birga o'qiladi (manzil, profil tafsiloti)
Soni KICHIK va CHEGARALANGAN (bir necha telefon, bir necha rasm)
Mustaqil o'zgarmaydi (parent bilan birga)
Atomik yangilash kerak
REFERENCE qiling (ishora) — agar:
Ma'lumot MUSTAQIL so'raladi (user — alohida ham kerak)
CHEKSIZ o'sadi (foydalanuvchining buyurtmalari — minglab)
Ko'p parent'da ULASHILADI (mahsulot — ko'p buyurtmada)
Tez-tez o'zgaradi (takror joyda yangilash muammosi)Misol (oneuptime/mongodb): foydalanuvchi manzili embed (birga, kichik). Foydalanuvchi buyurtmalari reference (cheksiz, mustaqil). Blog post + kommentlar kommentlar kam bo'lsa embed, ko'p bo'lsa reference. Qoida: "birga o'qiladimi + kichikmi?" embed; "mustaqilmi + ko'paymi?" reference.
2.14. One-to-Few, One-to-Many, Many-to-Many
One-to-Few (1:bir necha) — embed (user bir necha manzil)
One-to-Many (1:ko'p) — reference (user minglab buyurtma)
Many-to-Many (ko'p:ko'p) — reference (talaba kurslar; ikki tomon ID massivi)Many-to-Many misoli: talaba bir necha kursga, kurs bir necha talabaga. MongoDB'da — har ikkisida ID massivi (
student.kurslar: [id],course.talabalar: [id]), yoki oraliq collection (SQL'dagi junction table — 6.7). SQL bu yerda tabiiyroq (JOIN).
2.15. Mongoose'da aggregation va indeks
// Aggregation (Mongoose model orqali — 6.2: 2.6)
const natija = await Order.aggregate([
{ $match: { holat: "tugallandi" } },
{ $group: { _id: "$userId", jami: { $sum: "$summa" } } },
]);
// Indeks (schema'da — 6.2: 2.15)
orderSchema.index({ userId: 1, createdAt: -1 }); // birikma (2.9)
// Mongoose ilova boshida indekslarni avtomatik yaratadi (autoIndex)Production'da
autoIndex: false: Mongoose har ishga tushganda indeks yaratishga urinadi (dev'da qulay, production'da sekin). Production'da indekslarni alohida (deploy paytida) yarating (autoIndex: false).
2.16. Aggregation use-case'lar (real)
E-commerce: har kategoriya daromadi; top mahsulotlar; oylik savdo
Ijtimoiy: har post like/komment soni; faol foydalanuvchilar
Analitika: kunlik/oylik statistika; o'rtacha qiymatlar
Hisobot: guruhlangan, hisoblangan ma'lumot (dashboard — 11)2.17. Xavfsizlik va best practices (14)
$match'ni oldinga (indeks + kam ma'lumot — 2.2, 2.7)
$lookup'ni minimallashtiring (embed afzal — 2.5)
Tez-qidiriladigan maydonga indeks 2.10-bob; explain() bilan tekshiring
Hujjat 16MB chegarasi (katta massivni embed qilmang — 2.11)
Aggregation'da foydalanuvchi kiritgan ma'lumotni validatsiya (injection — 14)
Katta $group — xotira (allowDiskUse kerak bo'lishi mumkin — 2.3)
Production'da autoIndex: false (2.15)2.18. Tranzaksiyalar (bir necha hujjatni atomik o'zgartirish)
Bitta hujjatni yangilash MongoDB'da doim atomik (embed'ning kuchi — 2.11). Ammo bir necha hujjat (yoki bir necha collection) birgalikda o'zgarishi kerak bo'lsa — masalan pul o'tkazmasida bir hisobdan yechib, ikkinchisiga qo'shish — tranzaksiya kerak. Tranzaksiya: yo hammasi bajariladi, yo hech biri (SQL'dagi ACID atomiklik — 6.1).
const session = await mongoose.startSession();
try {
await session.withTransaction(async () => {
await Account.updateOne({ _id: a }, { $inc: { balans: -100 } }, { session });
await Account.updateOne({ _id: b }, { $inc: { balans: +100 } }, { session });
}); // ikkisi ham muvaffaqiyatli commit; biri xato hammasi bekor (rollback)
} finally {
session.endSession();
}Tranzaksiya faqat replica set'da: MongoDB tranzaksiyalari replica set (yoki sharded cluster) talab qiladi — yakka (standalone) serverda ishlamaydi. Development'da bitta tugunli replica set yetadi. Narxi bor (bloklash, sekinroq) — shuning uchun tranzaksiyadan faqat haqiqatan bir necha hujjat atomik bo'lishi shart bo'lganda foydalaning. Ko'p holatda to'g'ri embed (bog'liq ma'lumot bitta hujjatda — 2.11) tranzaksiya zaruriyatini yo'q qiladi.
3. Sintaksis — tez ma'lumotnoma
// Aggregation (2.1)
await Model.aggregate([
{ $match: { ... } }, // filtrla (oldinda — 2.2)
{ $group: { _id: "$field", jami: { $sum: "$x" }, soni: { $sum: 1 } } }, // guruhla (2.3)
{ $sort: { jami: -1 } }, // tartibla
{ $project: { _id: 0, ism: 1 } }, // shaklla (2.4)
{ $lookup: { from, localField, foreignField, as } }, // JOIN (2.5)
]);
// Indeks (2.9)
schema.index({ email: 1 }, { unique: true });
schema.index({ userId: 1, createdAt: -1 }); // birikma (ESR — 2.9)
// Embed vs reference 2.13-bob: birga+kichik embed; mustaqil+ko'p reference4. Batafsil kod namunalari
Misol 1 — Oddiy aggregation (kategoriya bo'yicha — 2.1, 2.3)
// Har kategoriya bo'yicha mahsulot soni va o'rtacha narx
const statistika = await Product.aggregate([
{ $match: { faol: true } }, // 1. faqat faol (oldinda — 2.2)
{
$group: {
_id: "$kategoriya", // kategoriya bo'yicha guruhla (2.3)
soni: { $sum: 1 }, // har guruhda nechta
ortachaNarx: { $avg: "$narx" }, // o'rtacha narx
engQimmat: { $max: "$narx" }, // eng qimmat
},
},
{ $sort: { soni: -1 } }, // ko'pdan kamga (2.6)
]);
// Natija: [{ _id: "telefon", soni: 45, ortachaNarx: 3500000, ... }, ...]Misol 2 — Top 10 mijoz (sotuv bo'yicha — 2.3, 2.5)
// Eng ko'p xarid qilgan 10 mijoz (user ma'lumoti bilan)
const topMijozlar = await Order.aggregate([
{ $match: { holat: "tugallandi" } }, // tugallangan buyurtmalar
{
$group: {
_id: "$userId", // mijoz bo'yicha
jamiXarid: { $sum: "$summa" }, // jami summa
buyurtmaSoni: { $sum: 1 },
},
},
{ $sort: { jamiXarid: -1 } }, // kamayish
{ $limit: 10 }, // top 10 (2.6)
{
$lookup: { // user ma'lumotini qo'sh (2.5)
from: "users", localField: "_id", foreignField: "_id", as: "user",
},
},
{ $unwind: "$user" }, // massivni yoy (2.6)
{ $project: { _id: 0, ism: "$user.ism", jamiXarid: 1, buyurtmaSoni: 1 } }, // shaklla (2.4)
]);Misol 3 — Oylik daromad hisoboti (sana guruhlash — 2.3)
// Har oyning daromadi (dashboard uchun — 2.16)
const oylikDaromad = await Order.aggregate([
{ $match: { holat: "tugallandi", createdAt: { $gte: new Date("2026-01-01") } } },
{
$group: {
_id: { yil: { $year: "$createdAt" }, oy: { $month: "$createdAt" } }, // yil+oy bo'yicha
daromad: { $sum: "$summa" },
buyurtmalar: { $sum: 1 },
},
},
{ $sort: { "_id.yil": 1, "_id.oy": 1 } }, // xronologik
]);
// Natija: [{ _id: { yil: 2026, oy: 1 }, daromad: 15000000, buyurtmalar: 320 }, ...]Misol 4 — $facet (bir vaqtda ko'p hisobot — 2.6)
// Bitta so'rovda bir necha statistika (dashboard — 2.16)
const dashboard = await Order.aggregate([
{
$facet: {
jami: [{ $group: { _id: null, summa: { $sum: "$summa" }, soni: { $sum: 1 } } }],
holatBoyicha: [{ $group: { _id: "$holat", soni: { $sum: 1 } } }],
songgi5: [{ $sort: { createdAt: -1 } }, { $limit: 5 }],
},
},
]);
// dashboard[0].jami, .holatBoyicha, .songgi5 — hammasi bir so'rovdaMisol 5 — Indekslar (schema'da — 2.9)
const productSchema = new mongoose.Schema({
nom: String, narx: Number, kategoriya: String, userId: mongoose.Schema.Types.ObjectId,
}, { timestamps: true });
// Yagona indeks (tez-qidiriladigan — 2.9)
productSchema.index({ kategoriya: 1 });
// Birikma indeks (ESR qoidasi: equality sort — 2.9)
productSchema.index({ kategoriya: 1, narx: -1 }); // kategoriya bo'yicha, narx tartibida
// Matn indeks (qidiruv — 2.9)
productSchema.index({ nom: "text", tavsif: "text" });
// Production'da avtomatik indeks o'chirilgan (2.15)
mongoose.set("autoIndex", process.env.NODE_ENV !== "production");
export const Product = mongoose.model("Product", productSchema);
// Matn qidiruv (text indeks bilan)
await Product.find({ $text: { $search: "telefon" } });Misol 6 — Embed modellashtirish (one-to-few — 2.11, 2.13)
// Foydalanuvchi + manzillari (embed — kichik, birga o'qiladi — 2.13)
const userSchema = new mongoose.Schema({
ism: String,
email: String,
manzillar: [{ // embed massiv (one-to-few — 2.14)
shahar: String,
kocha: String,
asosiy: { type: Boolean, default: false },
}],
});
// Bitta o'qishda user + barcha manzillar (JOIN yo'q — tez — 2.11)
const user = await User.findById(id);
console.log(user.manzillar); // darrov bor (qo'shimcha so'rovsiz)Misol 7 — Reference modellashtirish (one-to-many — 2.12, 2.13)
// Buyurtma — user'ga reference (cheksiz o'sadi — 2.13, 2.14)
const orderSchema = new mongoose.Schema({
user: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true, index: true }, // indeks!
mahsulotlar: [{
mahsulot: { type: mongoose.Schema.Types.ObjectId, ref: "Product" },
miqdor: Number,
narx: Number, // narxni NUSXALANG (mahsulot narxi keyin o'zgarsa ham — snapshot)
}],
summa: Number,
}, { timestamps: true });
// populate bilan birlashtirish (6.2: 2.13)
const order = await Order.findById(id).populate("user", "ism email");Muhim nuans: buyurtmadagi
narx— mahsulotga reference qilinsa ham, nusxalanadi (snapshot). Sababi: mahsulot narxi keyin o'zgarsa, eski buyurtma o'sha vaqtdagi narxni saqlashi kerak (tarix). Bu — embed/reference aralashmasi (amaliy hikmat).
Misol 8 — Many-to-Many (2.14)
// Talaba Kurs (many-to-many — 2.14)
const studentSchema = new mongoose.Schema({
ism: String,
kurslar: [{ type: mongoose.Schema.Types.ObjectId, ref: "Course" }], // ID massivi
});
const courseSchema = new mongoose.Schema({
nom: String,
talabalar: [{ type: mongoose.Schema.Types.ObjectId, ref: "Student" }],
});
// Talaba kurslari: Student.findById(id).populate("kurslar")
// Ikki tomonni sinxron saqlash kerak (talabaga kurs qo'shsangiz, kursga talaba ham)
// Murakkab bog'lanish — ba'zan SQL (JOIN) tabiiyroq (6.7)5. To'g'ri va noto'g'ri holatlar
1) $match'ni oxirga qo'yish
// avval hammasini guruhla, keyin filtrla (isrof — 2.7)
[{ $group: {...} }, { $match: {...} }]
// avval filtrla (kam ma'lumot — 2.2)
[{ $match: {...} }, { $group: {...} }]2) Tez-qidiriladigan maydonga indekssiz
email/userId indekssiz million hujjatda sekin (COLLSCAN — 2.8)
index({ email: 1 }) (IXSCAN — tez)3) Cheksiz o'sadigan ma'lumotni embed qilish
// foydalanuvchining barcha buyurtmalari embed (16MB chegara — 2.11)
{ ism: "Ali", buyurtmalar: [/* minglab */] }
// reference (mustaqil collection — 2.12, 2.13)4) $lookup'ni ortiqcha ishlatish
har so'rovda ko'p $lookup (sekin — 2.5)
ko'p-o'qiladigan ma'lumotni embed (lookup'siz — 2.13)5) Ko'p kerakmas indeks
har maydonga indeks (yozish sekin, joy — 2.10)
faqat tez-qidiriladigan maydon (explain() bilan tekshiring)6. Keng tarqalgan xatolar va yechimlari
Xato 1 — Aggregation sekin
Sababi: $match oldinda emas; indeks yo'q 2.7-bob. Yechimi: $match/$sort boshida; tegishli indeks; explain() bilan tahlil qiling.
Xato 2 — $group xotira xatosi (katta ma'lumot)
Sababi: $group bloklovchi, ko'p ma'lumotni xotiraga oladi 2.3-bob. Yechimi: $match bilan kamaytiring; { allowDiskUse: true }.
Xato 3 — Indeks yaratilmaydi (production sekin)
Sababi: autoIndex production'da 2.15-bob. Yechimi: autoIndex: false; indekslarni alohida yarating.
Xato 4 — Embed qilingan hujjat 16MB'dan oshdi
Sababi: cheksiz massivni embed 2.11-bob. Yechimi: reference'ga o'tkazing 2.13-bob.
Xato 5 — $lookup natijasi massiv (kutilmagan)
Sababi: $lookup doim massiv qaytaradi 2.5-bob. Yechimi: $unwind bilan yoying (bitta bo'lsa).
Xato 6 — Embed ma'lumot eskirdi (takror)
Sababi: embed qilingan ma'lumot manbada o'zgardi, nusxasi eski 2.13-bob. Yechimi: o'zgaruvchan ma'lumot — reference; yoki yangilashda barcha nusxani.
7. Integratsiya — bu mavzu stack'ning qayerida uchraydi
- MongoDB/Mongoose 6.2-bob: asosiy CRUD; bu — chuqurlashtirish.
- DB asoslari 6.1-bob: normalizatsiya/denormalizatsiya, relations.
- Tree 3.6-bob: indeks — B-tree; Big-O 3.1-bob.
- Stream 5.4-bob: pipeline g'oyasi.
- Query optimization 6.13-bob: explain, indeks tahlili.
- SQL JOIN 6.7-bob: $lookup ekvivalenti.
- Dashboard (11): aggregation hisobotlari.
- Performance 5.21-bob: indeks + kesh birga.
- NestJS 8.13-bob: Mongoose aggregation.
8. Eng yaxshi amaliyotlar (best practices)
- $match/$sort pipeline boshida (indeks + kam ma'lumot — 2.2, 2.7).
- $lookup minimallashtiring (embed afzal — 2.5, 2.13).
- Tez-qidiriladigan maydonga indeks (email, ref, sana — 2.9, 2.10).
- Birikma indeks ESR tartibida (equality sort range — 2.9).
- explain() bilan tekshiring (COLLSCAN yomon, IXSCAN yaxshi — 2.10).
- Embed: birga+kichik+chegaralangan; reference: mustaqil+ko'p 2.13-bob.
- Hujjat 16MB chegarasi (cheksiz embed qilma — 2.11).
- O'zgaruvchan/takror ma'lumotda snapshot yoki reference (2.13, Misol 7).
- Production'da autoIndex: false 2.15-bob.
- Katta $group — allowDiskUse 2.3-bob; foydalanuvchi ma'lumotini validatsiya (14).
9. Amaliy loyiha: "Analitika va Optimizatsiya (MongoDB)"
MongoDB'ning kuchli imkoniyatlarini mustahkamlash.
Maqsad
Aggregation pipeline, indekslar va to'g'ri relations modellashtirish bilan tahliliy, tez ishlaydigan ma'lumot qatlamini qurish (e-commerce yoki ijtimoiy tarmoq).
Talablar (requirements)
- Modellar: User, Product, Order — embed va reference to'g'ri tanlangan (Misol 6, 7, 2.13).
- Aggregation hisobotlar: kategoriya bo'yicha statistika; top mijozlar; oylik daromad (Misol 1-3, 2.3).
- $lookup: buyurtma + user/mahsulot birlashtirish (Misol 2, 2.5).
- $facet: dashboard uchun bir necha hisobot bir so'rovda (Misol 4, 2.6).
- Indekslar: tez-qidiriladigan maydonlarga; birikma (ESR); matn qidiruv (Misol 5, 2.9).
- Pipeline optimizatsiya: $match oldinda; explain() bilan tekshiring (2.7, 2.10).
- Many-to-many: misol (talaba-kurs yoki teg-mahsulot — Misol 8, 2.14).
- Snapshot: buyurtmada narxni nusxalash (Misol 7, 2.13).
- Production: autoIndex: false 2.15-bob.
Maslahatlar (hint)
- $match birinchi (indeks + kam ma'lumot — 2.7).
- $group:
{ _id: "$field", jami: { $sum: "$x" }, soni: { $sum: 1 } }2.3-bob. - Embed: kichik+birga; reference: ko'p+mustaqil 2.13-bob.
- Birikma indeks ESR (equalitysort — 2.9).
- $lookup natijasi massiv $unwind (5-xato).
- explain("executionStats") — IXSCAN bo'lsin 2.10-bob.
"Tayyor" mezonlari (acceptance criteria)
- Modellar embed/reference to'g'ri tanlangan (asoslangan).
- Aggregation hisobotlar ishlaydi (guruhlash, hisoblash).
- $lookup bilan birlashtirish.
- $facet bilan dashboard.
- Indekslar (yagona, birikma, matn).
- $match oldinda; explain IXSCAN ko'rsatadi.
- Many-to-many misoli.
- Snapshot (buyurtma narxi).
Yechim kodi ataylab berilmagan — bu loyihani o'zingiz yozib ko'ring.
10. Xulosa va keyingi bobga ko'prik
Bu bobda MongoDB'ning professional imkoniyatlarini chuqur o'rgandik:
- Aggregation pipeline (bosqichlar quvuri — 2.1): $match (filtr, oldinda — 2.2), $group (guruhlash/hisoblash — 2.3), $project (shakl — 2.4), $lookup (JOIN — 2.5); tartib optimizatsiyasi 2.7-bob.
- Indekslar (B-tree, qidiruv tezligi — 2.8); turlari (yagona/birikma/unique/text/TTL — 2.9); ESR qoidasi; narxi (yozish/joy — 2.10); explain().
- Relations: embed (birga, kichik — 2.11) vs reference (mustaqil, ko'p — 2.12); qachon qaysi biri 2.13-bob; one-to-few/many, many-to-many 2.14-bob.
- Tranzaksiyalar (bir necha hujjatni atomik — replica set — 2.18).
- Use-case'lar (hisobot/dashboard — 2.16); xavfsizlik/performance 2.17-bob.
Keyingi bob — 6.4-bob: SQL asoslari — CREATE, INSERT, SELECT, UPDATE, DELETE, WHERE. MongoDB (NoSQL) dunyosini chuqur ko'rdik; endi ikkinchi katta dunyoga — relatsion DB va SQL tiliga — o'tamiz. Jadval yaratish, ma'lumot qo'shish/o'qish/yangilash/o'chirish, shartlar (WHERE), turlar va cheklovlar (constraints) — SQL'ning poydevori. Bu — PostgreSQL/MySQL va ORM'lar uchun asos.
Foydalanilgan rasmiy/ishonchli manbalar
- mongodb.com/docs — Aggregation Pipeline ($match, $group, $lookup, $project), optimization
- mongodb.com/docs/data-modeling — Embedding vs References best practices; ESR indeks qoidasi
- mongodb.com — Performance Best Practices: Indexing
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!