Query operatorlari — $eq, $gt, $lt, $in, $nin, $exists, $regex
Muammodan boshlaylik
Oldingi darsda oddiy filterlarni ko'rdik: { shahar: "Toshkent" }.
Lekin real hayotda so'rovlar murakkabroq bo'ladi:
- 18 yoshdan katta va 30 yoshdan kichik talabalar
- Toshkent yoki Samarqandda yashovchilar
- Telefon raqami bo'lmaganlar
- Ismi "A" harfi bilan boshlanadigan foydalanuvchilar
- Aktiv bo'lmagan yoki o'chirilgan accountlar
Bularning barchasi uchun MongoDB da maxsus query operatorlari bor.
Operatorlar — umumiy ko'rinish
┌─────────────────────────────────────────────────────────────────┐
│ TAQQOSLASH │ MANTIQIY │ ELEMENT │
│ $eq = │ $and VA │ $exists mavjudmi │
│ $ne != │ $or YOKI │ $type tipi │
│ $gt > │ $not EMAS │ │
│ $gte >= │ $nor NA VA NA │ ARRAY │
│ $lt < │ │ $all hammasi │
│ $lte <= │ QIDIRISH │ $elemMatch │
│ $in ichida │ $regex pattern │ $size uzunlik │
│ $nin tashqarida │ $text full-text │ │
└─────────────────────────────────────────────────────────────────┘
Bu darsda eng ko'p ishlatiladiganlari — birin-ketin ko'ramiz.
Taqqoslash operatorlari
$eq — teng
// Ikkalasi bir xil
db.talabalar.find({ yosh: 24 })
db.talabalar.find({ yosh: { $eq: 24 } })
// $eq odatda to'g'ridan-to'g'ri yoziladi — qisqaroq
$ne — teng emas
// Toshkentda bo'lmaganlar
db.talabalar.find({ shahar: { $ne: "Toshkent" } })
// Faol bo'lmaganlar
db.foydalanuvchilar.find({ faol: { $ne: true } })
SQL: WHERE shahar != 'Toshkent'
$gt, $gte, $lt, $lte — kattalik-kichiklik
$gt → > strictly greater than
$gte → >= greater than or equal
$lt → < strictly less than
$lte → <= less than or equal
Sonlar: { narx: { $gt: 50000 } }
Sanalar: { sana: { $gt: new Date("2024-01-01") } }
Matnlar: { ism: { $gt: "M" } } ← "M" dan keyin alfavit bo'yicha
// 18 dan katta
db.talabalar.find({ yosh: { $gt: 18 } })
// 18 va 25 oraliq
db.talabalar.find({ yosh: { $gte: 18, $lte: 25 } })
// Narxi 100,000 dan past mahsulotlar
db.mahsulotlar.find({ narx: { $lt: 100000 } })
// 2024-yil yanvardan keyin yaratilganlar
db.postlar.find({ yaratilgan: { $gte: new Date("2024-01-01") } })
SQL bilan:
SELECT * FROM talabalar WHERE yosh > 18;
SELECT * FROM talabalar WHERE yosh BETWEEN 18 AND 25;
$in va $nin — ro'yxatda bor/yo'q
$in — ro'yxatdagi qiymatlardan biri
// Toshkent, Samarqand yoki Namanganda
db.talabalar.find({ shahar: { $in: ["Toshkent", "Samarqand", "Namangan"] } })
// 10A, 10B yoki 10C sinflarda
db.talabalar.find({ sinf: { $in: ["10A", "10B", "10C"] } })
SQL: WHERE shahar IN ('Toshkent', 'Samarqand', 'Namangan')
$nin — ro'yxatdagi qiymatlardan hech biri emas
// Toshkentda ham, Samarqandda ham emas
db.talabalar.find({ shahar: { $nin: ["Toshkent", "Samarqand"] } })
SQL: WHERE shahar NOT IN ('Toshkent', 'Samarqand')
$in — array maydonlarda qudratli
// Massiv maydonida $in — element shu massivda bormi?
db.talabalar.insertMany([
{ ism: "Jasur", hobbylar: ["dasturlash", "futbol"] },
{ ism: "Malika", hobbylar: ["raqs", "musiqa"] },
{ ism: "Bobur", hobbylar: ["futbol", "shaxmat"] },
])
// Futbol yoki musiqa hobbysi borlar
db.talabalar.find({ hobbylar: { $in: ["futbol", "musiqa"] } })
// → Jasur (futbol bor), Malika (musiqa bor), Bobur (futbol bor)
Mantiqiy operatorlar
$and — VA (ikkalasi ham)
// Toshkentda VA 20 yoshdan katta
db.talabalar.find({
$and: [
{ shahar: "Toshkent" },
{ yosh: { $gt: 20 } }
]
})
// Yuqoridagi bilan bir xil — qisqa yozuv
db.talabalar.find({ shahar: "Toshkent", yosh: { $gt: 20 } })
$and ni qachon ochiq yozish kerak? Bitta maydon uchun ikki shart:
// ❌ Bu ishlamaydi — ikkinchi $gt birinchini ustidan yozadi
db.mahsulotlar.find({ narx: { $gt: 5000 }, narx: { $lt: 50000 } })
// ✅ Bir xil maydonda ikki shart — $and yoki birlashtirilgan
db.mahsulotlar.find({ narx: { $gt: 5000, $lt: 50000 } })
// Yoki $and bilan
db.mahsulotlar.find({
$and: [
{ narx: { $gt: 5000 } },
{ narx: { $lt: 50000 } }
]
})
$or — YOKI (kamida biri)
// Toshkentda YOKI 18 yoshdan kichik
db.talabalar.find({
$or: [
{ shahar: "Toshkent" },
{ yosh: { $lt: 18 } }
]
})
SQL: WHERE shahar = 'Toshkent' OR yosh < 18
$and va $or birga
// (Toshkent YOKI Samarqand) VA (yosh 20 dan katta)
db.talabalar.find({
$and: [
{ $or: [{ shahar: "Toshkent" }, { shahar: "Samarqand" }] },
{ yosh: { $gt: 20 } }
]
})
Mantiqiy ko'rinish:
(shahar == "Toshkent" || shahar == "Samarqand")
&&
(yosh > 20)
$not — EMAS
// 18 yoshdan katta bo'lmaganlar (18 va undan kichik)
db.talabalar.find({ yosh: { $not: { $gt: 18 } } })
// { yosh <= 18 } bilan bir xil, lekin ba'zan $not aniqroq
// Regex emas
db.users.find({ ism: { $not: /^A/ } }) // ismi A bilan boshlanmaydigan
$nor — NA bu, NA u
// Toshkentda ham emas, 18 dan kichik ham emas
db.talabalar.find({
$nor: [
{ shahar: "Toshkent" },
{ yosh: { $lt: 18 } }
]
})
// → shahar != "Toshkent" AND yosh >= 18
$exists — maydon mavjudmi
Collection:
Doc A: { ism: "Jasur", telefon: "+998901234567" }
Doc B: { ism: "Malika", telefon: null }
Doc C: { ism: "Bobur" } ← telefon yo'q umuman
// telefon maydoni bor (null bo'lsa ham)
db.users.find({ telefon: { $exists: true } })
// → Doc A, Doc B
// telefon maydoni yo'q
db.users.find({ telefon: { $exists: false } })
// → Doc C
// telefon bor VA null emas
db.users.find({ telefon: { $exists: true, $ne: null } })
// → faqat Doc A
┌──────────┬──────────────────┬──────────────────┐
│ │ $exists: true │ $exists: false │
├──────────┼──────────────────┼──────────────────┤
│ Doc A │ ✓ topiladi │ ✗ topilmaydi │
│ (qiymat) │ │ │
│ Doc B │ ✓ topiladi │ ✗ topilmaydi │
│ (null) │ │ │
│ Doc C │ ✗ topilmaydi │ ✓ topiladi │
│ (yo'q) │ │ │
└──────────┴──────────────────┴──────────────────┘
SQL da bu tushuncha yo'q — SQL da ustun doim bor, faqat NULL yoki emas.
$type — tip tekshirish
// narx string bo'lib qolganlarni topish (noto'g'ri ma'lumot)
db.mahsulotlar.find({ narx: { $type: "string" } })
// narx raqam bo'lganlar
db.mahsulotlar.find({ narx: { $type: "number" } })
// "number" → int32, int64, double, decimal128 — hammasi
// Faqat double
db.mahsulotlar.find({ narx: { $type: "double" } })
// Array bo'lganlar
db.users.find({ telefon: { $type: "array" } })
Amalda $type ko'pincha ma'lumotlar sifatini tekshirish uchun ishlatiladi.
$regex — pattern bilan qidirish
// "jav" so'zi bor documentlar (katta-kichik harfdan qat'iy nazar)
db.postlar.find({ sarlavha: { $regex: "jav", $options: "i" } })
// Qisqaroq yozuv — regex literal
db.postlar.find({ sarlavha: /jav/i })
// Boshidan moslik — ^ anchoring
db.users.find({ ism: /^Jas/ }) // "Jas" bilan boshlanadi
db.users.find({ email: /\.uz$/ }) // ".uz" bilan tugaydi
// Aniq so'z — word boundary
db.postlar.find({ matn: /\bMongoDB\b/ })
Eng ko'p ishlatiladigan bayroq:
i → katta-kichik harfdan qat'iy nazar (case-insensitive)
SQL bilan:
-- SQL LIKE
SELECT * FROM users WHERE ism LIKE 'Jas%';
SELECT * FROM users WHERE email LIKE '%.uz';
-- SQL REGEXP
SELECT * FROM users WHERE ism REGEXP '^Jas';
// MongoDB
db.users.find({ ism: /^Jas/ })
db.users.find({ email: /\.uz$/ })
Regex — index ishlatmaydi (ehtiyot bo'ling)
// ✅ Boshidan moslik — index ishlatishi mumkin
db.users.find({ ism: /^Jasur/ })
// ❌ O'rtadan yoki oxiridan moslik — full scan
db.users.find({ ism: /asur/ }) // collection ni to'liq o'qiydi
db.users.find({ ism: /ur$/ }) // to'liq scan
Ko'p qidirish kerak bo'lsa — Atlas Search yoki text index (30-dars).
Array operatorlari
$all — massivda barcha qiymatlar bo'lsin
// Futbol ham, shaxmat ham hobbysi borlar
db.talabalar.find({ hobbylar: { $all: ["futbol", "shaxmat"] } })
// → faqat ikkalasi ham bo'lganlar
$size — massiv uzunligi
// Aniq 3 ta hobby borlar
db.talabalar.find({ hobbylar: { $size: 3 } })
// ← faqat aniq son qabul qiladi
$elemMatch — massiv elementi bir necha shartni qondirsin
db.talabalar.insertMany([
{ ism: "Jasur", baholar: [{ fan: "mat", ball: 90 }, { fan: "fiz", ball: 75 }] },
{ ism: "Malika", baholar: [{ fan: "mat", ball: 60 }, { fan: "fiz", ball: 95 }] },
])
// Matematikadan 80 dan yuqori baho olganlar
db.talabalar.find({
baholar: {
$elemMatch: { fan: "mat", ball: { $gt: 80 } }
}
})
// → faqat Jasur (mat:90)
// Malika topilmaydi — uning mat bali 60
// $elemMatch siz (noto'g'ri)
db.talabalar.find({ "baholar.fan": "mat", "baholar.ball": { $gt: 80 } })
// → Malika ham keladi! Chunki u yerda fan:"mat" bor va 95 ball bor
// (lekin ular turli elementlarda)
$elemMatch nima qiladi:
Bir element ichida ikki shartni bir vaqtda tekshiradi.
Jasur: [{ fan:"mat", ball:90 }, { fan:"fiz", ball:75 }]
↑ fan="mat" va ball>80 — bitta elementda ✓
Malika: [{ fan:"mat", ball:60 }, { fan:"fiz", ball:95 }]
↑ fan="mat" lekin ball=60 ↑ ball=95 lekin fan="fiz"
Bir elementda ikkalasi bir vaqtda yo'q ✗
Bir nechta operator birgalikda — misol
Aktiv mahsulotlar, narxi 50,000 dan 500,000 gacha, "elektronika" yoki "sport" kategoriyasida:
db.mahsulotlar.find({
faol: true,
narx: { $gte: 50000, $lte: 500000 },
kategoriya: { $in: ["elektronika", "sport"] }
})
SQL bilan:
SELECT * FROM mahsulotlar
WHERE faol = TRUE
AND narx BETWEEN 50000 AND 500000
AND kategoriya IN ('elektronika', 'sport');
Tez-tez uchraydigan xatolar
$in ga massiv emas qiymat berish
// ❌ Xato — $in massiv kutadi
db.users.find({ shahar: { $in: "Toshkent" } })
// MongoServerError: $in needs an array
// ✅ To'g'ri
db.users.find({ shahar: { $in: ["Toshkent"] } })
$and va $or birga yozish
// faol: true VA (Toshkentda YOKI yoshi 18 dan kichik)
db.users.find({
$and: [
{ faol: true },
{ $or: [{ shahar: "Toshkent" }, { yosh: { $lt: 18 } }] }
]
})
// $and ichida $or — aniq va tushunarli
Regex — string qo'shtirnoqda yoki literal
// ✅ Ikkalasi ham to'g'ri
db.users.find({ ism: /^Jas/i })
db.users.find({ ism: { $regex: "^Jas", $options: "i" } })
// ❌ Xato — $regex ga string berilganda flag alohida
db.users.find({ ism: { $regex: "/^Jas/i" } })
// "/^Jas/i" — bu string sifatida tushuniladi, regex emas
Xulosa
┌───────────────────────────────────────────────────────────┐
│ TAQQOSLASH $eq $ne $gt $gte $lt $lte │
│ RO'YXAT $in $nin │
│ MANTIQIY $and $or $not $nor │
│ ELEMENT $exists $type │
│ MATN $regex │
│ ARRAY $all $size $elemMatch │
└───────────────────────────────────────────────────────────┘
{ yosh: { $gt: 18, $lte: 25 } }— bitta maydon, ikki shart$in: [...]— doim massiv bering$exists: true/false— maydon borligini tekshiradi, null ni ham topadi$elemMatch— massiv elementida bir necha shartni birga tekshiradi$regexboshidan moslikda index ishlaydi, o'rtadan moslikda yo'q
Keyingi dars: 9-dars — updateOne, updateMany: $set, $unset, $inc, $push, $pull