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

# Indexing

> Declare full-text BM25 and vector IVF indexes on your Infino tables, then tune parameters like analyzers, nlist, and nprobe for recall and speed.

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, n_cent, metric)` | semantic kNN, hybrid                        |

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

<CodeGroup>
  ```python Python icon="python" theme={null}
  spec = (
      infino.IndexSpec()
      .fts("body")                               # BM25 over `body`
      .vector("embedding", 384, 64, "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, 64, "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, 64, Metric::Cosine); // vector index over `embedding`
  ```
</CodeGroup>

## 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.

## Vector index: `vector(column, dim, n_cent, 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; must match your model's output and the values you append |
| `n_cent`  | int                                               | number of IVF partitions (centroids)                                          |
| `metric`  | `cosine` / `l2sq` / `negdot` (`Metric::Cosine` …) | distance metric (see [Embeddings](/guides/embeddings))                        |

**Tuning `n_cent`.** It sets how many partitions the vectors are bucketed into. More
partitions mean finer buckets and faster search **at scale**, at some recall cost per
partition probed. Raise `nprobe` at query time to recover that recall. The engine clamps
`n_cent` sensibly for small datasets, so a few dozen is a fine starting point; raise it
as the table grows into the hundreds of thousands of rows and beyond.

<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`) or as
  a pushdown pre-filter on vector search (see [Search](/guides/search#vector-search)).
</Note>

## See also

* [Tables](/guides/tables)
* [Search](/guides/search#full-text-bm25)
* [Embeddings](/guides/embeddings)
