Full-text Search
Keyword search, fuzzy matching, text matching, and BM25 relevance ranking.
Full-text search lets you find nodes by the words in their string properties.
Omnigraph provides four text search expressions: search() for keyword
matching, fuzzy() for typo-tolerant matching, match_text() for a dedicated
text-match call site, and bm25() for relevance ranking.
Schema setup
Text search requires an @index annotation on a String property. This causes
Omnigraph to build an inverted index over that field when data is loaded.
node Article {
slug: String @key
title: String @index
body: String @index
}
node Person {
name: String @key
bio: String @index
}Without @index, queries that reference search(), fuzzy(), match_text(),
or bm25() on that field are rejected at compile time.
search() — keyword matching
search(field, term) appears in the match block and filters to nodes whose
indexed field contains the search term.
query find_articles($term: String) {
match {
$a: Article
search($a.title, $term)
}
return { $a.slug, $a.title }
}fuzzy() — typo-tolerant matching
fuzzy(field, term, distance) works like search() but allows matches within
a given edit distance. The third argument is optional and defaults to 2.
query fuzzy_search($term: String) {
match {
$p: Person
fuzzy($p.name, $term, 2)
}
return { $p.name }
}match_text() — current text-match behavior
match_text(field, phrase) is a separate query expression, but in the current
runtime it uses the same Lance full-text backend as search(). Treat it as
tokenized text matching, not strict phrase adjacency.
query phrase_search($phrase: String) {
match {
$a: Article
match_text($a.body, $phrase)
}
return { $a.slug, $a.title }
}bm25() — relevance ranking
bm25(field, term) appears in the order block and ranks results by BM25
relevance score.
query ranked_articles($term: String) {
match {
$a: Article
search($a.title, $term)
}
return { $a.slug, $a.title }
order { bm25($a.title, $term) desc }
}Combining search with traversal
Search expressions compose naturally with graph traversal. You can filter by text, traverse edges, and return properties from connected nodes:
query articles_by_author($term: String, $author: String) {
match {
$a: Article
search($a.title, $term)
$a writtenBy $p: Person { name: $author }
}
return { $a.slug, $a.title, $p.name }
order { bm25($a.title, $term) desc }
}