6-bo‘lim

Massiv va ichma-ich hujjatlar

Nuqtali yozuv, massiv ichidan qidirish, $all va $size, $elemMatch nima uchun kerak hamda massiv elementini proyeksiya qilish.

🕑 15 daqiqa o‘qish 📄 724 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Nuqtali yozuv
  2. Massiv ichidan qidirish
  3. $all, $size va $in
  4. $elemMatch - eng muhim operator
  5. Massivning bir qismini qaytarish
  6. Ichma-ich massiv bo'yicha saralash
  7. Xulosa

Hujjatli bazaning asosiy kuchi shu yerda: bitta hujjat ichida massiv va boshqa hujjatlar bo'lishi mumkin. Lekin ular bo'yicha qidirishning o'z qoidalari bor.

JavaScript
db.kitob.insertMany([
  {
    _id: 1, nom: "Otkan kunlar",
    muallif: { ism: "Abdulla Qodiriy", tugilgan: 1894, shahar: "Toshkent" },
    teglar: ["roman", "tarixiy", "klassika"],
    baho: [
      { kim: "Malika", ball: 5, yil: 2025 },
      { kim: "Nodira", ball: 4, yil: 2026 }
    ]
  },
  {
    _id: 2, nom: "Kecha va kunduz",
    muallif: { ism: "Cho'lpon", tugilgan: 1897, shahar: "Andijon" },
    teglar: ["roman", "ijtimoiy"],
    baho: [
      { kim: "Aziza", ball: 5, yil: 2026 },
      { kim: "Malika", ball: 3, yil: 2024 }
    ]
  },
  {
    _id: 3, nom: "Ufq",
    muallif: { ism: "Said Ahmad", tugilgan: 1920, shahar: "Toshkent" },
    teglar: ["roman", "zamonaviy"],
    baho: [
      { kim: "Kamola", ball: 4, yil: 2025 }
    ]
  },
  {
    _id: 4, nom: "Sarob",
    muallif: { ism: "Abdulla Qahhor", tugilgan: 1907, shahar: "Qoqon" },
    teglar: [],
    baho: []
  }
])

Nuqtali yozuv #

Ichma-ich hujjat ichiga kirish uchun nuqta ishlatiladi. Yo'l qo'shtirnoq ichida yoziladi:

JavaScript
db.kitob.find({ "muallif.shahar": "Toshkent" }, { nom: 1, "muallif.ism": 1 })
Natija
[
  { _id: 1, nom: 'Otkan kunlar', muallif: { ism: 'Abdulla Qodiriy' } },
  { _id: 3, nom: 'Ufq', muallif: { ism: 'Said Ahmad' } }
]

Nuqtali yozuv proyeksiyada ham ishlaydi - yuqorida faqat muallif.ism qaytdi, tugilgan va shahar esa qaytmadi.

Butun ichma-ich hujjatni solishtirish - qat'iy tenglik

Nuqtasiz yozuv butunlay boshqacha ishlaydi:

YozuvMa'nosi
{ "muallif.shahar": "Toshkent" }Ichidagi bitta maydon mos kelsa
{ muallif: { shahar: "Toshkent" } }Hujjat aynan shunday bo'lsa

Ikkinchisi deyarli hech qachon mos kelmaydi, chunki u:

  • hamma maydon bir xil bo'lishini,
  • tartibi ham bir xil bo'lishini

talab qiladi. { ism: "...", tugilgan: 1894, shahar: "..." } hujjati { shahar: "Toshkent" } bilan mos kelmaydi.

Amaliy qoida: ichma-ich hujjat bilan ishlaganda deyarli har doim nuqtali yozuv kerak.

JavaScript
db.kitob.countDocuments({ muallif: { shahar: "Toshkent" } })
db.kitob.countDocuments({ "muallif.shahar": "Toshkent" })
Natija
0
2

Massiv ichidan qidirish #

Massivga oddiy tenglik yozilsa, MongoDB uni "elementlardan biri" deb tushunadi:

JavaScript
db.kitob.find({ teglar: "tarixiy" }, { nom: 1, teglar: 1 })
Natija
[
  {
    _id: 1,
    nom: 'Otkan kunlar',
    teglar: [ 'roman', 'tarixiy', 'klassika' ]
  }
]

Bu juda qulay: massiv ham, oddiy qiymat ham bir xil yoziladi.

Massivga qo'yilgan shart har elementga alohida qo'llanadi Hujjat teglar: [ "roman", "tarixiy", "klassika" ] uchta element { teglar: "tarixiy" } "roman" mosmi? yo'q "tarixiy" mosmi? HA - hujjat topildi "klassika" - tekshirilmaydi ham Ikkita shart yozilsa - har biri BOSHQA elementga tushishi mumkin { "baho.ball": 5, "baho.yil": 2026 } ball=5 birinchi bahoda, yil=2026 ikkinchi bahoda bo'lsa ham hujjat topiladi Bitta elementga bog'lash uchun $elemMatch kerak
Bu MongoDB da massiv bilan ishlashdagi eng muhim qoida

$all, $size va $in #

OperatorMa'nosi
$allSanalganlarning hammasi bo'lsin
$inSanalganlardan biri bo'lsa yetarli
$sizeElementlar soni aynan shuncha
$existsMassiv maydoni mavjudmi
JavaScript
db.kitob.find({ teglar: { $all: ["roman", "tarixiy"] } }, { nom: 1 })
db.kitob.find({ teglar: { $in: ["ijtimoiy", "zamonaviy"] } }, { nom: 1 })
db.kitob.find({ teglar: { $size: 0 } }, { nom: 1 })
Natija
[ { _id: 1, nom: 'Otkan kunlar' } ]
[ { _id: 2, nom: 'Kecha va kunduz' }, { _id: 3, nom: 'Ufq' } ]
[ { _id: 4, nom: 'Sarob' } ]
$size oraliq qabul qilmaydi

{ teglar: { $size: { $gt: 2 } } } yozuvi ishlamaydi - $size faqat aniq son oladi.

"Ikkitadan ko'p tegi bor kitoblar" ni topish uchun ikkita yo'l bor:

Yo'lYozuv
Indeks orqali tekshirish{ "teglar.2": { $exists: true } }
Agregatsiya$expr bilan $size ni hisoblash

Birinchisi ayyorona, lekin tez: massiv indeksi noldan boshlanadi, shuning uchun teglar.2 mavjud bo'lsa - demak kamida uchta element bor.

Ikkinchisi tushunarliroq, lekin har hujjatni hisoblashni talab qiladi:

Natija
{ $expr: { $gt: [ { $size: "$teglar" }, 2 ] } }
JavaScript
db.kitob.find({ "teglar.2": { $exists: true } }, { nom: 1, teglar: 1 })
Natija
[
  {
    _id: 1,
    nom: 'Otkan kunlar',
    teglar: [ 'roman', 'tarixiy', 'klassika' ]
  }
]

$elemMatch - eng muhim operator #

Massiv ichidagi hujjatlar bilan ishlaganda bu operator zarur bo'ladi. Avval usiz sinab ko'ramiz:

JavaScript
db.kitob.find(
  { "baho.ball": 5, "baho.yil": 2026 },
  { nom: 1, baho: 1 }
)
Natija
[
  {
    _id: 1,
    nom: 'Otkan kunlar',
    baho: [
      { kim: 'Malika', ball: 5, yil: 2025 },
      { kim: 'Nodira', ball: 4, yil: 2026 }
    ]
  },
  {
    _id: 2,
    nom: 'Kecha va kunduz',
    baho: [
      { kim: 'Aziza', ball: 5, yil: 2026 },
      { kim: 'Malika', ball: 3, yil: 2024 }
    ]
  }
]

Natijada ikkita kitob chiqdi. Lekin Otkan kunlar ni diqqat bilan qarang: unda ball: 5 2025-yilda, yil: 2026 esa 4 ball bilan. Ya'ni ikkala shart bitta bahoda emas, ikki xil bahoda bajarilgan.

Endi $elemMatch bilan:

JavaScript
db.kitob.find(
  { baho: { $elemMatch: { ball: 5, yil: 2026 } } },
  { nom: 1, baho: 1 }
)
Natija
[
  {
    _id: 2,
    nom: 'Kecha va kunduz',
    baho: [
      { kim: 'Aziza', ball: 5, yil: 2026 },
      { kim: 'Malika', ball: 3, yil: 2024 }
    ]
  }
]

Endi faqat Kecha va kunduz qoldi - unda haqiqatan bitta bahoda ikkala shart ham bajarilgan.

Massiv ichidagi hujjatlarda $elemMatch ni unutmang

Bu xato hisobotlarda juda ko'p uchraydi va uni sezish qiyin, chunki so'rov ishlaydi - shunchaki noto'g'ri javob beradi.

Qachon kerak:

HolatKerakmi
Massivda oddiy qiymatlar, bitta shartYo'q
Massivda hujjatlar, bitta shartYo'q
Massivda hujjatlar, ikki yoki undan ko'p shartHa

Oddiy qiymatlar massivi uchun ham bitta holat bor:

Natija
{ ball: { $gte: 4, $lte: 5 } }

Bu ham ikkita shartni har xil elementga tarqatishi mumkin. Bitta elementga bog'lash kerak bo'lsa:

Natija
{ ball: { $elemMatch: { $gte: 4, $lte: 5 } } }

Massivning bir qismini qaytarish #

Proyeksiyada $elemMatch va $slice ishlatiladi:

JavaScript
db.kitob.find(
  { _id: { $in: [1, 2] } },
  { nom: 1, baho: { $elemMatch: { ball: 5 } } }
)
Natija
[
  {
    _id: 1,
    nom: 'Otkan kunlar',
    baho: [ { kim: 'Malika', ball: 5, yil: 2025 } ]
  },
  {
    _id: 2,
    nom: 'Kecha va kunduz',
    baho: [ { kim: 'Aziza', ball: 5, yil: 2026 } ]
  }
]

Har hujjatdan faqat birinchi mos keladigan baho qaytdi.

JavaScript
db.kitob.find({ _id: 1 }, { nom: 1, teglar: { $slice: 2 } })
db.kitob.find({ _id: 1 }, { nom: 1, teglar: { $slice: -1 } })
Natija
[ { _id: 1, nom: 'Otkan kunlar', teglar: [ 'roman', 'tarixiy' ] } ]
[ { _id: 1, nom: 'Otkan kunlar', teglar: [ 'klassika' ] } ]
YozuvMa'nosi
$slice: 2Boshidan 2 ta
$slice: -1Oxiridan 1 ta
$slice: [1, 2]1-o'rindan boshlab 2 ta

Ichma-ich massiv bo'yicha saralash #

JavaScript
db.kitob.find(
  { "baho.ball": { $gte: 4 } },
  { nom: 1, _id: 0 }
).sort({ "muallif.tugilgan": 1 })
Natija
[ { nom: 'Otkan kunlar' }, { nom: 'Kecha va kunduz' }, { nom: 'Ufq' } ]

Nuqtali yozuv sort da ham xuddi shunday ishlaydi.

Amaliy topshiriq
  1. Nuqtali yozuv bilan ichma-ich maydon bo'yicha qidiring.
  2. Nuqtasiz butun hujjatni solishtiring va farqni ko'ring.
  3. Massivga oddiy tenglik qo'yib, nima bo'lishini yozing.
  4. $all va $in farqini misolda ko'rsating.
  5. $size bilan bo'sh massivli hujjatni toping.
  6. "Ikkitadan ko'p element" shartini ikki xil usulda yozing.
  7. Massiv ichidagi hujjatga ikkita shart qo'ying - $elemMatch siz.
  8. Natija nega noto'g'ri ekanini tushuntiring.
  9. Xuddi shuni $elemMatch bilan to'g'rilang.
  10. $slice bilan massivning oxirgi elementini oling.

Xulosa #

  • Ichma-ich hujjatga nuqtali yozuv bilan murojaat qilinadi: "muallif.shahar".
  • Nuqtasiz yozuv butun hujjatni aynan solishtiradi - maydon tartibi bilan birga.
  • Massivga qo'yilgan oddiy shart "elementlardan biri mos kelsa" degani.
  • $all hammasini, $in bittasini, $size esa aniq sonni talab qiladi.
  • $size oraliq qabul qilmaydi - "teglar.2": { $exists: true } yoki $expr ishlating.
  • Massiv ichidagi hujjatlarga ikkita shart qo'yilsa, ular har xil elementga tushishi mumkin.
  • Bitta elementga bog'lash uchun $elemMatch kerak.
  • Bu xato so'rovni buzmaydi - shunchaki noto'g'ri javob beradi.
  • Proyeksiyada $elemMatch birinchi mos elementni, $slice esa bir qismini qaytaradi.
  • Nuqtali yozuv find, sort va proyeksiyada bir xil ishlaydi.

Keyingi bo'limda hujjatlarni yangilashni va massiv operatorlarini ko'ramiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.