
# Індекси

`DocStore` індекси зберігаються поряд із колекцією в каталозі `.storh/indexes`.
Це звичайні файли, що повністю формуються із записів і можуть бути
перебудовані будь-коли. Їх можна оголосити ланцюжком викликів або через
[схему](https://storh.inline0.dev/uk/docs/schema):

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

Типи індексів:

- індекси рівності для полів, як-от `kind` або `status`: один файл на кожне унікальне
  значення, тому точковий пошук читає лише файл із відповідним значенням
- унікальні індекси для полів, як-от `slug`: унікальність забезпечується під час запису, дубльоване
  значення спричиняє помилку `put()` до записування будь-яких даних
- індекси діапазонів для скалярних значень: відсортований файл із розрідженими контрольними
  точками переходу, що обслуговують `gt`, `gte`, `lt`, `lte`, `between` і `prefix`

Індекси діапазонів також можуть повертати `orderBy` для того самого поля з `limit`
безпосередньо в порядку індексу, за зростанням або спаданням, без матеріалізації та
сортування всього результату.

Коли запит поєднує два предикати `eq` для неунікальних полів з індексами рівності,
storh може використовувати автоматичне складене відро для цієї пари полів. Це дає змогу
швидко виконувати вибіркову фільтрацію за двома полями без оголошення ще одного індексу.

## Узгодженість і виправлення

Записи індексів оновлюються після атомарної заміни файлу запису під блокуванням запису колекції,
тому записи й індекси змінюються разом.
`verify()` порівнює кожен індекс із повним скануванням записів і повідомляє про розбіжності;
`reindex()` перебудовує всі налаштовані індекси за файлами записів; `repair()`
поміщає пошкоджені записи в карантин, а потім перебудовує індекси.

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

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

`explain()` повертає `index_scan`, якщо планувальник може використати налаштований індекс, інакше — `full_scan`.
