3-bo‘lim

Hujjat va BSON turlari

BSON nima, ObjectId qanday tuzilgan, Date, Int32, Long va Decimal128 turlari, null va yo'q maydon farqi hamda $type bilan tekshirish.

🕑 13 daqiqa o‘qish 📄 992 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. BSON nima?
  2. ObjectId
  3. Sonlar - uchta alohida tur
  4. Sana
  5. null va yo'q maydon
  6. Massiv va ichma-ich hujjat
  7. Turlar ro'yxati
  8. Xulosa

Hujjat JSON ga o'xshaydi, lekin MongoDB uni JSON ko'rinishida saqlamaydi. U BSON - "Binary JSON" formatidan foydalanadi.

JavaScript
db.mahsulot.insertMany([
  {
    _id: 1,
    nom: "Noutbuk",
    narx: Decimal128("8500000.50"),
    ombor: Int32(12),
    korishlar: Long("4500000000"),
    qoshilgan: ISODate("2026-01-15T09:30:00Z"),
    faol: true,
    teglar: ["texnika", "ish"],
    xossa: { ram: 16, ekran: 15.6 }
  },
  {
    _id: 2,
    nom: "Sichqoncha",
    narx: Decimal128("250000.00"),
    ombor: Int32(140),
    qoshilgan: ISODate("2026-02-03T14:00:00Z"),
    faol: true,
    teglar: ["texnika"],
    izoh: null
  },
  {
    _id: 3,
    nom: "Stol",
    narx: Decimal128("1200000.00"),
    ombor: Int32(4),
    qoshilgan: ISODate("2026-03-11T08:15:00Z"),
    faol: false,
    teglar: []
  }
])

BSON nima? #

JSON - bu matn. Uni saqlash uchun har safar tahlil qilish kerak, va unda faqat bir nechta tur bor.

BSON - ikkilik format. U JSON ning barcha imkoniyatini saqlab, ustiga bir nechta muhim narsa qo'shadi:

JSONBSON
Ko'rinishiMatnIkkilik
Sana turiYo'q (matn sifatida)Date
Butun son turiBitta numberInt32, Long
Aniq kasrYo'qDecimal128
Ikkilik ma'lumotYo'q (base64 kerak)BinData
Maydonni o'tkazib yuborishTahlil qilish kerakUzunlik yozilgan

Oxirgi qator eng muhimi: BSON da har bir qiymatning uzunligi oldindan yozilgan bo'ladi. Shu tufayli baza kerak bo'lmagan maydonni o'qimasdan o'tib keta oladi.

Bitta hujjat, ikki xil saqlanish JSON - matn { "nom": "Stol", "ombor": 4 } Har o'qishda qayta tahlil qilinadi 4 - butun son yoki kasrmi? noma'lum Sana uchun tur yo'q BSON - ikkilik [uzunlik][tur=matn][nom][Stol] [uzunlik][tur=Int32][ombor][4] Tur aniq yozilgan Uzunlik bor - o'tib ketish mumkin Nima uchun bu muhim Hujjatda 50 ta maydon bo'lsa va sizga bittasi kerak bo'lsa baza qolgan 49 tasini o'qimasdan sakrab o'tadi
Hujjat ekranda JSON kabi ko'rinadi, lekin diskda ikkilik yozuv yotadi

ObjectId #

_id maydoni har bir hujjatda majburiy. Siz uni bermasangiz, MongoDB avtomatik ObjectId qo'yadi.

ObjectId - 12 baytli qiymat va u tasodifiy emas:

BaytlarNima
1-4Vaqt - hujjat yaratilgan soniya
5-9Jarayon va mashinaga xos tasodifiy qiymat
10-12Hisoblagich - bir soniyada ko'p yozuv uchun

Birinchi to'rt bayt vaqt bo'lgani uchun, ObjectId dan sanani ajratib olish mumkin:

JavaScript
const id = ObjectId("60a8f2b4c3d1e2f3a4b5c6d7")
id.getTimestamp()
Natija
ISODate('2021-05-22T12:01:56.000Z')
ObjectId tartibi vaqt tartibiga yaqin

_id bo'yicha saralash deyarli yaratilgan vaqt bo'yicha saralash bilan bir xil. Shuning uchun "oxirgi 10 ta yozuv" uchun alohida sana maydoni shart emas:

Natija
db.hodisa.find().sort({ _id: -1 }).limit(10)

Lekin ikkita ehtiyot shart bor:

  1. Bu taxminiy tartib. Bir soniya ichida yaratilgan hujjatlar orasidagi tartib kafolatlanmagan, ayniqsa ular turli serverlarda yaratilgan bo'lsa.
  2. Vaqt soniya aniqligida - millisekund yo'q.

Aniq vaqt kerak bo'lsa, alohida Date maydoni qo'ying.

Sonlar - uchta alohida tur #

Bu MongoDB ga yangi kelganlar uchun eng ko'p tuzoq tug'diradigan joy:

TurHajmiQachon
Int324 baytOmbor qoldig'i, yosh, son
Long (Int64)8 baytKo'rishlar soni, vaqt belgisi
Double8 baytO'lcham, og'irlik, foiz
Decimal12816 baytPul
JavaScript
db.mahsulot.findOne({ _id: 1 }, { nom: 1, narx: 1, ombor: 1, korishlar: 1 })
Natija
{
  _id: 1,
  nom: 'Noutbuk',
  narx: Decimal128('8500000.50'),
  ombor: 12,
  korishlar: Long('4500000000')
}

E'tibor bering: Decimal128 va Long o'z nomi bilan chiqdi, ombor esa oddiy 12 bo'lib ko'rindi - garchi u Int32 bo'lsa ham. mongosh Int32 va Double ni oddiy son kabi chop etadi.

Ya'ni ekranga qarab turni aniqlab bo'lmaydi. Buning uchun $type bor:

JavaScript
db.mahsulot.aggregate([
  { $match: { _id: 1 } },
  { $project: {
      narx_turi:      { $type: "$narx" },
      ombor_turi:     { $type: "$ombor" },
      korishlar_turi: { $type: "$korishlar" },
      sana_turi:      { $type: "$qoshilgan" },
      teglar_turi:    { $type: "$teglar" }
  } }
])
Natija
[
  {
    _id: 1,
    narx_turi: 'decimal',
    ombor_turi: 'int',
    korishlar_turi: 'long',
    sana_turi: 'date',
    teglar_turi: 'array'
  }
]
Pulni Double da saqlamang

JavaScript da yozilgan oddiy son - bu Double, ya'ni ikkilik kasr. U o'nlik kasrni aniq saqlay olmaydi:

Natija
0.1 + 0.2
0.30000000000000004

Pul bilan ishlaganda bu xato yig'ilib boradi va bir kun kelib hisobot bir necha so'mga farq qiladi.

Ikkita to'g'ri yechim bor:

YechimQanday
Decimal128Decimal128("8500000.50") - o'nlik kasr, aniq
Eng kichik birlikda butun sonNarxni tiyinda saqlash: 850000050

Ikkinchi usul tezroq va oddiyroq, lekin har o'qishda bo'lishni unutmaslik kerak. Birinchisi xavfsizroq.

Bu darslikda Decimal128 ishlatilgan.

Sana #

BSON da sana alohida tur - Date. Uni matn sifatida saqlamang:

JavaScript
db.mahsulot.find(
  { qoshilgan: { $gte: ISODate("2026-02-01T00:00:00Z") } },
  { nom: 1, qoshilgan: 1 }
)
Natija
[
  {
    _id: 2,
    nom: 'Sichqoncha',
    qoshilgan: ISODate('2026-02-03T14:00:00.000Z')
  },
  { _id: 3, nom: 'Stol', qoshilgan: ISODate('2026-03-11T08:15:00.000Z') }
]

Agar sana matn bo'lganida, $gte alifbo bo'yicha solishtirar edi va "2026-3-11" qiymati "2026-02-01" dan kichik chiqib qolardi.

null va yo'q maydon #

Bu ikkisi boshqa narsa, lekin oddiy filtrda bir xil ko'rinadi:

JavaScript
db.mahsulot.find({ izoh: null }, { nom: 1 })
Natija
[
  { _id: 1, nom: 'Noutbuk' },
  { _id: 2, nom: 'Sichqoncha' },
  { _id: 3, nom: 'Stol' }
]

Uchala hujjat ham chiqdi - lekin izoh maydoni faqat bittasida bor. Ikkinchi hujjatda izoh: null, qolgan ikkitasida esa bu maydon umuman yo'q.

Ularni ajratish uchun $exists kerak:

JavaScript
db.mahsulot.find({ izoh: { $exists: true } }, { nom: 1, izoh: 1 })
db.mahsulot.find({ izoh: { $exists: false } }, { nom: 1 })
Natija
[ { _id: 2, nom: 'Sichqoncha', izoh: null } ]
[ { _id: 1, nom: 'Noutbuk' }, { _id: 3, nom: 'Stol' } ]
{ maydon: null } - eng ko'p adashtiriladigan filtr

{ izoh: null } shartini MongoDB shunday tushunadi:

izoh qiymati null bo'lgan yoki izoh maydoni mavjud bo'lmagan hujjatlar

Bu ataylab shunday qilingan - hujjatli bazada "maydon yo'q" holati juda tez-tez uchraydi.

Aniq nima kerakligini shunday yozing:

MaqsadFiltr
Faqat haqiqiy null{ izoh: { $type: "null" } }
Faqat maydon yo'q{ izoh: { $exists: false } }
Ikkalasi ham{ izoh: null }
Qiymati bor (null emas){ izoh: { $ne: null } }

Sxemani loyihalashda esa eng yaxshisi - birini tanlash. Bo'sh qiymatni yo har doim null qilib yozing, yo har doim maydonni tashlab keting. Aralashtirish keyinchalik so'rovlarni chalkashtiradi.

Massiv va ichma-ich hujjat #

JavaScript
db.mahsulot.find(
  { teglar: { $size: 0 } },
  { nom: 1, teglar: 1 }
)
db.mahsulot.findOne({ "xossa.ram": 16 }, { nom: 1, xossa: 1 })
Natija
[ { _id: 3, nom: 'Stol', teglar: [] } ]
{ _id: 1, nom: 'Noutbuk', xossa: { ram: 16, ekran: 15.6 } }

"xossa.ram" - nuqtali yozuv. U ichma-ich hujjat ichiga kirish uchun ishlatiladi va u haqida 6-bobda batafsil gaplashamiz.

Turlar ro'yxati #

Turmongosh da yozilishi
Matn"salom"
Butun sonInt32(12) yoki oddiy 12
Katta butun sonLong("4500000000")
Kasr15.6
Aniq o'nlik kasrDecimal128("250000.00")
Mantiqiytrue, false
SanaISODate("2026-01-15T09:30:00Z")
KalitObjectId()
Massiv["a", "b"]
Hujjat{ ram: 16 }
Bo'shliknull
Amaliy topshiriq
  1. BSON va JSON orasidagi uchta farqni yozing.
  2. ObjectId ning birinchi to'rt bayti nimani saqlaydi?
  3. getTimestamp() bilan ObjectId dan sanani oling.
  4. _id bo'yicha saralash nega taxminiy ekanini yozing.
  5. Int32, Long va Decimal128 qachon ishlatilishini ayting.
  6. Pulni Double da saqlash nega xavfli - tushuntiring.
  7. $type bilan uchta maydon turini tekshiring.
  8. Sanani matn sifatida saqlash qanday xatoga olib keladi?
  9. { izoh: null } filtri nechta holatni qamrab olishini yozing.
  10. Faqat maydoni yo'q hujjatlarni topadigan filtr yozing.

Xulosa #

  • MongoDB hujjatni BSON - ikkilik formatda saqlaydi.
  • BSON da tur va uzunlik yozilgani uchun keraksiz maydonni o'qimasdan o'tish mumkin.
  • _id majburiy; berilmasa MongoDB ObjectId qo'yadi.
  • ObjectId ning birinchi to'rt bayti - yaratilgan vaqt.
  • Shuning uchun _id bo'yicha saralash vaqt tartibiga yaqin, lekin taxminiy.
  • Sonlar uchun uchta tur bor: Int32, Long, Double va alohida Decimal128.
  • Pulni Double da saqlamang - Decimal128 yoki eng kichik birlikda butun son ishlating.
  • Sana uchun ISODate bor; uni matn sifatida saqlash solishtirishni buzadi.
  • { maydon: null } ham nullni, ham maydon yo'qligini qamrab oladi.
  • Ularni ajratish uchun $exists va $type ishlatiladi.

Keyingi bo'limda hujjat qo'shishning barcha usullarini 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.