Search
Full-text, fuzzy, vector, and hybrid search are first-class query expressions in Omnigraph.
Omnigraph has five built-in search expressions plus Reciprocal Rank Fusion
(rrf) for hybrid ranking. They are not separate services. They are
expressions you use directly inside .gq queries, alongside traversal,
filtering, and projection.
The search modes
| Expression | Mode | Where it appears | What it does |
|---|---|---|---|
search(field, term) | Full-text | match, order, return | Inverted-index keyword matching. In match it filters; in order/return it projects a score. |
fuzzy(field, term, distance) | Fuzzy | match, order, return | Edit-distance-tolerant text matching for typos and near-matches. |
match_text(field, phrase) | Text match | match, order, return | Same Lance full-text backend as search; tokenized matching, not strict phrase adjacency. |
bm25(field, term) | BM25 ranking | order, return | BM25 relevance score over an @index-ed String field. |
nearest(field, query) | Vector KNN | order, return | Nearest-neighbor distance over an @index-ed Vector(N) field. Accepts a Vector(N) parameter or a string that the engine auto-embeds. Requires limit. |
rrf(rank_a, rank_b, k?) | Hybrid | order | Reciprocal Rank Fusion of two ranking signals. Optional third argument is the rank-fusion constant k (default 60). Requires limit. |
Where search expressions appear
Search expressions are valid in three places inside a query:
matchblock,search(),fuzzy(), andmatch_text()act as filters. They restrict which nodes are returned.orderblock,bm25(),nearest(), andrrf()rank results by relevance. Any of the text expressions can also drive ordering.returnblock. Any search expression can be projected as a per-row score column, so callers can see the underlying signal that produced the ranking.
A query can combine all three: filter in match, rank in order, expose the
score in return.
query find_experts($term: String, $vec: Vector(1536)) {
match {
$p: Person
search($p.bio, $term)
}
return { $p.name, $p.bio }
order { rrf(nearest($p.embedding, $vec), bm25($p.bio, $term)) desc }
limit 10
}Index requirements
Search expressions require indexes on the fields they operate on:
| Search type | Schema annotation | Index created |
|---|---|---|
| Full-text, fuzzy, text match, BM25 | @index on a String field | Inverted index |
| Vector KNN | @index on a Vector(N) field | ivf_flat vector index with L2 metric |
Without the right index, the query compiler rejects the query at compile time.
node Person {
name: String @key
bio: String @index
embedding: Vector(1536) @index
}Combining search with traversal
Search expressions compose with the rest of the query language. You can filter by search, traverse edges, and project properties all in one query:
query experts_at_company($term: String) {
match {
$p: Person
search($p.bio, $term)
$p worksAt $c: Company { name: "Acme" }
}
return { $p.name, $c.name }
order { bm25($p.bio, $term) desc }
}Next steps
- Full-text Search. Keyword search, fuzzy matching, text matching, and BM25 ranking.
- Vector Search. Nearest-neighbor search over embeddings.
- Hybrid Search. Combine BM25 and vector ranking with Reciprocal Rank Fusion.