pub struct SearchEngine { /* private fields */ }Expand description
The full-text search engine backed by Tantivy.
Implementations§
Source§impl SearchEngine
impl SearchEngine
Sourcepub fn open(path: impl AsRef<Path>) -> Result<Self>
pub fn open(path: impl AsRef<Path>) -> Result<Self>
Create or open a search engine index at the given path.
Sourcepub fn open_readonly(path: impl AsRef<Path>) -> Result<Self>
pub fn open_readonly(path: impl AsRef<Path>) -> Result<Self>
Open the index in read-only mode: no writer is created, so no exclusive tantivy lock is taken. Multiple processes (e.g. Antigravity’s proxy and an opencode MCP client) can share the store for searches; writes through this engine fail with a clear error.
Sourcepub const fn schema_migrated(&self) -> bool
pub const fn schema_migrated(&self) -> bool
True when the on-disk index had an incompatible schema and was
replaced with a fresh empty index at open time. The old index was
preserved as a .schema-mismatch.<timestamp> sibling directory.
Callers that own the canonical LMDB store should rebuild via
reindex::rebuild_index when this returns true.
Sourcepub const fn health(&self) -> &IndexHealth
pub const fn health(&self) -> &IndexHealth
Returns a snapshot of index health (success/failure counts, degraded flag, last error).
Sourcepub fn count_docs_in_galaxy(&self, galaxy: &str) -> Result<usize>
pub fn count_docs_in_galaxy(&self, galaxy: &str) -> Result<usize>
Count the number of indexed documents for a specific galaxy.
Used by consistency checks to compare Tantivy doc counts against LMDB memory counts. Returns 0 if the index is empty or the galaxy has no documents.
Sourcepub fn indexed_ids_in_galaxy(&self, galaxy: &str) -> Result<HashSet<String>>
pub fn indexed_ids_in_galaxy(&self, galaxy: &str) -> Result<HashSet<String>>
Enumerate the memory IDs currently indexed for one galaxy.
Used by the incremental drift heal to diff the index against LMDB
without rebuilding whole galaxies. Bounded by the galaxy’s own
document count (a term query on the non-tokenized galaxy field, so
the cost is one term seek + one stored-field fetch per hit).
Sourcepub fn is_readonly(&self) -> bool
pub fn is_readonly(&self) -> bool
True when the engine was opened read-only (no tantivy writer).
Sourcepub fn writer(&self) -> Result<MutexGuard<'_, Option<IndexWriter>>>
pub fn writer(&self) -> Result<MutexGuard<'_, Option<IndexWriter>>>
Lock the shared writer for adding/removing documents.
The writer is created at open() time and shared across all callers
via a Mutex, preventing lock contention with Tantivy’s single-writer model.
In read-only mode this errors.
Sourcepub fn add_document(
&self,
writer: &mut Option<IndexWriter>,
memory_id: &str,
galaxy: &str,
content: &str,
tags: &[String],
timestamp: i64,
) -> Result<()>
pub fn add_document( &self, writer: &mut Option<IndexWriter>, memory_id: &str, galaxy: &str, content: &str, tags: &[String], timestamp: i64, ) -> Result<()>
Index a memory document.
Content that is not clean text (binary garbage, low printable-char
ratio, null bytes) is skipped at index time — no document is added
and Ok(()) is returned so callers can proceed. See
sanitize_content_for_index.
Sourcepub fn index_memory(
&self,
writer: &mut Option<IndexWriter>,
mem: &Memory,
) -> Result<()>
pub fn index_memory( &self, writer: &mut Option<IndexWriter>, mem: &Memory, ) -> Result<()>
Index a complete Memory entry.
Sourcepub fn delete_document(
&self,
writer: &mut Option<IndexWriter>,
memory_id: &str,
) -> Result<()>
pub fn delete_document( &self, writer: &mut Option<IndexWriter>, memory_id: &str, ) -> Result<()>
Delete documents by memory ID.
Sourcepub fn delete_by_galaxy(
&self,
writer: &mut Option<IndexWriter>,
galaxy: &str,
) -> Result<()>
pub fn delete_by_galaxy( &self, writer: &mut Option<IndexWriter>, galaxy: &str, ) -> Result<()>
Delete every document belonging to a galaxy.
Used by filtered reindexing so --galaxy codex removes only codex
documents instead of wiping the entire index.
Sourcepub fn commit(&self, writer: &mut Option<IndexWriter>) -> Result<()>
pub fn commit(&self, writer: &mut Option<IndexWriter>) -> Result<()>
Commit pending index changes and reload the reader.
Sourcepub fn search(&self, query: &str, limit: usize) -> Result<Vec<SearchResult>>
pub fn search(&self, query: &str, limit: usize) -> Result<Vec<SearchResult>>
Search for memories matching the query text. Returns results sorted by BM25 score (descending).
The query is stripped of stopwords and sanitized to prevent Tantivy query syntax injection.
Sourcepub fn search_in_galaxy(
&self,
query: &str,
galaxy: Option<Galaxy>,
limit: usize,
) -> Result<Vec<SearchResult>>
pub fn search_in_galaxy( &self, query: &str, galaxy: Option<Galaxy>, limit: usize, ) -> Result<Vec<SearchResult>>
Search for memories matching the query, optionally filtered by galaxy.
The query is stripped of stopwords and sanitized to escape Tantivy special characters (+, -, *, “”, field syntax, boolean operators) that could be used for query injection.
Sourcepub fn search_opt(
&self,
query: &str,
opts: &SearchOptions,
) -> Result<Vec<SearchResult>>
pub fn search_opt( &self, query: &str, opts: &SearchOptions, ) -> Result<Vec<SearchResult>>
Search with full recall-quality options (stopword stripping, score thresholds, token-coverage filtering, galaxy filter).
Pipeline:
strip_stopwords— common English stopwords are removed.sanitize_tantivy_query— reserved query syntax is neutralized; plain terms (incl. hyphenated compounds) pass through so the tokenizer can split them into phrase matches.- OR query across
content+tags(broader recall than conjunction, filtered by token-coverage in step 5). - Hits below
min_score(absolute) orrelative_floor * top_scoreare dropped. - Token-coverage floor: for queries with ≥ 3 terms, at least 2 must appear in the content (stemming-aware). Documents that pass the floor receive a coverage-ratio score boost.
- Output content is scrubbed of control characters.
Auto Trait Implementations§
impl !Freeze for SearchEngine
impl !RefUnwindSafe for SearchEngine
impl !UnwindSafe for SearchEngine
impl Send for SearchEngine
impl Sync for SearchEngine
impl Unpin for SearchEngine
impl UnsafeUnpin for SearchEngine
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
impl<T> Fruit for T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more