Skip to main content
Infino retrieves from the same table several ways. Pick the mode that matches the question; you can also compose any of them in SQL. Every search returns Arrow rows, and you can pass a projection to choose which columns come back.

Choose a search mode

Always pass a sensible top-k on production queries: it bounds both the work and the result size.

Full-text (BM25)

Ranked keyword search over an FTS-indexed column.
BM25 score is a similarity — higher is better. (Vector score is a distance; the two run in opposite directions.)

Counting matches

count returns how many rows match a BM25 keyword query, without fetching or ranking them — cheaper than a search when you only need the tally.

Unranked lookups

When you don’t need scoring, token_match (rows containing a token) and exact_match (rows whose column equals a value) return every matching row, unranked.
exact_match and token_match run over an FTS-indexed column. Index the column you want to match, for example IndexSpec().fts("doc_id"), to look it up this way.
Semantic search over a vector-indexed column. Embed the query with the same model you used to index (see Embeddings).
Vector score is a distance: 0.0 is a perfect match and larger is farther. This is the opposite direction from BM25’s score (a similarity, higher is better). Don’t compare the two raw scores — hybrid search fuses them for you by rank.

Pushdown filter

Restrict the kNN to rows whose FTS-indexed column matches a text predicate. This is a pre-filter, where the kNN ranks only among matching rows, not a post-filter on the top-k.
For scalar filtering (such as WHERE source = '...') or filtering the results of a search, query with SQL. Hybrid search runs BM25 and vector kNN over the same table and fuses their rankings with reciprocal-rank fusion (RRF), which is strong when a query has both keyword and semantic intent. It’s a first-class method — pass the text query and the query vector, and it returns ranked Arrow rows like the other searches:
Hybrid search needs both indexes on the table: an fts index on the text column and a vector index on the embedding column. It’s also available in SQL via the hybrid_search table function, where you can compose it with joins and filters.

Limitations

  • Vector search is approximate (IVF). It trades exactness for speed; raise nprobe (and rerank_mult) to recover recall at some cost in work.
  • Bring your own embeddings. Embed queries with the same model and dimension you indexed with.
  • Filters in vector search are text predicates over an FTS-indexed column. For scalar filters, use SQL.
  • exact_match and token_match need an FTS-indexed column.

See also

Last modified on July 15, 2026