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.
Ushbu bo‘lim mundarijasi
Hujjat JSON ga o'xshaydi, lekin MongoDB uni JSON ko'rinishida saqlamaydi. U BSON - "Binary JSON" formatidan foydalanadi.
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:
| JSON | BSON | |
|---|---|---|
| Ko'rinishi | Matn | Ikkilik |
| Sana turi | Yo'q (matn sifatida) | Date |
| Butun son turi | Bitta number | Int32, Long |
| Aniq kasr | Yo'q | Decimal128 |
| Ikkilik ma'lumot | Yo'q (base64 kerak) | BinData |
| Maydonni o'tkazib yuborish | Tahlil qilish kerak | Uzunlik 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.
ObjectId #
_id maydoni har bir hujjatda majburiy. Siz uni
bermasangiz, MongoDB avtomatik ObjectId qo'yadi.
ObjectId - 12 baytli qiymat va u tasodifiy emas:
| Baytlar | Nima |
|---|---|
| 1-4 | Vaqt - hujjat yaratilgan soniya |
| 5-9 | Jarayon va mashinaga xos tasodifiy qiymat |
| 10-12 | Hisoblagich - bir soniyada ko'p yozuv uchun |
Birinchi to'rt bayt vaqt bo'lgani uchun, ObjectId dan
sanani ajratib olish mumkin:
const id = ObjectId("60a8f2b4c3d1e2f3a4b5c6d7")
id.getTimestamp()
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:
db.hodisa.find().sort({ _id: -1 }).limit(10)
Lekin ikkita ehtiyot shart bor:
- Bu taxminiy tartib. Bir soniya ichida yaratilgan hujjatlar orasidagi tartib kafolatlanmagan, ayniqsa ular turli serverlarda yaratilgan bo'lsa.
- 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:
| Tur | Hajmi | Qachon |
|---|---|---|
Int32 | 4 bayt | Ombor qoldig'i, yosh, son |
Long (Int64) | 8 bayt | Ko'rishlar soni, vaqt belgisi |
Double | 8 bayt | O'lcham, og'irlik, foiz |
Decimal128 | 16 bayt | Pul |
db.mahsulot.findOne({ _id: 1 }, { nom: 1, narx: 1, ombor: 1, korishlar: 1 })
{
_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:
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" }
} }
])
[
{
_id: 1,
narx_turi: 'decimal',
ombor_turi: 'int',
korishlar_turi: 'long',
sana_turi: 'date',
teglar_turi: 'array'
}
]
Double da saqlamangJavaScript da yozilgan oddiy son - bu Double, ya'ni
ikkilik kasr. U o'nlik kasrni aniq saqlay olmaydi:
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:
| Yechim | Qanday |
|---|---|
Decimal128 | Decimal128("8500000.50") - o'nlik kasr, aniq |
| Eng kichik birlikda butun son | Narxni 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:
db.mahsulot.find(
{ qoshilgan: { $gte: ISODate("2026-02-01T00:00:00Z") } },
{ nom: 1, qoshilgan: 1 }
)
[
{
_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:
db.mahsulot.find({ izoh: null }, { nom: 1 })
[
{ _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:
db.mahsulot.find({ izoh: { $exists: true } }, { nom: 1, izoh: 1 })
db.mahsulot.find({ izoh: { $exists: false } }, { nom: 1 })
[ { _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:
izohqiymatinullbo'lgan yokiizohmaydoni mavjud bo'lmagan hujjatlar
Bu ataylab shunday qilingan - hujjatli bazada "maydon yo'q" holati juda tez-tez uchraydi.
Aniq nima kerakligini shunday yozing:
| Maqsad | Filtr |
|---|---|
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 #
db.mahsulot.find(
{ teglar: { $size: 0 } },
{ nom: 1, teglar: 1 }
)
db.mahsulot.findOne({ "xossa.ram": 16 }, { nom: 1, xossa: 1 })
[ { _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 #
| Tur | mongosh da yozilishi |
|---|---|
| Matn | "salom" |
| Butun son | Int32(12) yoki oddiy 12 |
| Katta butun son | Long("4500000000") |
| Kasr | 15.6 |
| Aniq o'nlik kasr | Decimal128("250000.00") |
| Mantiqiy | true, false |
| Sana | ISODate("2026-01-15T09:30:00Z") |
| Kalit | ObjectId() |
| Massiv | ["a", "b"] |
| Hujjat | { ram: 16 } |
| Bo'shlik | null |
- BSON va JSON orasidagi uchta farqni yozing.
ObjectIdning birinchi to'rt bayti nimani saqlaydi?getTimestamp()bilanObjectIddan sanani oling._idbo'yicha saralash nega taxminiy ekanini yozing.Int32,LongvaDecimal128qachon ishlatilishini ayting.- Pulni
Doubleda saqlash nega xavfli - tushuntiring. $typebilan uchta maydon turini tekshiring.- Sanani matn sifatida saqlash qanday xatoga olib keladi?
{ izoh: null }filtri nechta holatni qamrab olishini yozing.- 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.
_idmajburiy; berilmasa MongoDBObjectIdqo'yadi.ObjectIdning birinchi to'rt bayti - yaratilgan vaqt.- Shuning uchun
_idbo'yicha saralash vaqt tartibiga yaqin, lekin taxminiy. - Sonlar uchun uchta tur bor:
Int32,Long,Doubleva alohidaDecimal128. - Pulni
Doubleda saqlamang -Decimal128yoki eng kichik birlikda butun son ishlating. - Sana uchun
ISODatebor; uni matn sifatida saqlash solishtirishni buzadi. { maydon: null }hamnullni, ham maydon yo'qligini qamrab oladi.- Ularni ajratish uchun
$existsva$typeishlatiladi.
Keyingi bo'limda hujjat qo'shishning barcha usullarini ko'ramiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
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.