pub struct MemvidStore { /* private fields */ }Expand description
A persistent, file-backed vector / lexical index over a memvid .mv2
archive.
MemvidStore is cheap to clone (it shares an Arc<Mutex<Memvid>> with
every clone) and can be both read from and written to concurrently from
multiple async tasks. Writes are serialised through the inner mutex.
§Concurrency
Every public method on the underlying Memvid handle — including
search, vec_search_with_embedding, frame_count, and the various
put_* writers — takes &mut self. Reads cannot run in parallel with
other reads, so the inner lock is a Mutex rather than an
RwLock. Workloads that require concurrent reads should open separate
read-only handles via MemvidStoreBuilder::open_read_only.
The lock is std::sync::Mutex (not tokio::sync::Mutex): the crate
is intentionally runtime-agnostic and the clippy await_holding_lock
lint enforces that no .await ever happens while a guard is live. Every
guard in this module is scope-dropped before any async boundary.
Unlike most rig vector stores, MemvidStore is not parameterised over
an EmbeddingModel: memvid embeds queries internally using whichever
engine its file is configured with (BM25/Tantivy when the lex feature is
enabled, HNSW + BGE-small when vec is enabled). Pass plain text in
VectorSearchRequest::query and let memvid do the rest.
Implementations§
Source§impl MemvidStore
impl MemvidStore
Sourcepub fn from_memvid(memvid: Memvid) -> Self
pub fn from_memvid(memvid: Memvid) -> Self
Wraps an already-open Memvid handle.
Sourcepub fn frame_count(&self) -> Result<usize, MemvidError>
pub fn frame_count(&self) -> Result<usize, MemvidError>
Number of frames currently stored in the underlying .mv2 file.
Sourcepub fn stats(&self) -> Result<Stats, MemvidError>
pub fn stats(&self) -> Result<Stats, MemvidError>
Aggregate statistics for the underlying memory.
Sourcepub fn builder() -> MemvidStoreBuilder
pub fn builder() -> MemvidStoreBuilder
Begin building a new store. See MemvidStoreBuilder.
Sourcepub fn put_text(
&self,
text: &str,
options: PutOptions,
) -> Result<u64, MemvidError>
pub fn put_text( &self, text: &str, options: PutOptions, ) -> Result<u64, MemvidError>
Append a UTF-8 text payload to the archive and immediately commit.
Returns the assigned frame_id. When the store has been built with
an embedder (vec feature), the text is embedded and stored
alongside its frame so that subsequent
VectorStoreIndex::top_n calls perform semantic search.
Sourcepub fn put_text_uncommitted(
&self,
text: &str,
options: PutOptions,
) -> Result<u64, MemvidError>
pub fn put_text_uncommitted( &self, text: &str, options: PutOptions, ) -> Result<u64, MemvidError>
Append a payload without committing. The caller is responsible for
invoking MemvidStore::commit before a subsequent search will see
the new frame.
Sourcepub fn commit(&self) -> Result<(), MemvidError>
pub fn commit(&self) -> Result<(), MemvidError>
Flush any pending writes to disk.
Sourcepub fn search(
&self,
request: SearchRequest,
) -> Result<SearchResponse, MemvidError>
pub fn search( &self, request: SearchRequest, ) -> Result<SearchResponse, MemvidError>
Run a SearchRequest directly. Useful for callers that need
memvid-native features (cursors, ACL contexts, etc.) that do not map
onto VectorSearchRequest.
§Concurrency
Acquires the store’s inner Mutex for the duration of the call.
Do not invoke this (or any other MemvidStore method) from
within a crate::WriteTransform closure: hook writes already hold
a path through put_text and a re-entrant call would deadlock.
Sourcepub fn memory_card_count(&self) -> Result<usize, MemvidError>
pub fn memory_card_count(&self) -> Result<usize, MemvidError>
Total number of memvid_core::MemoryCards currently stored on
the memories track.
Cards are produced automatically when frames are written with
memvid_core::PutOptions::extract_triplets enabled (the default,
also exposed through crate::MemoryConfig::extract_triplets).
They form a structured Subject-Predicate-Object index over the
underlying free-text frames.
Sourcepub fn all_memory_cards(&self) -> Result<Vec<MemoryCard>, MemvidError>
pub fn all_memory_cards(&self) -> Result<Vec<MemoryCard>, MemvidError>
Snapshot of every memvid_core::MemoryCard currently on the
memories track, cloned to owned values so the inner lock is
released before returning.
Useful for callers that need to filter / sort across the entire
card set (for example
crate::MemoryCardContext’s EntityMentions selection
strategy). Avoid in hot paths against very large archives:
returns one allocation per card.
Sourcepub fn cards_for_query(
&self,
query: &str,
) -> Result<Vec<MemoryCard>, MemvidError>
pub fn cards_for_query( &self, query: &str, ) -> Result<Vec<MemoryCard>, MemvidError>
Cards whose entity mentions appear (case-insensitive,
whole-word) in query. Filters behind the inner mutex so only
matching cards are cloned out, avoiding the full-archive
snapshot that MemvidStore::all_memory_cards performs.
Sourcepub fn put_memory_card(
&self,
card: MemoryCard,
) -> Result<MemoryCardId, MemvidError>
pub fn put_memory_card( &self, card: MemoryCard, ) -> Result<MemoryCardId, MemvidError>
Insert a fully-built memvid_core::MemoryCard onto the memories
track. The card’s id field is overwritten with a freshly assigned
memvid_core::MemoryCardId, which is returned.
Useful for tests, deterministic seeding, or callers that have their own structured-extraction pipeline upstream of memvid’s.
Sourcepub fn entity_memories(
&self,
entity: &str,
) -> Result<Vec<MemoryCard>, MemvidError>
pub fn entity_memories( &self, entity: &str, ) -> Result<Vec<MemoryCard>, MemvidError>
All memory cards associated with entity, returned as owned
values (the underlying lock is released before returning).
Returns an empty Vec if the entity is unknown. Pair with
MemvidStore::current_memory when only the latest non-retracted
value of a single slot is needed.
Sourcepub fn current_memory(
&self,
entity: &str,
slot: &str,
) -> Result<Option<MemoryCard>, MemvidError>
pub fn current_memory( &self, entity: &str, slot: &str, ) -> Result<Option<MemoryCard>, MemvidError>
The most recent non-retracted card for the given entity and
slot, if any. Mirrors
memvid_core::Memvid::get_current_memory.
Sourcepub fn entity_preferences(
&self,
entity: &str,
) -> Result<Vec<MemoryCard>, MemvidError>
pub fn entity_preferences( &self, entity: &str, ) -> Result<Vec<MemoryCard>, MemvidError>
All preference-kind cards for entity, in insertion order.
Sourcepub fn aggregate_memory_slot(
&self,
entity: &str,
slot: &str,
) -> Result<Vec<String>, MemvidError>
pub fn aggregate_memory_slot( &self, entity: &str, slot: &str, ) -> Result<Vec<String>, MemvidError>
Aggregate every distinct value recorded for entity/slot across
all sessions. Useful for slots that legitimately accumulate (lists
of hobbies, places lived in, etc.).
Sourcepub fn memory_timeline(
&self,
entity: &str,
) -> Result<Vec<MemoryCard>, MemvidError>
pub fn memory_timeline( &self, entity: &str, ) -> Result<Vec<MemoryCard>, MemvidError>
Event-kind cards for entity in chronological order.
Sourcepub fn mesh_node_count(&self) -> Result<usize, MemvidError>
pub fn mesh_node_count(&self) -> Result<usize, MemvidError>
Number of entity nodes in the underlying memvid Logic-Mesh.
The Logic-Mesh is memvid’s graph track: typed entity nodes
(memvid_core::MeshNode) connected by relationship edges
(memvid_core::MeshEdge). Populated automatically when frames
are written with NER-style enrichment (controlled by
memvid_core::PutOptions).
Sourcepub fn mesh_edge_count(&self) -> Result<usize, MemvidError>
pub fn mesh_edge_count(&self) -> Result<usize, MemvidError>
Number of relationship edges in the Logic-Mesh.
Sourcepub fn find_entity(&self, name: &str) -> Result<Option<MeshNode>, MemvidError>
pub fn find_entity(&self, name: &str) -> Result<Option<MeshNode>, MemvidError>
Find an entity node by canonical or display name (case-insensitive).
Sourcepub fn frame_entities(
&self,
frame_id: u64,
) -> Result<Vec<MeshNode>, MemvidError>
pub fn frame_entities( &self, frame_id: u64, ) -> Result<Vec<MeshNode>, MemvidError>
All entity nodes mentioned in frame_id. Returns owned values
so the inner lock is released before returning.
Sourcepub fn entities_by_kind(
&self,
kind: EntityKind,
) -> Result<Vec<MeshNode>, MemvidError>
pub fn entities_by_kind( &self, kind: EntityKind, ) -> Result<Vec<MeshNode>, MemvidError>
All entity nodes of the given memvid_core::EntityKind.
Sourcepub fn follow_relationship(
&self,
start: &str,
link_type: &str,
hops: usize,
) -> Result<Vec<FollowResult>, MemvidError>
pub fn follow_relationship( &self, start: &str, link_type: &str, hops: usize, ) -> Result<Vec<FollowResult>, MemvidError>
Traverse the Logic-Mesh starting from start, following edges
of link_type up to hops deep. Wraps
memvid_core::Memvid::follow.
Useful for “who reports to alice’s manager?”-style relationship
queries. Returns the result list directly; callers that want
streaming traversal should call memvid’s logic_mesh() API by
holding their own clone of the inner memvid_core::Memvid
handle.
Trait Implementations§
Source§impl Clone for MemvidStore
impl Clone for MemvidStore
Source§fn clone(&self) -> MemvidStore
fn clone(&self) -> MemvidStore
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for MemvidStore
impl Debug for MemvidStore
Source§impl InsertDocuments for MemvidStore
impl InsertDocuments for MemvidStore
Source§async fn insert_documents<Doc>(
&self,
documents: Vec<(Doc, OneOrMany<Embedding>)>,
) -> Result<(), VectorStoreError>
async fn insert_documents<Doc>( &self, documents: Vec<(Doc, OneOrMany<Embedding>)>, ) -> Result<(), VectorStoreError>
Persist documents into the underlying .mv2 file.
Note: caller-supplied embeddings are intentionally ignored.
On the lex-only path the document JSON is written as bytes and
embeddings are dropped. When this store is configured with a
local embedder (vec feature) every document is re-embedded
with that model so memvid’s vector index stays consistent with its
bound model identifier.
Source§impl MemoryGraph for MemvidStore
impl MemoryGraph for MemvidStore
Source§type Error = MemvidError
type Error = MemvidError
rig::vector_store::VectorStoreError when used with an
adapter that exposes a rig::vector_store::VectorStoreIndex
(such as crate::MemoryCardContext).Source§fn memory_card_count(&self) -> Result<usize, Self::Error>
fn memory_card_count(&self) -> Result<usize, Self::Error>
Source§fn all_memory_cards(&self) -> Result<Vec<MemoryCard>, Self::Error>
fn all_memory_cards(&self) -> Result<Vec<MemoryCard>, Self::Error>
Source§fn entity_memories(&self, entity: &str) -> Result<Vec<MemoryCard>, Self::Error>
fn entity_memories(&self, entity: &str) -> Result<Vec<MemoryCard>, Self::Error>
entity. Empty Vec for unknown entities.Source§fn current_memory(
&self,
entity: &str,
slot: &str,
) -> Result<Option<MemoryCard>, Self::Error>
fn current_memory( &self, entity: &str, slot: &str, ) -> Result<Option<MemoryCard>, Self::Error>
entity/slot, if any.Source§fn entity_preferences(
&self,
entity: &str,
) -> Result<Vec<MemoryCard>, Self::Error>
fn entity_preferences( &self, entity: &str, ) -> Result<Vec<MemoryCard>, Self::Error>
entity.Source§fn memory_timeline(&self, entity: &str) -> Result<Vec<MemoryCard>, Self::Error>
fn memory_timeline(&self, entity: &str) -> Result<Vec<MemoryCard>, Self::Error>
entity in chronological order.Source§fn cards_for_query(&self, query: &str) -> Result<Vec<MemoryCard>, Self::Error>
fn cards_for_query(&self, query: &str) -> Result<Vec<MemoryCard>, Self::Error>
entity mentions appear in query (case-insensitive
whole-word match). The default implementation snapshots the entire
archive via MemoryGraph::all_memory_cards and filters in pure
Rust, which is correct but clones every card; backends backed by a
graph store should override this to filter behind their own
locking / indexing and avoid the intermediate full-archive
allocation.Source§impl VectorStoreIndex for MemvidStore
impl VectorStoreIndex for MemvidStore
Source§async fn top_n<T>(
&self,
req: VectorSearchRequest<Self::Filter>,
) -> Result<Vec<(f64, String, T)>, VectorStoreError>where
T: for<'a> Deserialize<'a> + WasmCompatSend,
async fn top_n<T>(
&self,
req: VectorSearchRequest<Self::Filter>,
) -> Result<Vec<(f64, String, T)>, VectorStoreError>where
T: for<'a> Deserialize<'a> + WasmCompatSend,
Run a search and deserialise each hit’s JSON representation into T.
§Contract
The type T must be deserialisable from a SearchHit JSON object —
i.e. either T = SearchHit itself, or a struct whose fields are a
subset of SearchHit’s public fields (frame_id, text, score,
metadata, …). Use serde_json::Value for an opaque view.
This method does not round-trip user-defined document types.
If you persisted JSON documents through InsertDocuments and want
them back, use VectorStoreIndex::top_n_ids for the frame ids and
then MemvidStore::search for full-fidelity access via the
memvid-native SearchRequest API.
§Example
use memvid_core::SearchHit;
use rig::vector_store::{
VectorSearchRequest, VectorStoreIndex,
request::VectorSearchRequestBuilder,
};
use rig_memvid::{MemvidFilter, MemvidStore};
let req: VectorSearchRequest<MemvidFilter> =
VectorSearchRequestBuilder::<MemvidFilter>::default()
.query("hello")
.samples(5)
.build();
let hits: Vec<(f64, String, SearchHit)> = store.top_n(req).await?;Source§type Filter = MemvidFilter
type Filter = MemvidFilter
Source§async fn top_n_ids(
&self,
req: VectorSearchRequest<Self::Filter>,
) -> Result<Vec<(f64, String)>, VectorStoreError>
async fn top_n_ids( &self, req: VectorSearchRequest<Self::Filter>, ) -> Result<Vec<(f64, String)>, VectorStoreError>
(score, id) tuples.Auto Trait Implementations§
impl Freeze for MemvidStore
impl RefUnwindSafe for MemvidStore
impl Send for MemvidStore
impl Sync for MemvidStore
impl Unpin for MemvidStore
impl UnsafeUnpin for MemvidStore
impl UnwindSafe for MemvidStore
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
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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
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> 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 moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<T, F> Tool for Twhere
F: SearchFilter<Value = Value> + WasmCompatSend + WasmCompatSync + for<'de> Deserialize<'de>,
T: VectorStoreIndex<Filter = F>,
impl<T, F> Tool for Twhere
F: SearchFilter<Value = Value> + WasmCompatSend + WasmCompatSync + for<'de> Deserialize<'de>,
T: VectorStoreIndex<Filter = F>,
Source§const NAME: &'static str = "search_vector_store"
const NAME: &'static str = "search_vector_store"
ToolSet or other registration scope that dispatches tools by name.