
# Konstruktor zapytań

`DocStore` i `SegmentedLog` udostępniają `query()`. `DocStore` może korzystać z indeksów pomocniczych; `SegmentedLog` stosuje te same predykaty do strumieniowanych rekordów.

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

Przydatne metody końcowe:

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

W `DocStore` dwa warunki `eq` dotyczące pól z nieunikalnym indeksem równości mogą
korzystać z automatycznego indeksu złożonego. Pojedynczy warunek równości, `in` i operatory zakresu
nadal korzystają ze skonfigurowanych indeksów pól.

Operatory:

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

`andWhere` i `orWhere` używają funkcji zwrotnych, ponieważ `and` i `or` są zarezerwowanymi słowami kluczowymi PHP:

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

Łańcuchowe wywołania `where()` łączą warunki operatorem AND; każda gałąź `orWhere()` dodaje
alternatywę.

## Sposób wykonywania zapytań

Każdy warunek działa w każdej kolekcji; indeksy wpływają tylko na koszt.
W `DocStore` `eq` i `in` korzystają z indeksów równości, operatory zakresu i `prefix` korzystają z indeksów zakresu, a `orderBy` z `limit` dla pola z indeksem zakresu odczytuje dane w kolejności indeksu. Pozostałe przypadki filtrują wyniki skanowania rekordów. `orderBy` dla pola, którego planer nie może obsłużyć za pomocą indeksu, sortuje
pasujące rekordy w pamięci PHP, więc w dużych kolekcjach łącz je z warunkami korzystającymi z indeksów. `count()` używa liczby wpisów w indeksie w `DocStore` oraz liczników w pamięci w `SegmentedLog`, jeśli filtr dotyczy pojedynczej równości.

`cursor($id)` ogranicza wyniki do rekordów po wskazanym identyfikatorze; w połączeniu z `page()` zapewnia stabilne stronicowanie posortowane według identyfikatora rekordu. Informacje o prostych filtrach strumieniowych bez konstruktora znajdziesz w sekcji [Zapytania](https://storh.inline0.dev/pl/docs/queries).
