
# Dotazy

`RecordQuery` je streamovací filtr používaný s `stream()`. Pokrývá přístupové vzory zaměřené na přidávání: pokračování od kurzoru, čtení časového okna, filtrování podle rovnosti polí a zastavení na limitu. Pro složitější predikáty, řazení a vyhledávání s podporou indexů použijte [tvůrce dotazů](https://storh.inline0.dev/cs/docs/query-builder); pro vše, co zvládne běžné `foreach` nad streamem, je `RecordQuery` úspornější volbou.

`RecordQuery` je neměnný. Každý modifikátor vrací klon dotazu:

```php
$query = Storh\RecordQuery::all()
    ->after($lastSeenId)
    ->time_range_ms($fromMs, $untilMs)
    ->where_equal('kind', 'page')
    ->limit(100);

foreach ($store->stream($query) as $record) {
    // Records are yielded lazily.
}
```

`after()` a `time_range_ms()` používají řazení UUID, takže v datech záznamu nepotřebují časové razítko. Na `SegmentedLog` také přeskočí zbytečnou práci: segmenty, jejichž rozsah ID leží mimo okno, se vůbec neotevřou a řídké indexy pro jednotlivé segmenty vyhledají začátek poblíž prvního odpovídajícího záznamu místo procházení od začátku.

`where_equal()` porovnává pole nejvyšší úrovně v datech s `===` a přijímá skalární hodnoty nebo `null`. Filtr `null` odpovídá záznamům, kde pole existuje a má hodnotu null; záznamy bez tohoto pole neodpovídají.

## Stránkování pomocí kurzoru

ID se řadí podle času vytvoření, takže poslední ID jedné stránky slouží jako kurzor pro další:

```php
$page = iterator_to_array($store->stream(
    Storh\RecordQuery::all()->after($lastSeenId)->limit(100)
), false);

$lastSeenId = [] === $page ? $lastSeenId : end($page)->id();
```

## Zachování poškozených záznamů

Prohledávání ve výchozím nastavení skončí chybou při prvním nečitelném záznamu. Pokud má prohledávání tento záznam přeskočit a místo toho nahlásit chybu, použijte `continue_on_error()`:

```php
$query = Storh\RecordQuery::all()->continue_on_error(
    static function (string $location, Throwable $error): void {
        error_log($location . ': ' . $error->getMessage());
    },
);
```

Umístění je ID záznamu pro `DocStore` a `segment-file:byte-offset`, pro `SegmentedLog`. K samotnému čištění poškozených záznamů slouží `repair()`; viz [CLI](https://storh.inline0.dev/cs/docs/cli).
