
# Construtor de consultas

`DocStore` e `SegmentedLog` expõem `query()`. `DocStore` pode usar
índices secundários; `SegmentedLog` aplica os mesmos predicados aos registros transmitidos em fluxo.

```php
$records = $docs
    ->query()
    ->where('kind')->eq('page')
    ->where('status')->in(['draft', 'published'])
    ->where('publishedAt')->between($from, $until)
    ->orderBy('publishedAt', 'desc')
    ->limit(50)
    ->get();
```

Métodos terminais úteis:

```php
$docs->query()->where('slug')->eq('home')->first();
$docs->query()->where('kind')->eq('page')->count();
$docs->query()->cursor($lastId)->page(100)->get();
$docs->query()->where('slug')->eq('home')->explain();
```

Em `DocStore`, duas condições `eq` em campos indexados por igualdade e não únicos podem
usar um bucket composto automático. Igualdade simples, `in` e operadores de intervalo
continuam usando os índices configurados para os campos.

Operadores:

- `eq`, `neq`
- `in`, `notIn`
- `gt`, `gte`, `lt`, `lte`, `between`
- `exists`, `missing`
- `prefix`
- `andWhere`, `orWhere`
- `orderBy`, `limit`, `cursor`, `page`

`andWhere` e `orWhere` usam callbacks porque `and` e `or` são palavras-chave reservadas PHP:

```php
$docs->query()
    ->where('kind')->eq('page')
    ->orWhere(fn ($q) => $q->where('kind')->eq('post')->where('featured')->eq(true))
    ->get();
```

Chamadas encadeadas de `where()` são combinadas com AND; cada ramo de `orWhere()` acrescenta uma
alternativa.

## Como cada operação é executada

Todas as condições funcionam em todas as coleções; os índices alteram apenas o custo.
Em `DocStore`, `eq` e `in` são resolvidos por índices de igualdade; os operadores de intervalo e `prefix` são resolvidos por índices de intervalo, e `orderBy` com `limit` em um campo indexado por intervalo lê na ordem do índice. Todo o restante filtra uma varredura de registros. `orderBy` em um campo que o planejador não consegue atender com um índice ordena os registros correspondentes em PHP; portanto, em coleções grandes, combine-o com condições indexadas. `count()` usa a contagem de entradas do índice em `DocStore` e contadores em memória em `SegmentedLog` quando o filtro é uma única igualdade.

`cursor($id)` restringe os resultados aos registros posteriores ao ID, o que se combina com
`page()` para uma paginação estável ordenada pelo ID do registro. Para filtros simples em fluxo
sem o construtor, consulte [Consultas](https://storh.inline0.dev/pt/docs/queries).
