
# Constructeur de requêtes

`DocStore` et `SegmentedLog` exposent `query()`. `DocStore` peut utiliser des index secondaires ; `SegmentedLog` applique les mêmes prédicats aux enregistrements parcourus en continu.

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

Méthodes terminales utiles :

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

Sur `DocStore`, deux conditions `eq` sur des champs indexés par égalité non uniques peuvent utiliser un compartiment composé automatique. Les opérateurs d’égalité simple, `in` et de plage continuent d’utiliser les index configurés pour leurs champs.

Opérateurs :

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

`andWhere` et `orWhere` utilisent des fonctions de rappel, car `and` et `or` sont des mots-clés réservés PHP :

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

Les appels chaînés à `where()` se combinent avec ET ; chaque branche `orWhere()` ajoute une autre possibilité.

## Mode d’exécution

Chaque condition fonctionne sur toutes les collections ; les index ne changent que le coût. Sur `DocStore`, `eq` et `in` utilisent les index d’égalité ; les opérateurs de plage et `prefix` utilisent les index de plage ; et `orderBy` avec `limit` sur un champ doté d’un index de plage lit les données dans l’ordre de l’index. Tout le reste filtre un parcours des enregistrements. `orderBy` sur un champ que le planificateur ne peut pas servir à partir d’un index trie les enregistrements correspondants en PHP ; dans les grandes collections, associez-le donc à des conditions indexées. `count()` utilise le nombre d’entrées de l’index sur `DocStore` et les compteurs en mémoire sur `SegmentedLog` lorsque le filtre est une égalité simple.

`cursor($id)` limite les résultats aux enregistrements dont l’identifiant suit celui indiqué ; combiné à `page()`, il permet une pagination stable triée par identifiant d’enregistrement. Pour les filtres en continu simples sans constructeur, consultez [Requêtes](https://storh.inline0.dev/fr/docs/queries).
