
# Kyselyrakennin

`DocStore` ja `SegmentedLog` tarjoavat käyttöön `query()`. `DocStore` voi käyttää toissijaisia indeksejä; `SegmentedLog` soveltaa samoja ehtoja virtaaviin tietueisiin.

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

Hyödyllisiä päätetason menetelmiä:

```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();
```

Kohteessa `DocStore` kaksi `eq`-ehtoa ei-yksikäsitteisillä yhtäsuuruusindeksoiduilla kentillä voi käyttää automaattista yhdistelmäkoria. Yksittäinen yhtäsuuruusehto, `in` ja välioperaattorit käyttävät edelleen niille määritettyjä kenttäindeksejä.

Operaattorit:

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

`andWhere` ja `orWhere` käyttävät takaisinkutsuja, koska `and` ja `or` ovat varattuja PHP-avainsanoja:

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

Ketjutetut `where()`-kutsut yhdistyvät AND-operaatiolla; kukin `orWhere()`-haara lisää vaihtoehdon.

## Suoritustapa

Jokainen ehto toimii kaikissa kokoelmissa; indeksit vaikuttavat vain suorituksen kustannuksiin. Kohteessa `DocStore` `eq` ja `in` ratkaistaan yhtäsuuruusindeksien avulla, välioperaattorit ja `prefix` väli-indeksien avulla, ja `orderBy` yhdessä ehdon `limit` kanssa lukee väli-indeksoitua kenttää indeksijärjestyksessä. Kaikki muu suodatetaan tietueiden läpikäynnillä. Jos suunnittelija ei voi palvella kenttää indeksistä, `orderBy` lajittelee osuvat tietueet muistissa arvossa PHP; suurissa kokoelmissa yhdistä se siksi indeksoituihin ehtoihin. `count()` käyttää indeksimerkintöjen määriä kohteessa `DocStore` ja muistissa olevia laskureita kohteessa `SegmentedLog`, kun suodatin on yksittäinen yhtäsuuruusehto.

`cursor($id)` rajaa tulokset tietuetunnuksen jälkeisiin tietueisiin. Yhdessä toiminnon `page()` kanssa se mahdollistaa vakaan sivutuksen tietuetunnuksen mukaan järjestettynä. Tavalliset virtaavat suodattimet ilman rakenninta kuvataan kohdassa [Kyselyt](https://storh.inline0.dev/fi/docs/queries).
