
# Generator de interogări

`DocStore` și `SegmentedLog` oferă `query()`. `DocStore` poate folosi indexuri secundare; `SegmentedLog` aplică aceleași predicate în timp ce parcurge înregistrările în flux.

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

Metode terminale utile:

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

În `DocStore`, două condiții `eq` pe câmpuri indexate după egalitate, dar fără valori unice, pot folosi un bucket compus automat. Egalitatea simplă, `in` și operatorii de interval continuă să folosească indexurile configurate pentru câmpuri.

Operatori:

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

`andWhere` și `orWhere` folosesc callback-uri deoarece `and` și `or` sunt cuvinte-cheie rezervate în PHP:

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

Apelurile înlănțuite `where()` se combină cu AND; fiecare ramură `orWhere()` adaugă o alternativă.

## Cum se execută

Fiecare condiție funcționează pentru fiecare colecție; indexurile schimbă doar costul. În `DocStore`, `eq` și `in` sunt rezolvate prin indexuri de egalitate, operatorii de interval și `prefix` prin indexuri de interval, iar `orderBy` cu `limit` pe un câmp indexat după interval citește în ordinea indexului. Orice altceva filtrează o scanare a înregistrărilor. `orderBy` pe un câmp pe care planificatorul nu îl poate servi dintr-un index sortează în PHP înregistrările potrivite, așa că, pentru colecțiile mari, combinați-l cu condiții indexate. `count()` folosește numărul intrărilor din index pe `DocStore` și contoare în memorie pe `SegmentedLog` când filtrul este o singură egalitate.

`cursor($id)` restrânge rezultatele la înregistrările de după id, lucru care se combină cu `page()` pentru o paginare stabilă, ordonată după id-ul înregistrării. Pentru filtre simple de streaming fără generatorul de interogări, consultați [Interogări](https://storh.inline0.dev/ro/docs/queries).
