Querying
SemiLayer exposes three distinct operations. Understanding which to use and when is the key to building fast, accurate, and secure data features.
| Operation | What it does | Source DB hit? |
|---|---|---|
| Search | Semantic / keyword / hybrid query against vector index | No |
| Similar | Find records nearest to a given record's stored vector | No |
| Query | Direct query through your Bridge — filtered rows | Yes |
Search
Search embeds the query text and finds the nearest vectors. Your source database is never hit — all results come from the vector index built during ingest.
Enable it with facets: { search: { fields: [...] } } in your Lens config.
Search modes
| Mode | How it works |
|---|---|
semantic (default) | Embeds query → cosine similarity against stored vectors |
keyword | PostgreSQL full-text search (tsvector / tsquery) |
hybrid | Reciprocal Rank Fusion (RRF) merge of semantic + keyword |
Request shape
Response shape
Examples
Streaming search
Stream results as they arrive instead of waiting for the full response. Useful for rendering results progressively in a UI.
Similar
Find records similar to a given record using its stored vector. Takes a source record's primary key (as a string), returns nearest neighbors.
Enable it with facets: { similar: { fields: [...] } } in your Lens config.
Request shape
Response shape
Same as Search: { results: SearchResult<M>[], meta: {...} }
Examples
Query
Query reads directly from your source database through the Bridge. Results are real-time (not from the vector index) but the query incurs a live DB call.
query is disabled by default. You must explicitly enable it in your Lens config
by setting rules.query. This is a safety measure — enabling it opens a direct read
path through your Bridge.
Enable query in your Lens config:
Request shape
Response shape
Examples
Streaming query
Stream large result sets row-by-row instead of waiting for the full response:
Live Tail (Subscribe)
Subscribe to all changes on a Lens — every insert, update, and delete fires an event in real time via WebSocket. No polling required.
With a filter (simple equality only in v0.1):
Observe One Record
React to changes on a single record by ID. The first yield is the current state; subsequent yields fire only when the record changes.
Choosing the Right Operation
| You want to... | Use |
|---|---|
| Find relevant records by natural language | Search (semantic) |
| Find exact-match or keyword results | Search (keyword) |
| Blend semantic + keyword results | Search (hybrid) |
| Find records similar to a known item | Similar |
| Filter or sort by known field values | Query |
| Get a live feed of all changes | Subscribe |
| Watch one record for changes | Observe |