
# Конструктор на заявки

`DocStore` и `SegmentedLog` предоставят `query()`. `DocStore` може да използва вторични индекси; `SegmentedLog` прилага същите предикати върху поточно извличани записи.

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

Полезни крайни методи:

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

При `DocStore` две условия `eq` върху полета с индекси за равенство, които не са уникални, могат да използват автоматична комбинирана група. Единичното равенство, `in` и операторите за диапазон продължават да използват конфигурираните индекси на полетата си.

Оператори:

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

`andWhere` и `orWhere` използват обратни извиквания, защото `and` и `or` са запазени PHP ключови думи:

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

Последователните извиквания на `where()` се комбинират с AND; всеки клон `orWhere()` добавя алтернатива.

## Как се изпълняват заявките

Всяко условие работи с всяка колекция; индексите променят само цената на изпълнението. При `DocStore` `eq` и `in` се разрешават чрез индекси за равенство, операторите за диапазон и `prefix` — чрез индекси за диапазон, а `orderBy` с `limit` върху поле с индекс за диапазон чете в реда на индекса. Всичко останало филтрира сканиране на записите. `orderBy` върху поле, което планировчикът не може да обслужи чрез индекс, сортира съвпадащите записи в PHP, затова при големи колекции го комбинирайте с индексни условия. `count()` използва броя на индексните записи в `DocStore` и броячи в паметта в `SegmentedLog`, когато филтърът е единично равенство.

`cursor($id)` ограничава резултатите до записи след идентификатора и се комбинира с `page()` за стабилно странично прелистване, подредено по идентификатор на запис. За обикновени поточни филтри без конструктора вижте [Заявки](https://storh.inline0.dev/bg/docs/queries).
