createIndex() cu unique: true în MongoDB & NoSQL

Un index unic garantează că două documente nu pot avea aceeași valoare într-un câmp, de exemplu același email.

Sintaxă
db.colectie.createIndex({ <camp>: 1 }, { unique: true, partialFilterExpression: { ... }, name: '...' })

Ce face createIndex() cu unique: true

Cu opțiunea unique: true, MongoDB refuză orice inserare sau actualizare care ar crea o valoare duplicată în câmpul indexat. Este singura metodă sigură de a garanta unicitatea: o verificare în aplicație („există deja?”) nu oprește doi clienți care scriu în același timp. createIndex() există în mongosh din MongoDB 3.0 (înainte: ensureIndex).

Atenție: un document fără câmp contează ca valoare null, deci doar un singur document poate lipsi câmpul. Ca să permiți mai multe documente fără email, folosește un index unic parțial, cu partialFilterExpression, care indexează doar documentele unde câmpul există.

Parametri

Parametru Descriere
unique: true Respinge valorile duplicate.
partialFilterExpression Indexează (și verifică) doar documentele care se potrivesc filtrului.
name Numele indexului (implicit camp_1).

Ce returnează

Numele indexului creat. La duplicat, scrierea dă eroarea E11000 duplicate key error.

Exemple

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

use magazin
db.clienti.insertMany([
  { _id: 1, nume: 'Ana', email: 'ana@exemplu.ro' },
  { _id: 2, nume: 'Dan', email: 'dan@exemplu.ro' },
  { _id: 3, nume: 'Ioana' }
])

Exemplul 1: Email unic pentru clienți

Ioana nu are email, dar e singurul document fără câmp, deci indexul se poate crea.

db.clienti.createIndex({ email: 1 }, { unique: true })

Ieșire în mongosh

email_1

Exemplul 2: Inserarea unui duplicat este refuzată

După exemplul 1, al doilea client cu același email nu poate fi salvat.

db.clienti.insertOne({ nume: 'Ana Popescu', email: 'ana@exemplu.ro' })

Ieșire în mongosh

MongoServerError: E11000 duplicate key error collection: magazin.clienti index: email_1 dup key: { email: "ana@exemplu.ro" }

Exemplul 3: Unic doar acolo unde există email

Indexul parțial ignoră documentele fără email, deci poți avea oricâți clienți fără el. Se creează în locul indexului din exemplul 1: șterge-l întâi cu dropIndex('email_1'), altfel MongoDB refuză un al doilea index pe aceeași cheie cu alte opțiuni.

db.clienti.createIndex({ email: 1 }, { unique: true, partialFilterExpression: { email: { $type: 'string' } }, name: 'email_unic' })

Ieșire în mongosh

email_unic

Greșeli frecvente

  • Crearea indexului unic eșuează dacă în colecție există deja duplicate; curăță-le înainte (le găsești cu $group și $match: { n: { $gt: 1 } }).
  • Indexul unic face diferența între majuscule și minuscule: Ana@exemplu.ro și ana@exemplu.ro sunt valori diferite. Salvează emailurile cu litere mici sau folosește o colație.
  • În aplicație, tratează eroarea cu codul 11000 ca „există deja”, nu ca eroare de server.

Comenzi înrudite

  • getIndexes(): Listează indexurile unei colecții, cu câmpurile, numele și opțiunile fiecăruia (unique, expireAfterSeconds etc.).
  • Index compus: Un index compus pe mai multe câmpuri accelerează interogările care filtrează și sortează după aceste câmpuri, în ordinea lor.
  • 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.
  • dropIndex() / dropIndexes(): dropIndex() șterge un index după nume sau după cheie; dropIndexes() le șterge pe toate, în afară de _id.