Full-Text + JSON Search¶
Uni supports full-text search over string properties and JSON documents, plus JSON path predicates for nested fields.
What It Provides¶
- Full-text indexes for string properties.
- JSON full-text search with path targeting.
CONTAINSpredicates on JSON documents.CALL uni.fts.query(...)for BM25-scored search with relevance ranking.
Example¶
use uni_db::Uni;
# async fn demo() -> Result<(), uni_db::UniError> {
let db = Uni::open("./my_db").build().await?;
let session = db.session();
let tx = session.tx().await?;
tx.execute("CREATE FULLTEXT INDEX doc_fts FOR (d:Doc) ON (d.title, d.body)")
.await?;
tx.commit().await?;
let rows = session.query(
"MATCH (d:Doc) WHERE d.body CONTAINS 'vector' RETURN d.title"
).await?;
println!("{:?}", rows);
# Ok(())
# }
FTS Query Procedure¶
For BM25-scored search with normalized relevance scores:
-- Create a fulltext index
CREATE FULLTEXT INDEX article_content FOR (a:Article) ON (a.content)
-- Query with relevance scoring
CALL uni.fts.query('Article', 'content', 'database optimization', 20)
YIELD node, score
RETURN node.title, score
ORDER BY score DESC
Parameters:
label- Node label to searchproperty- Text property with inverted indexsearch_term- Search query stringk- Number of resultsthreshold(optional) - Minimum score (0-1)
Yields:
vid- Vertex IDscore- Normalized BM25 score (0-1)node- Full node with properties
How It Works¶
Auto-Build on Index Creation¶
When you run CREATE FULLTEXT INDEX, Uni automatically builds the FTS index over existing data. There is no need to call rebuild_indexes() manually — the index is ready to query immediately after creation.
-- This both creates AND builds the index in one step
CREATE FULLTEXT INDEX article_content FOR (a:Article) ON (a.content)
Immediate Write Visibility (L0 Buffer)¶
FTS queries see unflushed writes from the in-memory L0 buffer. This means data is searchable immediately after a write, without waiting for a flush to persistent storage. The query engine merges L0 buffer results with on-disk index results transparently.
-- Write and search in the same session — no flush needed
CREATE (a:Article {title: 'New Article', content: 'graph database optimization'})
-- This will find the article even before flush
CALL uni.fts.query('Article', 'content', 'optimization', 10)
YIELD node, score
RETURN node.title, score
Use Cases¶
- Search across documents, notes, or product descriptions.
- JSON documents with nested fields.
- Hybrid filters that combine text search with graph structure.
When To Use¶
Use full-text or JSON search when keyword matching and relevance ranking matter more than exact equality on fields.
See also: Vector Search | Hybrid Search