Full-Text Search in Your Database โ€” BM25, No Separate Engine

Adding search usually means adding infrastructure: an external engine, an indexing pipeline, and a sync job that drifts. In Aito v2, any Text column is full-text searchable in place โ€” analyzed, BM25-ranked, and composable with ordinary database conditions in the same JSON query. The same index also powers prediction from text, so search and inference share one copy of the data.

The $search operator

A Lucene-subset query language: bare terms (AND), "quoted phrases", OR, NOT / -term, and ( โ€ฆ ) groups.

{
  "from": "products",
  "where": { "name": { "$search": "(milk OR bread) AND NOT chocolate" } },
  "select": ["name"],
  "limit": 20
}
{ "offset": 0, "total": 11, "hits": [
  { "name": "Fazer Puikula fullcorn rye bread 330g" },
  { "name": "Pirkka Finnish semi-skimmed milk 1l" },
  { "name": "Valio semi-skimmed milk 1l" } ] }

It composes with plain conditions โ€” full-text match and structured filter in one where:

{
  "from": "products",
  "where": {
    "name": { "$search": "milk OR juice" },
    "category": "104"
  },
  "select": ["name", "category"]
}

Relevance-ranked search with highlighting

The search query type ranks by BM25 โ€” the same scorer Lucene and Elasticsearch use โ€” and $highlight marks the matched tokens for your UI:

{
  "from": "products",
  "search": { "field": "name", "text": "milk" },
  "select": ["name", "$score", "$highlight"],
  "limit": 3
}

$why on a search result breaks the score down per token; $matches reports the matched token positions.

From search to understanding

Because the analyzed text is a first-class column, the same tokens are prediction evidence โ€” this is where an embedded search engine beats a bolted-on one:

{
  "from": "products",
  "where": { "name": { "$match": "semi-skimmed milk" } },
  "predict": "category",
  "select": ["$value", "$p", "$why"],
  "limit": 1
}

One system answers "which rows match" (search), "which category is this" (classification), and "why" (explanation) โ€” over the same live data, with no sync pipeline.

Why Aito for this

  • Zero-infrastructure: per-language analyzers configured in the schema ("type": "Text", "analyzer": "English"); the index is built and merged with the data.
  • Exact, reproducible results โ€” real BM25 scores, deterministic ties.
  • Composability: $search is a where proposition like any other โ€” it works under predict, in population restrictions, and alongside links.

Related: Query Reference ยท Vector Search for semantic (embedding-based) retrieval ยท Sandbox

โ† All v2 use cases