Search
Query, search, and filter your graph data with powerful engines.
Querying and Search
Three built-in engines for exploring your graph.
QueryEngine
Graph traversal and structural queries.
import { useInferaGraph } from '@inferagraph/core/react';
function PatriarchExplorer() {
const { queryEngine } = useInferaGraph();
const neighbors = queryEngine.getNeighbors('abraham', 2);
const path = queryEngine.findPath('abraham', 'canaan');
const sub = queryEngine.getSubgraph(['abraham', 'isaac', 'jacob']);
return (
<div>
<h2>Abraham's Neighbors</h2>
{neighbors.map(n => <li key={n.id}>{n.id}</li>)}
</div>
);
}SearchEngine
Full-text search with relevance scoring.
import { useInferaGraph } from '@inferagraph/core/react';
import { useState } from 'react';
function BibleSearch() {
const { searchEngine } = useInferaGraph();
const [query, setQuery] = useState('');
const results = searchEngine.search(query);
return (
<div>
<input value={query} onChange={e => setQuery(e.target.value)} />
{results.map(r => <li key={r.nodeId}>{r.nodeId} ({r.score})</li>)}
</div>
);
}FilterEngine
Predicate-based node filtering.
import { useInferaGraph } from '@inferagraph/core/react';
function PatriarchFilter() {
const { filterEngine } = useInferaGraph();
// Find all people from the Patriarchs era
const patriarchs = filterEngine.filter(
(attrs) => attrs.type === 'person' && attrs.era === 'Patriarchs'
);
return (
<ul>
{patriarchs.map(p => <li key={p.id}>{p.id}</li>)}
</ul>
);
}Semantic Search
Add an llm prop and useInferaGraphSearch() auto-detects search mode: short tokens hit the keyword index; sentence-length queries run vector search via embeddings. Same API, the right answer either way.
import { useInferaGraphSearch } from '@inferagraph/core/react';
import { useState } from 'react';
function SmartSearch() {
const { search } = useInferaGraphSearch();
const [results, setResults] = useState([]);
async function go(q) {
// Auto-detect:
// - 'abraham' → keyword
// - 'patriarchs who left their homeland' → semantic
const hits = await search(q);
setResults(hits);
}
}Embedding Storage
Embeddings can be stored at three tiers. Pick what matches your traffic and budget; the API is the same in all three cases.
- No store — keyword-only search, zero embedding calls.
- Cache as store — reuse a CacheProvider for embeddings. Easiest upgrade path.
- Dedicated EmbeddingStore — implement the contract for any vector-native backend. inMemoryEmbeddingStore() ships built-in.
// Tier 1 — no semantic search (keyword only)
<InferaGraph data={data} llm={llm} />
// Tier 2 — bring-your-own-cache (cache as embedding store)
import { lruCache } from '@inferagraph/core/data';
<InferaGraph data={data} llm={llm} cache={lruCache()} />
// Tier 3 — dedicated EmbeddingStore (vector-native backend)
import { inMemoryEmbeddingStore } from '@inferagraph/core/data';
<InferaGraph
data={data}
llm={llm}
embeddingStore={inMemoryEmbeddingStore()}
/>
// Every embedding is stamped with model + version + content hash.
// Unchanged content is never re-embedded.Provenance: every stored embedding carries the model id, version, and a hash of the source content. When content or model changes, the embedding is regenerated; otherwise it's reused indefinitely. See Embeddings for the full contract and per-tier tradeoffs.