Sections
Getting started
CLI flags & config
SQL
DDLDMLSELECTFunctions & expressionsTransactions
Clients
HTTP APINative driversPostgreSQL / MySQL wire protocolBinary RPC
Features
RBAC (multi-user)Embeddings (semantic search)File importBackupsDemo showcase mode and .fdb management
Operations
DeploymentArchitectureFileDB on Windows: tray and autostart
Reference
FileDB vs PostgreSQL / MySQL
AI
AI Features: overviewAI Chat and AI AgentSmart Export and AI Import MappingEmbeddings and Hybrid SearchAI setup: providers and presets
Dashboards
Dashboards: overviewDatasets and chartsNo-Code query builderDashboards AI assistantWidgets, grid and filtersPublic links and exportLayout, text cards and KPI comparison

Embeddings and Hybrid Search

Base embeddings and semantic search (4 providers, vector storage, /api/embed/*) are covered on the "Embeddings (semantic search)" page. This page is about what's built on top: hybrid search, which combines vector similarity with an ordinary SQL filter in a single request.

The problem it solves

/api/embed/search tells you "row 42 in articles is the closest match" — but you still need a second query to fetch that row's actual columns. And there was no way to combine "most similar to X" with "where category = 'news'" in one call — you had to do it in two round trips.

POST /api/vector/search

One HTTP call does all three steps:

  1. Embeds the query text (cached for repeated queries);
  2. Searches the embeddings table for the top-K most similar rows;
  3. Runs SELECT * FROM <table> WHERE pk IN (...) with an optional extra WHERE — and returns the rows together with their similarity scores.
curl -X POST $URL/api/vector/search -H "X-Token: $TOK" -d '{
  "table": "products",
  "text": "warm winter jacket",
  "k": 10,
  "where": "category = ''outerwear'' AND in_stock = true",
  "candidate_multiplier": 3
}'
{
  "hits": [
    {"pk": "482", "score": 0.91, "row": {"id": 482, "name": "Winter parka", "category": "outerwear"}}
  ]
}

An important nuance: rank first, filter second

The pipeline gets the top-K by similarity first, then applies WHERE — not the other way around. If you ask for k=10 and WHERE filters out 7 of them, you get 3 results, not 10 from a wider candidate pool. That's what candidate_multiplier is for: if you expect WHERE to cut the results roughly in half, set it to 3 — the engine then fetches the top-30 by similarity first, and filters after.

What's not there yet: a vector function inside arbitrary SQL (ORDER BY similarity(emb, 'x') in a normal SELECT) — that needs a real function in the SQL parser, tracked separately and not part of the current hybrid endpoint.

Related pages
← Previous
Smart Export and AI Import Mapping
Next →
AI setup: providers and presets