Ma'lumotlar bazalari

MongoDB (NoSQL)

MongoDB โ€” eng mashhur hujjatli NoSQL baza. U ma'lumotni jadval emas, JSON-simon hujjatlar ko'rinishida saqlaydi. Node.js dasturchilari uni yaxshi ko'radi, chunki hujjatlar JavaScript obyektlariga juda o'xshaydi. Ushbu darsda MongoDB'ning asosiy amallarini o'rganamiz va ularni SQL bilan solishtiramiz.

Kolleksiya va hujjat

MongoDB'da ma'lumot ikki darajali tuzilishda saqlanadi:

Hujjat quyidagicha ko'rinadi (BSON, ya'ni JSON'ning ichki formati):

{
  "_id": ObjectId("64a1f..."),
  "name": "Ali",
  "email": "ali@mail.com",
  "age": 25,
  "hobbies": ["futbol", "kitob"]
}
Har bir hujjat avtomatik _id maydoniga ega bo'ladi โ€” bu SQL'dagi PRIMARY KEY'ga o'xshaydi. Agar siz _id bermasangiz, MongoDB o'zi ObjectId โ€” takrorlanmaydigan maxsus identifikator yaratadi.

SQL bilan atamalar taqqosi

MongoDB'ga o'tishdan oldin atamalarni SQL bilan solishtirib olaylik:

SQL              MongoDB
-------------    ----------------------
database         database
table (jadval)   collection (kolleksiya)
row (qator)      document (hujjat)
column (ustun)   field (maydon)
PRIMARY KEY id   _id
INSERT           insertOne / insertMany
SELECT           find / findOne
UPDATE           updateOne / updateMany
DELETE           deleteOne / deleteMany
WHERE            filtr obyekti { ... }

Hujjat qo'shish: insertOne va insertMany

Yangi hujjat qo'shish uchun insertOne ishlatiladi. Buyruqlar JavaScript obyekti sifatida yoziladi:

db.users.insertOne({
  name: "Ali",
  email: "ali@mail.com",
  age: 25
});

Bu yerda db.users โ€” users kolleksiyasi (agar mavjud bo'lmasa, avtomatik yaratiladi). Bir necha hujjatni birdaniga qo'shish uchun insertMany massiv qabul qiladi:

db.users.insertMany([
  { name: "Vali", email: "vali@mail.com", age: 30 },
  { name: "Guli", email: "guli@mail.com", age: 22 }
]);

SQL bilan solishtiring: SQL'da avval CREATE TABLE bilan tuzilishni belgilash kerak edi. MongoDB'da esa hujjatni to'g'ridan-to'g'ri qo'shasiz โ€” tuzilish oldindan belgilanmaydi.

Ma'lumot o'qish: find va findOne

Hujjatlarni o'qish uchun find ishlatiladi. Bo'sh {} filtr barcha hujjatlarni qaytaradi (SQL'dagi SELECT * kabi):

db.users.find({});          // barcha foydalanuvchilar
db.users.findOne({});       // faqat bitta (birinchi) hujjat

Filtrlash uchun find ichiga obyekt beriladi. Bu obyekt SQL'dagi WHERE vazifasini bajaradi:

// SQL:     SELECT * FROM users WHERE name = 'Ali';
db.users.find({ name: "Ali" });

// SQL:     SELECT * FROM users WHERE age = 25;
db.users.find({ age: 25 });

Agar obyektda bir necha maydon bo'lsa, ular VA (AND) bilan birlashadi:

// SQL:  ... WHERE name = 'Ali' AND age = 25;
db.users.find({ name: "Ali", age: 25 });
Faqat kerakli maydonlarni olish uchun findning ikkinchi argumenti (projection) beriladi: db.users.find({}, { name: 1, email: 1 }) โ€” bu faqat name va email (hamda _id) qaytaradi. Bu SQL'dagi SELECT name, email ga o'xshaydi.

So'rov operatorlari: $gt, $lt, $in va boshqalar

"Katta", "kichik", "ro'yxatda" kabi shartlar uchun MongoDB maxsus operatorlardan foydalanadi. Ular $ belgisi bilan boshlanadi va obyekt ichida yoziladi:

// SQL:  ... WHERE age > 25;
db.users.find({ age: { $gt: 25 } });

// SQL:  ... WHERE age >= 20 AND age <= 30;
db.users.find({ age: { $gte: 20, $lte: 30 } });

// SQL:  ... WHERE age IN (22, 25, 30);
db.users.find({ age: { $in: [22, 25, 30] } });

OR shartini yozish uchun $or operatori ishlatiladi (u shartlar massivini oladi):

// SQL:  ... WHERE name = 'Ali' OR name = 'Vali';
db.users.find({
  $or: [
    { name: "Ali" },
    { name: "Vali" }
  ]
});
Saralash va cheklash ham bor: db.users.find().sort({ age: -1 }).limit(3) โ€” yosh bo'yicha kamayish tartibida (-1) 3 ta hujjat. Bu SQL'dagi ORDER BY age DESC LIMIT 3 ga teng. 1 โ€” o'sish, -1 โ€” kamayish.

Ma'lumotni o'zgartirish: updateOne va $set

Hujjatni o'zgartirish uchun updateOne ikki argument oladi: (1) qaysi hujjat(lar)ni topish (filtr), (2) qanday o'zgartirish. O'zgartirishda $set operatori ishlatiladi:

// SQL:  UPDATE users SET age = 26 WHERE name = 'Ali';
db.users.updateOne(
  { name: "Ali" },        // qaysi hujjat
  { $set: { age: 26 } }   // nimani o'zgartirish
);
$setni unutmang! Agar shunchaki db.users.updateOne({ name: "Ali" }, { age: 26 }) yozsangiz, MongoDB butun hujjatni { age: 26 } bilan almashtiradi โ€” name, email va boshqa maydonlar yo'qoladi! $set esa faqat ko'rsatilgan maydonni o'zgartiradi.

Bir necha hujjatni bir vaqtda o'zgartirish uchun updateMany ishlatiladi:

// 25 yoshdan kichiklarning hammasini faolsizlantirish
db.users.updateMany(
  { age: { $lt: 25 } },
  { $set: { is_active: false } }
);
Boshqa foydali o'zgartirish operatorlari: $inc โ€” sonni oshiradi/kamaytiradi ({ $inc: { age: 1 } } โ€” yoshni 1ga oshiradi), $push โ€” massivga element qo'shadi, $unset โ€” maydonni o'chiradi.

Hujjatni o'chirish: deleteOne va deleteMany

O'chirish uchun deleteOne (birinchi mos hujjatni) yoki deleteMany (barcha mos hujjatlarni) ishlatiladi:

// SQL:  DELETE FROM users WHERE name = 'Guli';
db.users.deleteOne({ name: "Guli" });

// SQL:  DELETE FROM users WHERE age < 18;
db.users.deleteMany({ age: { $lt: 18 } });
db.users.deleteMany({}) โ€” bo'sh filtr bilan chaqirilsa, kolleksiyadagi BARCHA hujjatlarni o'chiradi! SQL'dagi DELETE FROM users; kabi ehtiyot bo'ling.

MongoDB'ning kuchli va zaif tomonlari

MongoDB har doim ham eng yaxshi tanlov emas. Uni tanlashdan oldin farqlarni bilish muhim:

Ko'p JOIN va murakkab hisobotlar kerak bo'lsa โ€” SQL bazani tanlang. Ma'lumot tuzilishi tez o'zgarsa yoki hujjat ko'rinishi tabiiy bo'lsa (masalan, mahsulot katalogi turli xususiyatlar bilan) โ€” MongoDB qulay bo'lishi mumkin.

Xulosa