
# Constructor de consultas

`DocStore` y `SegmentedLog` exponen `query()`. `DocStore` puede usar índices secundarios; `SegmentedLog` aplica los mismos predicados a los registros transmitidos.

```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étodos terminales útiles:

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

En `DocStore`, dos condiciones `eq` sobre campos indexados por igualdad no únicos pueden usar una cesta compuesta automática. La igualdad individual, `in` y los operadores de rango siguen usando los índices configurados para cada campo.

Operadores:

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

`andWhere` y `orWhere` usan funciones de devolución de llamada porque `and` y `or` son palabras clave reservadas de PHP:

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

Las llamadas encadenadas a `where()` se combinan con AND; cada rama de `orWhere()` añade una alternativa.

## Cómo se ejecuta cada operación

Todas las condiciones funcionan en todas las colecciones; los índices solo cambian el coste. En `DocStore`, `eq` y `in` se resuelven mediante índices de igualdad; los operadores de rango y `prefix` se resuelven mediante índices de rango; y `orderBy` con `limit` sobre un campo con índice de rango lee en el orden del índice. Todo lo demás filtra un recorrido de registros. `orderBy` sobre un campo que el planificador no puede atender con un índice ordena los registros coincidentes en PHP, así que, en colecciones grandes, combínelo con condiciones indexadas. `count()` usa el número de entradas del índice en `DocStore` y los contadores en memoria en `SegmentedLog` cuando el filtro es una única igualdad.

`cursor($id)` restringe los resultados a los registros posteriores al identificador, y se combina con `page()` para una paginación estable ordenada por identificador de registro. Para filtros de transmisión sencillos sin el constructor, consulte [Consultas](https://storh.inline0.dev/es/docs/queries).
