bulkWrite() în MongoDB & NoSQL

Operațiuni CRUD MongoDB 3.2

Trimite mai multe operații de scriere (inserări, actualizări, ștergeri) către o colecție într-o singură cerere.

Sintaxă
db.colectie.bulkWrite([ { insertOne: {...} }, { updateOne: {...} }, { updateMany: {...} }, { replaceOne: {...} }, { deleteOne: {...} }, { deleteMany: {...} } ], { ordered: true })

Ce face bulkWrite()

bulkWrite() primește o listă de operații, fiecare descrisă ca un obiect: insertOne, updateOne, updateMany, replaceOne, deleteOne, deleteMany. Toate pleacă spre server într-o singură călătorie prin rețea, ceea ce e mult mai rapid decât sute de apeluri separate.

Implicit (ordered: true) operațiile se execută în ordine și se opresc la prima eroare. Cu ordered: false serverul le poate executa în orice ordine și continuă după erori, raportându-le pe toate la final. bulkWrite nu este o tranzacție: operațiile reușite rămân scrise chiar dacă altele eșuează.

Parametri

Parametru Descriere
insertOne { document }
updateOne / updateMany { filter, update, upsert }
replaceOne { filter, replacement, upsert }
deleteOne / deleteMany { filter }
ordered true (implicit): în ordine, oprire la prima eroare.

Ce returnează

Un rezultat cu numărul de documente inserate, potrivite, modificate, șterse și upsert-ate, plus ID-urile inserate (după poziția operației în listă).

Exemple

Exemplele de pe această pagină pornesc de la datele de mai jos. Rulează mai întâi acest cod, apoi exemplul.

use magazin
db.comenzi.insertMany([
  { _id: 1, client: 'Ana', oras: 'Iași', total: 120, status: 'livrata', produse: ['caiet', 'pix'] },
  { _id: 2, client: 'Dan', oras: 'Cluj', total: 85, status: 'noua', produse: ['carte'] },
  { _id: 3, client: 'Ioana', oras: 'Iași', total: 240, status: 'livrata', produse: ['rucsac', 'caiet', 'pix'] },
  { _id: 4, client: 'Mihai', oras: 'Brașov', total: 60, status: 'anulata', produse: [] }
])

Exemplul 1: O comandă nouă, arhivarea celor livrate și ștergerea celor anulate

Trei tipuri de operații într-o singură cerere. insertedIds folosește poziția operației în listă ca cheie.

db.comenzi.bulkWrite([
  { insertOne: { document: { _id: 6, client: 'Radu', oras: 'Cluj', total: 45, status: 'noua' } } },
  { updateMany: { filter: { status: 'livrata' }, update: { $set: { arhivata: true } } } },
  { deleteOne: { filter: { status: 'anulata' } } }
])

Ieșire în mongosh

{
  acknowledged: true,
  insertedCount: 1,
  insertedIds: { '0': 6 },
  matchedCount: 2,
  modifiedCount: 2,
  deletedCount: 1,
  upsertedCount: 0,
  upsertedIds: {}
}

Exemplul 2: Actualizarea prețurilor dintr-un import

Câte un updateOne cu upsert pentru fiecare produs din fișier; ordered: false continuă și dacă un rând dă eroare. Caietul exista deja în produse cu alt preț (actualizat), pixul nu exista (creat).

db.produse.bulkWrite([
  { updateOne: { filter: { _id: 'caiet' }, update: { $set: { pret: 12 } }, upsert: true } },
  { updateOne: { filter: { _id: 'pix' }, update: { $set: { pret: 4 } }, upsert: true } }
], { ordered: false })

Ieșire în mongosh

{
  acknowledged: true,
  insertedCount: 0,
  insertedIds: {},
  matchedCount: 1,
  modifiedCount: 1,
  deletedCount: 0,
  upsertedCount: 1,
  upsertedIds: { '1': 'pix' }
}

Greșeli frecvente

  • bulkWrite nu anulează operațiile reușite dacă una eșuează. Dacă ai nevoie de „totul sau nimic”, folosește o tranzacție.
  • Numele operațiilor sunt chei de obiect ({ updateOne: { filter, update } }), nu metode; o cheie scrisă greșit dă eroare.

Comenzi înrudite

  • upsert: true și $setOnInsert: Cu upsert: true, updateOne actualizează documentul găsit sau, dacă nu există, îl creează; $setOnInsert scrie câmpuri doar la creare.
  • findOneAndUpdate(): Actualizează un document și îl întoarce, atomic, într-un singur pas; există și findOneAndDelete și findOneAndReplace.
  • Tranzacții cu sesiuni (startTransaction): Tranzacțiile grupează mai multe scrieri, pe mai multe colecții, astfel încât să se aplice toate sau niciuna; cer replica set sau cluster.
  • mongoimport / mongoexport: mongoimport încarcă date din fișiere JSON sau CSV într-o colecție; mongoexport scoate documentele unei colecții în JSON sau CSV.