Semantic Search, Built Into Your Database
Keyword search matches strings. Semantic search matches meaning. Montycat does both — vector search, BM25 keyword search, and hybrid ranking that fuses them — directly inside a self-hosted NoSQL database, so you can query your data the way you think about it. No separate search service, no external embedding API. Built in, self-hosted, yours.
Read the docsRank by Meaning
kNN similarity over on-device embeddings returns the closest matches to a natural-language query, scored top-k.
Embed on Write
Text is embedded and indexed as a vector automatically as you write it — no pipeline to run.
Keys or Values
Get lightweight {__key__, __score__} hits to page later, or full {__key__, __score__, __value__} results in one call.
Score Filtering
Drop weak matches with a relevance floor on the scale of the mode you asked for.
Keyword and Hybrid
Rank with BM25 when the query hinges on an exact term, or fuse both rankings with reciprocal rank fusion when it is meaning and term at once.
What is semantic search?
Semantic search represents text as vectors (embeddings) so that similar meanings sit close together in vector space. A query is embedded the same way, and the database returns its nearest neighbors. The result: searching for "cancel my subscription" surfaces "end recurring billing" even though they share no keywords.
It is the retrieval technique behind RAG, AI-agent memory, recommendations, deduplication, and semantic product search — anywhere matching by meaning beats matching by string.
Semantic search vs. keyword search
Keyword (full-text) search and semantic search solve different problems — and Montycat gives you both, plus a mode that runs them together:
- Keyword search matches exact tokens; semantic search matches meaning, so synonyms and paraphrases still hit.
- Keyword search fails on vocabulary mismatch between the query and the content; semantic search bridges it.
- Keyword search ranks by term frequency; semantic search ranks by vector similarity (cosine distance).
- Semantic search understands intent — "affordable laptop for coding" finds relevant products without those exact words.
- Neither wins outright: a part number, an error code, or a product name is exactly where keyword search beats a vector model, which will happily rank synonyms alongside it.
How Montycat does it
Montycat embeds your data on-device using a built-in engine and indexes it in an approximate nearest-neighbor graph (HNSW) for sub-linear search. You enable it once, DB-wide, and every keyspace is embedded in the background as data is written — the write path never blocks on embedding.
Queries return hits ranked by cosine similarity, with an optional minimum-score cutoff. Records and vectors share one engine, so there is nothing to sync and no second service to run.
Keyword and hybrid ranking
Ranking mode is a per-query choice. Semantic ranks by vector similarity, keyword ranks with BM25 over the stored text, and hybrid runs both and fuses them with reciprocal rank fusion — one request, one ranked list.
Hybrid is the safe default when a query mixes the two, like an error code sitting inside a sentence describing what went wrong. Metadata, timestamp, pointer, and schema filters narrow which records are ranked in every mode, and never rescore them.
- Scores are not comparable across modes: cosine similarity is bounded to [-1, 1], hybrid RRF is normalized to [0, 1], and raw BM25 is unbounded above.
- BM25 keyword indexes are built and maintained alongside the vector index — there is no second service and no separate ingest.
- Keyword and hybrid ranking require Montycat Semantic 1.3.4 or newer.
Choosing an embedding model
Montycat ships a small registry of quantized, on-device models, downloaded on demand and cached locally. You pick the trade-off:
- BGE-small (default) — strong English retrieval, small and fast.
- MiniLM — tiny and very fast, a solid baseline.
- BGE-base — higher quality, larger and slower.
- Multilingual E5 — for non-English and mixed-language corpora.
Tuning your results
Three knobs shape what comes back, and two result shapes fit different needs:
- mode — semantic, keyword, or hybrid ranking for this query.
- top-k — how many results to return.
- min_score — a relevance floor that drops weak matches, set on the scale of the mode you asked for.
- search_values — full {__key__, __score__, __value__} hits when you need the data immediately.
- search_keys — lightweight {__key__, __score__} hits to page or filter before fetching.
Where semantic search helps
Any product that searches text benefits from meaning-aware retrieval:
- Site and in-app search that understands what users mean, not just what they typed.
- Product and content recommendations by similarity.
- Deduplication and clustering of near-identical records.
- The retrieval step in RAG pipelines and AI-agent memory.
Search by meaning, by keyword, or both (Python)
from montycat import SearchMode
# semantic search is on by default in the montycat-semantic edition
hits = await products.search_values(query="Show all Bluetooth devices", limit=5)
# -> [{__key__, __score__, __value__: {"name": "Wireless Headphones"}}, ...] (matched by meaning, not keywords)
# BM25 when the exact term has to appear, hybrid when it is both
exact = await products.search_values(
query="WH-1000XM5", mode=SearchMode.KEYWORD, limit=5
)
mixed = await products.search_values(
query="noise cancelling WH-1000XM5", mode=SearchMode.HYBRID, limit=5, min_score=0.2
)FAQ
Is this full-text search or semantic search?
Both, and you choose per query. Semantic mode ranks by meaning using vector embeddings and kNN similarity, keyword mode ranks with BM25 over the stored text, and hybrid mode fuses the two with reciprocal rank fusion.
Do I need a separate vector database?
No. The vector index lives inside Montycat alongside your records, so there is no separate service to run or sync.
Which embedding models are supported?
A small on-device registry — MiniLM, BGE (small/base), and multilingual E5 — downloaded on demand and cached locally. The default is BGE-small.
Is semantic search fast enough for real-time use?
Yes. Search runs over an approximate nearest-neighbor (HNSW) index for sub-linear latency, and embedding happens off the write path, so queries stay fast even as data grows.
Can I combine semantic search with exact filters?
Yes. Use exact-match lookups for structured filters and semantic search for meaning-based ranking, all within the same engine and keyspace.
