
# Kueri

`RecordQuery` adalah filter streaming yang digunakan dengan `stream()`. Fitur ini mencakup pola akses yang menggunakan append: lanjutkan setelah cursor, baca jendela waktu, filter berdasarkan kesetaraan kolom, dan berhenti pada batas tertentu. Untuk predikat yang lebih kaya, pengurutan, dan pencarian yang didukung indeks, gunakan [query builder](https://storh.inline0.dev/id/docs/query-builder); untuk semua hal yang dapat dilakukan `RecordQuery` atas stream biasa dengan `foreach`, ini adalah alat yang lebih ringan.

`RecordQuery` bersifat immutable. Setiap modifier mengembalikan kueri kloning:

```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()` dan `time_range_ms()` menggunakan urutan UUID, sehingga tidak memerlukan kolom timestamp dalam data catatan. Pada `SegmentedLog`, keduanya juga menghemat pekerjaan: segmen yang rentang ID-nya berada di luar jendela tidak pernah dibuka, dan indeks sparse per segmen mencari lokasi dekat catatan pertama yang cocok alih-alih memindai dari awal.

`where_equal()` membandingkan kolom data tingkat atas dengan `===` dan menerima nilai skalar atau `null`. Filter `null` mencocokkan catatan ketika kolom tersebut ada dan bernilai null; catatan tanpa kolom itu tidak cocok.

## Paginasi cursor

ID diurutkan berdasarkan waktu pembuatan, sehingga ID terakhir pada satu halaman menjadi cursor untuk halaman berikutnya:

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

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

## Menangani catatan yang rusak

Secara default, pemindaian akan berhenti dengan error pada catatan pertama yang tidak dapat dibaca. Gunakan `continue_on_error()` jika pemindaian perlu melewatinya dan melaporkan kegagalan tersebut:

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

Lokasinya adalah ID catatan untuk `DocStore` dan `segment-file:byte-offset`, serta `SegmentedLog` untuk `repair()`. Untuk benar-benar membersihkan catatan yang rusak, gunakan [CLI](https://storh.inline0.dev/id/docs/cli); lihat dokumentasinya.
