
# 인덱스

`DocStore` 인덱스는 컬렉션 옆의 `.storh/indexes` 아래에 저장됩니다.
일반 파일이며 레코드에서만 파생되므로 언제든 다시 빌드할 수 있습니다. 유창한 방식이나 [스키마](https://storh.inline0.dev/ko/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은 해당 필드 쌍에 자동 복합 버킷을 사용할 수 있습니다. 별도의 인덱스 선언 없이도 선택적인 2개 필드 필터를 빠르게 처리합니다.

## 일관성 및 복구

쓰기 잠금 아래에서 레코드 파일을 원자적으로 교체한 후 인덱스 항목을 업데이트하므로 레코드와 인덱스가 함께 변경됩니다. `verify()`은 전체 레코드 스캔 결과와 모든 인덱스를 비교해 불일치를 보고합니다. `reindex()`은 레코드 파일에서 설정된 모든 인덱스를 다시 빌드하고, `repair()`는 손상된 레코드를 격리한 다음 인덱스를 다시 빌드합니다.

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

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

`explain()`은 쿼리 계획자가 설정된 인덱스를 사용할 수 있으면 `index_scan`을 반환하고, 그렇지 않으면 `full_scan`를 반환합니다.
