
# Índices

`DocStore` índices são armazenados ao lado da coleção em `.storh/indexes`.
São arquivos comuns, derivados inteiramente dos registros, e podem ser
reconstruídos a qualquer momento. Declare-os de forma fluente ou por meio de um
[esquema](https://storh.inline0.dev/pt/docs/schema):

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

Tipos de índice:

- índices de igualdade para campos como `kind` ou `status`: um arquivo por valor distinto,
  para que uma consulta pontual leia apenas o arquivo do valor correspondente
- índices únicos para campos como `slug`: aplicados no momento da gravação; um valor
  duplicado faz a operação `put()` falhar antes de qualquer gravação
- índices de intervalo para valores escalares: um arquivo ordenado com pontos de verificação de busca esparsos,
  que atende a `gt`, `gte`, `lt`, `lte`, `between` e `prefix`

Índices de intervalo também podem responder a `orderBy` no mesmo campo com um `limit`
diretamente pela ordem do índice, crescente ou decrescente, sem materializar e
ordenar todo o resultado.

Quando uma consulta combina dois predicados `eq` em campos indexados por igualdade e não únicos,
storh pode usar um bucket composto automático para esse par de campos. Isso mantém
rápidos os filtros seletivos de dois campos sem exigir a declaração de outro índice.

## Consistência e reparo

As gravações atualizam as entradas do índice depois que o arquivo de registro é substituído atomicamente,
sob o bloqueio de gravação da coleção, para que registros e índices sejam atualizados em conjunto.
`verify()` compara cada índice com uma varredura completa dos registros e informa divergências;
`reindex()` reconstrói todos os índices configurados a partir dos arquivos de registro; `repair()`
isola os registros corrompidos e depois reconstrói os índices.

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

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

`explain()` retorna `index_scan` quando o planejador pode usar um índice configurado e
`full_scan` caso contrário.
