
# Indici

`DocStore` Gli indici sono memorizzati accanto alla raccolta in `.storh/indexes`.
Sono normali file, derivati interamente dai record e ricostruibili in qualsiasi
momento. Potete dichiararli in modo fluido o tramite uno
[schema](https://storh.inline0.dev/it/docs/schema):

```php
$docs->indexes()
    ->field('slug')->unique()
    ->field('kind')
    ->field('publishedAt')->range()
    ->sync();
```

Tipi di indice:

- indici di uguaglianza per campi come `kind` o `status`: un file per ogni valore distinto,
  così una ricerca puntuale legge solo il file del valore corrispondente
- indici univoci per campi come `slug`: applicati al momento della scrittura; un valore duplicato
  fa fallire `put()` prima che venga scritto alcunché
- indici per intervallo per valori scalari: un file ordinato con checkpoint di ricerca sparsi,
  che supporta `gt`, `gte`, `lt`, `lte`, `between` e `prefix`

Gli indici per intervallo possono anche rispondere a `orderBy` sullo stesso campo con un `limit`
partendo direttamente dall'ordine dell'indice, crescente o decrescente, senza materializzare e
ordinare l'intero risultato.

Quando una query combina due condizioni `eq` su campi indicizzati per uguaglianza non univoci,
storh può usare un bucket composto automatico per quella coppia di campi. Questo mantiene
veloci i filtri selettivi su due campi senza richiedere la dichiarazione di un altro indice.

## Coerenza e riparazione

Le scritture aggiornano le voci dell'indice dopo la sostituzione atomica del file del record,
all'interno del lock di scrittura della raccolta, così record e indici si aggiornano insieme.
`verify()` confronta ogni indice con una scansione completa dei record e segnala eventuali divergenze;
`reindex()` ricostruisce ogni indice configurato a partire dai file dei record; `repair()`
mette in quarantena i record danneggiati e poi ricostruisce gli indici.

```php
$docs->reindex();

$plan = $docs
    ->query()
    ->where('slug')->eq('home')
    ->explain();
```

`explain()` restituisce `index_scan` quando il pianificatore può usare un indice configurato e
`full_scan` negli altri casi.
