Index compus în MongoDB & NoSQL

Un index compus pe mai multe câmpuri accelerează interogările care filtrează și sortează după aceste câmpuri, în ordinea lor.

Sintaxă
db.colectie.createIndex({ <camp1>: 1, <camp2>: -1, ... })

Ce face Index compus

Un index compus, de exemplu { status: 1, total: -1 }, ține valorile ordonate întâi după status, apoi, în interiorul fiecărui status, după total descrescător. Același index poate răspunde la un filtru pe status și la o sortare după total, fără sortare în memorie.

Ordinea câmpurilor contează. Indexul ajută interogările care folosesc un prefix al lui (status sau status + total), dar nu pe cele doar după total. Regula practică ESR: întâi câmpurile de egalitate (Equality), apoi cele de sortare (Sort), apoi intervalele (Range).

Parametri

Parametru Descriere
camp: 1 / -1 Câmpurile, în ordine, cu direcția de sortare.

Ce returnează

Numele indexului, format din câmpuri și direcții, de exemplu status_1_total_-1.

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: Index pentru „comenzile cu un status, cele mai mari primele”

Numele generat combină câmpurile și direcțiile.

db.comenzi.createIndex({ status: 1, total: -1 })

Ieșire în mongosh

status_1_total_-1

Exemplul 2: Interogarea servită de index

Filtrul de egalitate pe status și sortarea după total folosesc indexul din exemplul 1, în ordinea lui.

db.comenzi.find({ status: 'livrata' }, { client: 1, total: 1 }).sort({ total: -1 })

Ieșire în mongosh

[
  { _id: 3, client: 'Ioana', total: 240 },
  { _id: 1, client: 'Ana', total: 120 }
]

Greșeli frecvente

  • Un index { status: 1, total: -1 } nu ajută la find({ total: { $gt: 100 } }), pentru că total nu e primul câmp.
  • Prea multe indexuri încetinesc scrierile: fiecare inserare actualizează toate indexurile. Șterge-le pe cele nefolosite (vezi $indexStats).
  • Verifică cu explain('executionStats') că interogarea chiar folosește indexul (etapa IXSCAN).

Comenzi înrudite

  • getIndexes(): Listează indexurile unei colecții, cu câmpurile, numele și opțiunile fiecăruia (unique, expireAfterSeconds etc.).
  • createIndex() cu unique: true: Un index unic garantează că două documente nu pot avea aceeași valoare într-un câmp, de exemplu același email.
  • dropIndex() / dropIndexes(): dropIndex() șterge un index după nume sau după cheie; dropIndexes() le șterge pe toate, în afară de _id.
  • $sort / $limit / $skip: Etapele $sort, $skip și $limit ordonează documentele din pipeline și aleg o porțiune din ele (top N, paginare).