
# Queries

`RecordQuery` is het streamingfilter dat met `stream()` wordt gebruikt. Het dekt toegangspatronen waarbij records worden toegevoegd: verdergaan na een cursor, een tijdvenster lezen, filteren op veldgelijkheid en stoppen bij een limiet. Gebruik voor uitgebreidere predicaten, sortering en op indexen gebaseerde zoekopdrachten de [querybuilder](https://storh.inline0.dev/nl/docs/query-builder). Voor alles wat een gewone `foreach` op een stream kan doen, is `RecordQuery` het efficiëntere hulpmiddel.

`RecordQuery` is onveranderlijk. Elke modifier retourneert een gekloonde query:

```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()` en `time_range_ms()` gebruiken UUID-sortering, dus de recordgegevens hoeven geen tijdstempelveld te bevatten. Op `SegmentedLog` slaan ze ook werk over: segmenten waarvan het ID-bereik buiten het venster valt, worden nooit geopend, en sparse indexen per segment zoeken dicht bij het eerste overeenkomende record in plaats van vanaf het begin te scannen.

`where_equal()` vergelijkt een gegevensveld op het hoogste niveau met `===` en accepteert scalaire waarden of `null`. Een filter `null` komt overeen met records waarin het veld aanwezig is en null is; records zonder dat veld komen niet overeen.

## Cursorpaginering

ID's worden gesorteerd op aanmaaktijd, dus de laatste ID van een pagina is de cursor voor de volgende:

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

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

## Beschadigde records behouden

Een scan stopt standaard bij de eerste onleesbare record. Gebruik `continue_on_error()` als de scan die record moet overslaan en de fout moet rapporteren:

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

De locatie is de record-ID voor `DocStore` en `segment-file:byte-offset`, en `SegmentedLog` voor `repair()`. [CLI](https://storh.inline0.dev/nl/docs/cli) is het hulpmiddel om beschadigde records daadwerkelijk op te ruimen.
