4-bo‘lim

Hujjat qo'shish

insertOne va insertMany, _id ni o'zi berish yoki avtomatik qoldirish, takroriy kalit xatosi, ordered va yozuv kafolati.

🕑 12 daqiqa o‘qish 📄 755 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. insertOne
  2. insertMany
  3. _id ni o'zingiz bering yoki qoldiring
  4. Takroriy kalit
  5. ordered - xato bo'lganda to'xtaymizmi
  6. Yozuv kafolati
  7. Boshqa qo'shish usullari
  8. Xulosa

Hujjat qo'shish MongoDB dagi eng oddiy amal. Lekin uning ichida bir nechta muhim tafsilot bor: kalit qayerdan keladi, xato bo'lsa nima bo'ladi va yozuv qachon "saqlandi" hisoblanadi.

JavaScript
db.kitob.insertMany([
  { _id: 1, nom: "Otkan kunlar", muallif: "Abdulla Qodiriy", narx: 85000 },
  { _id: 2, nom: "Navoiy",       muallif: "Oybek",           narx: 95000 },
  { _id: 3, nom: "Ufq",          muallif: "Said Ahmad",      narx: 64000 }
])

insertOne #

JavaScript
db.kitob.insertOne({
  _id: 4,
  nom: "Kecha va kunduz",
  muallif: "Cho'lpon",
  narx: 68000
})
Natija
{ acknowledged: true, insertedId: 4 }

Javobda ikkita maydon bor:

MaydonMa'nosi
acknowledgedServer yozuvni tasdiqladimi
insertedIdQo'shilgan hujjatning kaliti

insertMany #

JavaScript
db.kitob.insertMany([
  { _id: 5, nom: "Sarob",   muallif: "Abdulla Qahhor", narx: 59000 },
  { _id: 6, nom: "Shum bola", muallif: "G'afur G'ulom",  narx: 47000 }
])
db.kitob.countDocuments()
Natija
{ acknowledged: true, insertedIds: { '0': 5, '1': 6 } }
5

_id ni o'zingiz bering yoki qoldiring #

_id majburiy, lekin uni yozish shart emas:

JavaScript
const javob = db.kitob.insertOne({ nom: "Yulduzli tunlar", narx: 78000 })
javob.acknowledged
javob.insertedId instanceof ObjectId
db.kitob.findOne({ nom: "Yulduzli tunlar" }).narx
Natija
true
true
78000

Biz _id bermadik, MongoDB esa ObjectId qo'ydi.

_id har doim bor - savol faqat uni kim qo'yishida insertOne chaqirildi Hujjatda _id bor O'sha qiymat ishlatiladi Hujjatda _id yo'q Mijoz ObjectId yaratadi _id bo'yicha indeks har doim mavjud U yagona (unique) va uni o'chirib bo'lmaydi Shuning uchun takroriy _id yozilganda xato qaytadi
ObjectId ni server emas, mijoz kutubxonasi yaratadi - shuning uchun u tarmoqqa bormasdan ham ma'lum
O'z _id ingizni qo'yish ko'pincha yaxshiroq

Agar ma'lumotning tabiiy kaliti bo'lsa - ISBN, pasport raqami, tartib raqami - uni to'g'ridan-to'g'ri _id ga qo'ying.

YondashuvYutuq
_id: "978-9943-01-234-5"Qidirish uchun qo'shimcha indeks kerak emas
_id: ObjectId(...) + isbn maydoniIkkita indeks, ikki baravar joy

_id bo'yicha indeks baribir mavjud va u yagona. Tabiiy kalitni shu yerga qo'ysangiz, takrorlanishdan himoya ham bepul keladi.

Faqat bitta shart: _id ni keyinchalik o'zgartirib bo'lmaydi. Shuning uchun u haqiqatan o'zgarmas bo'lishiga ishonch hosil qiling. Masalan elektron pochta manzili yomon tanlov - odam uni almashtirishi mumkin.

Takroriy kalit #

JavaScript
db.kitob.insertOne({ _id: 1, nom: "Boshqa kitob" })
Natija
MongoServerError: E11000 duplicate key error collection: dokon.kitob index: _id_ dup key: { _id: 1 }

E11000 - MongoDB dagi eng ko'p uchraydigan xato kodi. U "bu kalit allaqachon band" degani.

ordered - xato bo'lganda to'xtaymizmi #

insertMany odatda tartibli ishlaydi: birinchi xatoda to'xtaydi va qolganini qo'shmaydi.

JavaScript
db.kitob.insertMany([
  { _id: 10, nom: "Birinchi" },
  { _id: 1,  nom: "Takror - bu xato" },
  { _id: 11, nom: "Uchinchi" }
])
db.kitob.find({ _id: { $in: [10, 11] } }, { nom: 1 })
Natija
Uncaught:
MongoBulkWriteError: E11000 duplicate key error collection: dokon.kitob index: _id_ dup key: { _id: 1 }
Result: BulkWriteResult {
  insertedCount: 1,
  matchedCount: 0,
  modifiedCount: 0,
  deletedCount: 0,
  upsertedCount: 0,
  upsertedIds: {},
  insertedIds: { '0': 10 }
}
Write Errors: [
  WriteError {
    err: {
      index: 1,
      code: 11000,
      errmsg: 'E11000 duplicate key error collection: dokon.kitob index: _id_ dup key: { _id: 1 }',
      errInfo: undefined,
      op: { _id: 1, nom: 'Takror - bu xato' }
    }
  }
]
[ { _id: 10, nom: 'Birinchi' } ]

_id: 10 qo'shildi, lekin _id: 11 qo'shilmadi - xatodan keyin ish to'xtadi.

Endi ordered: false bilan:

JavaScript
db.kitob.insertMany([
  { _id: 10, nom: "Birinchi" },
  { _id: 1,  nom: "Takror - bu xato" },
  { _id: 11, nom: "Uchinchi" }
], { ordered: false })
db.kitob.find({ _id: { $in: [10, 11] } }, { nom: 1 })
Natija
Uncaught:
MongoBulkWriteError: E11000 duplicate key error collection: dokon.kitob index: _id_ dup key: { _id: 1 }
Result: BulkWriteResult {
  insertedCount: 2,
  matchedCount: 0,
  modifiedCount: 0,
  deletedCount: 0,
  upsertedCount: 0,
  upsertedIds: {},
  insertedIds: { '0': 10, '2': 11 }
}
Write Errors: [
  WriteError {
    err: {
      index: 1,
      code: 11000,
      errmsg: 'E11000 duplicate key error collection: dokon.kitob index: _id_ dup key: { _id: 1 }',
      errInfo: undefined,
      op: { _id: 1, nom: 'Takror - bu xato' }
    }
  }
]
[ { _id: 10, nom: 'Birinchi' }, { _id: 11, nom: 'Uchinchi' } ]

Xato baribir chiqdi, lekin bu safar ikkala yaxshi hujjat ham qo'shildi.

insertMany - bu tranzaksiya emas

Eng xavfli noto'g'ri tasavvur: "insertMany yo hammasini qo'shadi, yo hech birini".

Bu noto'g'ri. Yuqoridagi natijaning o'zi buni ko'rsatdi: birinchi holatda bitta hujjat qo'shilib qoldi.

RejimXatodan keyinUndan oldingilar
ordered: true (odatiy)To'xtaydiQo'shilgan holicha qoladi
ordered: falseDavom etadiQo'shiladi

Haqiqiy "yo hammasi, yo hech nima" kerak bo'lsa, tranzaksiya ishlatiladi - 17-bobda ko'ramiz.

ordered: false qachon foydali: ma'lumotni ko'chirib o'tkazayotganda va bir nechta yozuv takror bo'lishi mumkinligini bilganda. Shunda ish to'xtamaydi.

Yozuv kafolati #

acknowledged: true "diskka yozildi" degani emas. U "server buyruqni qabul qildi" degani.

Aniq kafolatni writeConcern belgilaydi:

YozuvMa'nosi
w: 1Asosiy server qabul qildi (odatiy)
w: "majority"Nusxalarning ko'pchiligi qabul qildi
j: trueJurnalga (diskka) yozildi
w: 0Javob kutilmaydi - eng tez, eng ishonchsiz
JavaScript
db.kitob.insertOne(
  { _id: 20, nom: "Muhim yozuv", narx: 100000 },
  { writeConcern: { w: "majority", j: true } }
)
Natija
{ acknowledged: true, insertedId: 20 }
w: 0 - javobsiz yozuv

w: 0 bilan mijoz serverning javobini umuman kutmaydi. Buyruq yuboriladi va dastur darhol keyingi qatorga o'tadi.

Bu tez, lekin quyidagilarni bilmay qolasiz:

  • yozuv haqiqatan bordimi;
  • takroriy kalit xatosi bo'ldimi;
  • server umuman ishlayaptimi.

Bu rejim faqat yo'qolishi mumkin bo'lgan ma'lumot uchun o'rinli: sahifa ko'rishlari hisoblagichi, ixtiyoriy telemetriya.

Buyurtma, to'lov yoki foydalanuvchi ro'yxati uchun esa kamida w: "majority" kerak. Aks holda asosiy server almashganda yozuv yo'qolishi mumkin.

Boshqa qo'shish usullari #

UsulNima qiladi
insertOneBitta hujjat
insertManyRo'yxat
updateOne + upsert: trueYo'q bo'lsa qo'shadi, bor bo'lsa yangilaydi
bulkWriteBir nechta har xil amalni birga
mongoimportFayldan (JSON, CSV) - 19-bob
JavaScript
const javob = db.kitob.updateOne(
  { nom: "Mehrobdan chayon" },
  { $set: { muallif: "Abdulla Qodiriy", narx: 72000 } },
  { upsert: true }
)
javob.matchedCount
javob.upsertedCount
db.kitob.findOne({ nom: "Mehrobdan chayon" }, { _id: 0 })
Natija
0
1
{ nom: 'Mehrobdan chayon', muallif: 'Abdulla Qodiriy', narx: 72000 }

matchedCount: 0 - mos hujjat topilmadi. upsertedCount: 1

  • shuning uchun yangisi yaratildi. Filtrdagi nom ham yangi

hujjatga tushib qolganiga e'tibor bering.

upsert haqida 7-bobda batafsil gaplashamiz.

Amaliy topshiriq
  1. insertOne bilan bitta hujjat qo'shing va javobni o'qing.
  2. insertMany bilan uchta hujjat qo'shing.
  3. _id bermasdan hujjat qo'shing va nima qo'yilganini ko'ring.
  4. Tabiiy kalitni _id ga qo'yishning foydasini yozing.
  5. _id uchun elektron pochta nega yomon tanlov ekanini tushuntiring.
  6. Takroriy _id bilan hujjat qo'shib, xato kodini yozing.
  7. ordered: true da xatodan keyin nima bo'lishini sinang.
  8. Xuddi shuni ordered: false bilan takrorlang va farqni yozing.
  9. insertMany nega tranzaksiya emasligini tushuntiring.
  10. w: "majority" qachon kerakligini yozing.

Xulosa #

  • insertOne bitta, insertMany bir nechta hujjat qo'shadi.
  • _id majburiy; berilmasa mijoz ObjectId yaratadi.
  • ObjectId ni server emas, mijoz yaratadi - shuning uchun u darhol ma'lum.
  • Tabiiy kalit bo'lsa (ISBN, tartib raqami), uni to'g'ridan-to'g'ri _id ga qo'ying.
  • _id ni keyin o'zgartirib bo'lmaydi - o'zgaruvchan qiymatni qo'ymang.
  • Takroriy kalit E11000 xatosini beradi.
  • insertMany tranzaksiya emas: xatodan oldin qo'shilganlar joyida qoladi.
  • ordered: false xatodan keyin ham davom etadi.
  • acknowledged: true "diskka yozildi" degani emas.
  • Muhim ma'lumot uchun w: "majority", yo'qolsa mayli bo'lgan uchun w: 0.

Keyingi bo'limda hujjatlarni qidirishni - find va filtr 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.