# `Milvex.AnnSearch`

Represents a single ANN search request for hybrid search.

Supports both vector data (for dense/sparse vector search) and
text data (for BM25 full-text search).

## Examples

    # Vector search
    {:ok, search} = AnnSearch.new("embedding", [[0.1, 0.2, 0.3]],
      limit: 10,
      params: %{nprobe: 10}
    )

    # Text search (BM25)
    {:ok, search} = AnnSearch.new("text_sparse", ["search query"],
      limit: 10
    )

# `query_data`

```elixir
@type query_data() :: [[number()]] | [String.t()]
```

Query data - either vectors for dense/sparse search or text strings for BM25.

# `t`

```elixir
@type t() :: %Milvex.AnnSearch{
  anns_field: String.t(),
  data: query_data(),
  expr: String.t() | nil,
  expr_params: map() | nil,
  limit: pos_integer(),
  params: map() | nil
}
```

# `new`

```elixir
@spec new(String.t(), query_data(), keyword()) ::
  {:ok, t()} | {:error, Milvex.Errors.Invalid.t()}
```

Creates a new ANN search request.

## Parameters

  - `anns_field` - Name of the vector field to search
  - `data` - Query vectors or text strings
  - `opts` - Options (see below)

## Options

  - `:limit` - (required) Maximum results for this sub-search
  - `:params` - Search parameters map (e.g., `%{nprobe: 10}`)
  - `:expr` - Filter expression string
  - `:expr_params` - Template parameters map for the filter expression (e.g., `%{"min_year" => 2020}`)

## Examples

    {:ok, search} = AnnSearch.new("embedding", [[0.1, 0.2]], limit: 10)
    {:ok, search} = AnnSearch.new("text_sparse", ["query"], limit: 5)

---

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