MongoDB mantiqiy operatorlar: $and, $or, $not

Solishtirish operatorlari darsida har filtr bitta mantiq bilan ishladi: barcha shartlar bajarilishi kerak edi. Lekin do’kon qidiruvida savol boshqacha qo’yiladi: “kitob yoki kanselyariya”, “arzon yoki reytingi yuqori”.

“Yoki” mantig’i yashirin ravishda ishlamaydi — uni aniq yozish kerak.

Misollar uchun baza:

use shop
db.products.drop()
db.products.insertMany([
  { name: "O'tkan kunlar", category: "kitob", price: 45000, quantity: 12, rating: 4.8 },
  { name: "Mehrobdan chayon", category: "kitob", price: 38000, quantity: 7, rating: 4.5 },
  { name: "Shum bola", category: "kitob", price: 29000, quantity: 0, rating: 4.9 },
  { name: "Daftar", category: "kanselyariya", price: 8000, quantity: 150, rating: 3.9 },
  { name: "Ruchka", category: "kanselyariya", price: 4000, quantity: 300, rating: 4.1 },
  { name: "Quloqchin", category: "texnika", price: 320000, quantity: 5, rating: 4.2 },
  { name: "Klaviatura", category: "texnika", price: 180000, quantity: 0, rating: 4.6 }
])
{
  acknowledged: true,
  insertedIds: {
    '0': ObjectId('671f7a1b2c3d4e5f6a7b8c21'),
    '1': ObjectId('671f7a1b2c3d4e5f6a7b8c22'),
    '2': ObjectId('671f7a1b2c3d4e5f6a7b8c23'),
    '3': ObjectId('671f7a1b2c3d4e5f6a7b8c24'),
    '4': ObjectId('671f7a1b2c3d4e5f6a7b8c25'),
    '5': ObjectId('671f7a1b2c3d4e5f6a7b8c26'),
    '6': ObjectId('671f7a1b2c3d4e5f6a7b8c27')
  }
}

Yashirin VA — takrorlash

Filtrdagi vergul allaqachon “va” ma’nosini beradi:

db.products.find(
  { category: "texnika", price: { $lt: 200000 } },
  { name: 1, price: 1, _id: 0 }
)
[ { name: 'Klaviatura', price: 180000 } ]

Ikki shart ham bajarildi. Ko’p holatda shu yetarli va $and yozilmaydi.

$or — shartlardan birortasi

$or massiv qabul qiladi; massivdagi har element mustaqil filtr:

db.products.find(
  {
    $or: [
      { price: { $lt: 10000 } },
      { rating: { $gte: 4.8 } }
    ]
  },
  { name: 1, price: 1, rating: 1, _id: 0 }
)
[
  { name: "O'tkan kunlar", price: 45000, rating: 4.8 },
  { name: 'Shum bola', price: 29000, rating: 4.9 },
  { name: 'Daftar', price: 8000, rating: 3.9 },
  { name: 'Ruchka', price: 4000, rating: 4.1 }
]

Natijaga ikki guruh tushdi: arzonlar va reytingi yuqorilar. Hujjat ikki shartga ham mos kelsa, bir marta qaytadi.

VA bilan YOKI ni birlashtirish

Amaliy savol odatda aralash bo’ladi: “texnika kategoriyasidan, lekin arzon yoki reytingi yuqori bo’lganlari”.

db.products.find(
  {
    category: "texnika",
    $or: [
      { price: { $lt: 200000 } },
      { rating: { $gte: 4.5 } }
    ]
  },
  { name: 1, price: 1, rating: 1, _id: 0 }
)
[ { name: 'Klaviatura', price: 180000, rating: 4.6 } ]

category sharti $or dan tashqarida qoldi — demak u majburiy, $or ichidagilar esa muqobil.

$and — qachon haqiqatan kerak

Vergul VA ni bergani uchun $and kamdan-kam yoziladi. Lekin ikki holatda usiz iloji yo’q.

Birinchi holat: ikkita $or bir so’rovda. Obyektda bitta kalit ikki marta yozilmagani uchun ularni $and massiviga joylash kerak:

db.products.find(
  {
    $and: [
      { $or: [{ category: "kitob" }, { category: "texnika" }] },
      { $or: [{ price: { $lt: 40000 } }, { rating: { $gte: 4.6 } }] }
    ]
  },
  { name: 1, category: 1, price: 1, rating: 1, _id: 0 }
)
[
  { name: 'Mehrobdan chayon', category: 'kitob', price: 38000, rating: 4.5 },
  { name: 'Shum bola', category: 'kitob', price: 29000, rating: 4.9 },
  { name: "O'tkan kunlar", category: 'kitob', price: 45000, rating: 4.8 },
  { name: 'Klaviatura', category: 'texnika', price: 180000, rating: 4.6 }
]

Ikkinchi holat: bir maydonga ikki alohida shart. Oldingi darsda ko’rgan tuzoqni eslang — { price: {...}, price: {...} } ishlamaydi. Odatda ikki operatorni bitta obyektga qo’yish yetarli, lekin murakkabroq holatda $and yechim beradi:

db.products.find(
  {
    $and: [
      { price: { $gte: 10000 } },
      { price: { $lte: 100000 } }
    ]
  },
  { name: 1, price: 1, _id: 0 }
)
[
  { name: "O'tkan kunlar", price: 45000 },
  { name: 'Mehrobdan chayon', price: 38000 },
  { name: 'Shum bola', price: 29000 }
]

$not — shartni teskari qilish

$not bitta maydon ichida ishlaydi va undagi operatorni inkor qiladi:

db.products.find(
  { price: { $not: { $lt: 40000 } } },
  { name: 1, price: 1, _id: 0 }
)
[
  { name: "O'tkan kunlar", price: 45000 },
  { name: 'Quloqchin', price: 320000 },
  { name: 'Klaviatura', price: 180000 }
]

$nor — hech biri bajarilmasin

$nor massiv oladi va hech bir shart bajarilmagan hujjatlarni qaytaradi:

db.products.find(
  {
    $nor: [
      { category: "kitob" },
      { price: { $gt: 100000 } }
    ]
  },
  { name: 1, category: 1, price: 1, _id: 0 }
)
[
  { name: 'Daftar', category: 'kanselyariya', price: 8000 },
  { name: 'Ruchka', category: 'kanselyariya', price: 4000 },
  { name: 'Papka', category: 'kanselyariya', price: 12000 }
]

Kitob ham emas, qimmat ham emas.

Operator Qachon rost
$and Hamma shart bajarilsa
$or Kamida bittasi bajarilsa
$nor Hech biri bajarilmasa
$not Ichidagi operator bajarilmasa

Murakkab filtrni qanday yozish

Uzun filtr bir urinishda to’g’ri chiqmaydi. Ishlaydigan tartib:

  1. Savolni o’zbekcha yozing: “kitob yoki texnika, narxi 200 mingdan arzon, omborda bor”;
  2. “Va” bilan bog’langan qismlarni ajrating — ular tashqi darajaga chiqadi;
  3. “Yoki” qismini $or massiviga soling;
  4. Filtrni bo’lak-bo’lak sinab ko’ring: avval bitta shart, keyin qo’shing;
  5. Har qadamda countDocuments() bilan sonni kuzating.

Yuqoridagi savol natijasi:

db.products.find(
  {
    $or: [{ category: "kitob" }, { category: "texnika" }],
    price: { $lt: 200000 },
    quantity: { $gt: 0 }
  },
  { name: 1, category: 1, price: 1, quantity: 1, _id: 0 }
)
[
  { name: "O'tkan kunlar", category: 'kitob', price: 45000, quantity: 12 },
  { name: 'Mehrobdan chayon', category: 'kitob', price: 38000, quantity: 7 }
]

Shum bola va Klaviatura chiqmadi — ikkalasida ham quantity: 0.

Amaliy mashq

Yuqoridagi shop bazasida bajaring:

  1. $or bilan category si "kitob" yoki "texnika" bo’lgan mahsulotlarni toping va natijani $in bilan yozilganiga solishtiring.
  2. Majburiy quantity: { $gt: 0 } shartini $or tashqarisiga qo’shib, natijaning qisqarishini kuzating.
  3. Shu shartni $or massivi ichiga ko’chiring va nechta hujjat qaytganini sanang.
  4. Ikkita $or ni $and massiviga joylab, “kitob yoki kanselyariya” hamda “arzon yoki reytingi yuqori” shartini birga yozing.
  5. $not bilan reytingi 4.5 dan past mahsulotlarni toping, so’ng $exists: true qo’shib farqni ko’ring.
  6. $nor bilan “kitob ham emas, 100 mingdan qimmat ham emas” mahsulotlarini chiqaring.

2 va 3-qadamlar juftligi eng muhimi: shart $or ichida yoki tashqarida turishi natijani butunlay o’zgartiradi.

Qisqacha xulosa

  • Filtrdagi vergul allaqachon VA ma’nosini beradi.
  • $or massiv oladi va shartlardan kamida bittasi bajarilsa hujjatni qaytaradi.
  • Majburiy shart $or dan tashqarida yoziladi — ichiga tushsa, muqobilga aylanadi.
  • $and ikki holatda kerak: ikkita $or bir so’rovda va bir maydonga ikki alohida shart.
  • $not bitta maydon ichidagi operatorni inkor qiladi.
  • $not va $ne maydoni yo’q hujjatlarni ham qaytaradi; aniqlik uchun $exists qo’shiladi.
  • $nor — massivdagi hech bir shart bajarilmagan hujjatlar.

Keyingi darsda hujjat yangilashupdateOne, $set va $inc bilan ma’lumotni o’zgartirish.

Bu dars foydali bo'ldimi?

marta ko'rildi