# `Zvex.Query`
[🔗](https://github.com/edlontech/zvex/blob/main/lib/zvex/query.ex#L1)

Fluent builder for zvec vector queries.

## Example

    alias Zvex.Query
    alias Zvex.Vector

    vec = Vector.from_list([0.1, 0.2, 0.3, 0.4], :fp32)

    Query.new()
    |> Query.field("embedding")
    |> Query.vector(vec)
    |> Query.top_k(5)
    |> Query.hnsw(ef: 100)
    |> Query.execute(collection)
    # {:ok, [%Zvex.Query.Result{pk: _, score: _, doc_id: _, fields: %{}}]}

# `t`

```elixir
@type t() :: %Zvex.Query{
  field: String.t() | nil,
  filter: String.t() | nil,
  include_doc_id: boolean(),
  include_vector: boolean(),
  output_fields: [String.t()],
  params: nil | {:hnsw, keyword()} | {:ivf, keyword()} | {:flat, keyword()},
  top_k: pos_integer(),
  vector: binary() | nil
}
```

A vector similarity search query built with the fluent API.

# `execute`

```elixir
@spec execute(t(), Zvex.Collection.t()) ::
  {:ok, [Zvex.Query.Result.t()]} | {:error, Zvex.Error.t()}
```

Executes the query against the given collection.

Both `field/2` and `vector/2` must be set before calling this function.
Returns a list of `Zvex.Query.Result` structs sorted by score (closest first).

# `execute!`

```elixir
@spec execute!(t(), Zvex.Collection.t()) :: [Zvex.Query.Result.t()]
```

Like `execute/2` but raises on error.

# `field`

```elixir
@spec field(t(), String.t()) :: t()
```

Sets the vector field to search against. Required before executing.

# `filter`

```elixir
@spec filter(t(), String.t()) :: t()
```

Applies a filter expression to pre-filter candidates before vector search.

The expression uses zvec's filter syntax (e.g. `"category == 'books'"`).

# `flat`

```elixir
@spec flat(
  t(),
  keyword()
) :: t()
```

Selects brute-force flat scan. Guarantees exact results at the cost of speed.

# `hnsw`

```elixir
@spec hnsw(
  t(),
  keyword()
) :: t()
```

Selects HNSW as the search algorithm.

## Options

- `:ef` — search-time expansion factor (higher = better recall, slower search).

# `include_doc_id`

```elixir
@spec include_doc_id(t(), boolean()) :: t()
```

When `true`, includes the internal document ID in each result (default `false`).

# `include_vector`

```elixir
@spec include_vector(t(), boolean()) :: t()
```

When `true`, includes the matched vector data in each result (default `false`).

# `ivf`

```elixir
@spec ivf(
  t(),
  keyword()
) :: t()
```

Selects IVF as the search algorithm.

## Options

- `:n_probe` — number of partitions to scan (higher = better recall, slower search).

# `new`

```elixir
@spec new() :: t()
```

Creates a new query with default values (`top_k: 10`, no filter, no output fields).

# `output_fields`

```elixir
@spec output_fields(t(), [String.t()]) :: t()
```

Specifies which scalar fields to include in the results. Defaults to none.

# `top_k`

```elixir
@spec top_k(t(), pos_integer()) :: t()
```

Sets the maximum number of nearest neighbors to return (default `10`).

# `vector`

```elixir
@spec vector(t(), Zvex.Vector.t() | [number()]) :: t()
```

Sets the query vector for similarity search. Required before executing.

Accepts a `Zvex.Vector` struct or a plain list of numbers (auto-converted
to `:fp32`). Sparse vectors are not supported as query vectors.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
