> ## Documentation Index
> Fetch the complete documentation index at: https://infino.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Indexing: BM25 full-text and IVF vector indexes

> Declare full-text BM25 and vector IVF indexes on your Infino tables, and pick the dimension and distance metric that match your embeddings.

You declare indexes once, at table creation, with an `IndexSpec`. Two index types,
chained fluently.

| Index | Declare with | Powers |
| - | - | - |
| Full-text (BM25) | `fts(column)` | keyword search, hybrid, the pushdown filter |
| Vector (IVF) | `vector(column, dim, metric)` | semantic kNN, hybrid |

Declare both on a table to enable [hybrid search](https://infino.ai/docs/guides/search.md#hybrid-search). Scalar columns
need no index; filter them with [SQL](https://infino.ai/docs/sql-reference.md).

```python Python icon="python" theme={null}
spec = (
    infino.IndexSpec()
    .fts("body")                               # BM25 over `body`
    .vector("embedding", 384, "cosine")    # vector index over `embedding`
)
```

```typescript Node.js icon="node-js" theme={null}
const spec = new IndexSpec()
  .fts("body")                                 // BM25 over `body`
  .vector("embedding", 384, "cosine");     // vector index over `embedding`
```

```rust Rust icon="rust" theme={null}
use infino::{IndexSpec, Metric};

let spec = IndexSpec::new()
    .fts("body")                                  // BM25 over `body`
    .vector("embedding", 384, Metric::Cosine); // vector index over `embedding`
```

## Full-text index: `fts(column)`

Builds a BM25 inverted index over a text column, powering `bm25_search`, `token_match`,
and the hybrid / pushdown-filter paths. Call `fts` once per text column you want to search.

| Parameter | Type | Description |
| - | - | - |
| `column` | string | the text column to index |
| `analyzer` | `standard` | tokenizer; `standard` (Unicode-aware) is the only one and the default |
| `stored` | bool | keep the raw text in the table; default `true`. `false` makes the column searchable but not readable back |
| `k1` / `b` | float | BM25 term-frequency saturation and length normalization; pass both or neither |
| `stopwords` | string (`english`) | stopword set removed at index and query time; default none |
| `stemmer` | string (`english`) | stemmer applied at index and query time; default none |
| `positions` | bool | record token positions; default `false`. Needed for phrase queries: a column without them errors on a phrase query |

Each option is recorded with the table at create time and cannot be changed afterwards.

## Vector index: `vector(column, dim, metric)`

Builds an IVF (inverted-file) vector index for kNN.

| Parameter | Type | Description |
| - | - | - |
| `column` | string | the fixed-width vector column to index |
| `dim` | int | embedding dimension, in \[16, 4096]; must match your model's output and the values you append |
| `metric` | `cosine` / `l2sq` / `negdot` (`Metric::Cosine` …) | distance metric (see [Embeddings](https://infino.ai/docs/guides/embeddings.md)) |

**Partitioning is automatic.** The engine derives the IVF partition (centroid) count
from the data when the index is built, and it calibrates probe width and rerank budget
per table and per `k` at query time. There are no partition or probe knobs to set, and
the same declaration works from thousands of rows to hundreds of millions.

> [!NOTE]
>
> You can index multiple text columns (call `fts` per column) and multiple vector columns.
> **Scalar columns need no index declaration.** Filter them with SQL (`query_sql`); vector search's
> pushdown pre-filter is a text predicate over an FTS-indexed column (see [Search](https://infino.ai/docs/guides/search.md#pushdown-filter)).

## See also

* [Tables](https://infino.ai/docs/guides/tables.md)
* [Search](https://infino.ai/docs/guides/search.md#full-text-bm25)
* [Embeddings](https://infino.ai/docs/guides/embeddings.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.