Documentation
¶
Overview ¶
Package memgraph provides a store.Store implementation backed by Memgraph, a Bolt-compatible graph database. It uses Cypher queries and the neo4j-go-driver for all persistence operations.
Index ¶
- func BuildEntityVectorIndexDDL(dim int) string
- func BuildMemoryVectorIndexDDL(dim int) string
- func BuildSearchEntitiesCypher() string
- type GraphAdapter
- func (g *GraphAdapter) AppendEpisode(ctx context.Context, factID, episodeID string) error
- func (g *GraphAdapter) AppendMemoryToFact(ctx context.Context, factID, memoryID string) error
- func (g *GraphAdapter) Close() error
- func (g *GraphAdapter) CreateEpisode(ctx context.Context, episode models.Episode) error
- func (g *GraphAdapter) EnsureSchema(ctx context.Context, vectorDim int) error
- func (g *GraphAdapter) GetEntity(ctx context.Context, id string) (*models.Entity, error)
- func (g *GraphAdapter) GetEpisodesForMemory(ctx context.Context, memoryID string) ([]models.Episode, error)
- func (g *GraphAdapter) GetFactsBetween(ctx context.Context, sourceID, targetID string) ([]models.Fact, error)
- func (g *GraphAdapter) GetFactsForEntity(ctx context.Context, entityID string) ([]models.Fact, error)
- func (g *GraphAdapter) GetMemoryFacts(ctx context.Context, memoryID string) ([]models.Fact, error)
- func (g *GraphAdapter) Healthy(ctx context.Context) bool
- func (g *GraphAdapter) InvalidateFact(ctx context.Context, id string, expiredAt, invalidAt time.Time) error
- func (g *GraphAdapter) RecallByGraph(ctx context.Context, query string, embedding []float32, limit int) ([]string, error)
- func (g *GraphAdapter) RecallByGraphWithDepth(ctx context.Context, query string, embedding []float32, limit int, depth int) ([]string, error)
- func (g *GraphAdapter) SearchEntities(ctx context.Context, query string, _ []float32, project string, limit int) ([]graph.EntityResult, error)
- func (g *GraphAdapter) SearchFacts(ctx context.Context, query string, _ []float32, limit int) ([]graph.FactResult, error)
- func (g *GraphAdapter) UpsertEntity(ctx context.Context, entity models.Entity) error
- func (g *GraphAdapter) UpsertFact(ctx context.Context, fact models.Fact) error
- type MemgraphStore
- func (s *MemgraphStore) Close() error
- func (s *MemgraphStore) Delete(ctx context.Context, id string) error
- func (s *MemgraphStore) DeleteAllMemories(ctx context.Context) error
- func (s *MemgraphStore) EnsureCollection(ctx context.Context) error
- func (s *MemgraphStore) FindDuplicates(ctx context.Context, vector []float32, threshold float64) ([]models.SearchResult, error)
- func (s *MemgraphStore) Get(ctx context.Context, id string) (*models.Memory, error)
- func (s *MemgraphStore) GetChain(ctx context.Context, id string) ([]models.Memory, error)
- func (s *MemgraphStore) GetEntity(ctx context.Context, id string) (*models.Entity, error)
- func (s *MemgraphStore) GetHistory(ctx context.Context, id string) ([]models.Memory, error)
- func (s *MemgraphStore) InvalidateMemory(ctx context.Context, id string, validTo time.Time) error
- func (s *MemgraphStore) LinkMemoryToEntity(ctx context.Context, entityID, memoryID string) error
- func (s *MemgraphStore) List(ctx context.Context, filters *store.SearchFilters, limit uint64, cursor string) ([]models.Memory, string, error)
- func (s *MemgraphStore) MigrateTemporalFields(ctx context.Context) error
- func (s *MemgraphStore) Search(ctx context.Context, vector []float32, limit uint64, ...) ([]models.SearchResult, error)
- func (s *MemgraphStore) SearchEntities(ctx context.Context, name, entityType string, limit int) ([]models.Entity, error)
- func (s *MemgraphStore) SetContradictionDetector(d store.ContradictionDetector)
- func (s *MemgraphStore) Stats(ctx context.Context) (*models.CollectionStats, error)
- func (s *MemgraphStore) UpdateAccessMetadata(ctx context.Context, id string) error
- func (s *MemgraphStore) UpdateConflictFields(ctx context.Context, id, conflictGroupID, conflictStatus string) error
- func (s *MemgraphStore) UpdateReinforcement(ctx context.Context, id string, confidenceBoost float64) error
- func (s *MemgraphStore) Upsert(ctx context.Context, memory models.Memory, vector []float32) error
- func (s *MemgraphStore) UpsertEntity(ctx context.Context, entity models.Entity) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BuildEntityVectorIndexDDL ¶ added in v0.10.0
BuildEntityVectorIndexDDL returns the CREATE VECTOR INDEX DDL for entities.
func BuildMemoryVectorIndexDDL ¶ added in v0.10.0
BuildMemoryVectorIndexDDL returns the CREATE VECTOR INDEX DDL for the given dimension. Exported for testing.
func BuildSearchEntitiesCypher ¶ added in v0.10.0
func BuildSearchEntitiesCypher() string
BuildSearchEntitiesCypher returns the Cypher query used by SearchEntities for text search. Exported so that tests in the tests/ package can verify the query uses the correct Memgraph procedure (text_search.search_all) and clause order (WITH before WHERE). Do not call from production code; exported only to satisfy the tests/ package testing convention (tests are black-box and cannot access unexported identifiers).
Fixes:
- Bug 1: Memgraph requires an explicit WITH clause to bridge YIELD and WHERE; WHERE directly after YIELD causes "mismatched input 'WHERE'" parse error.
- Bug 2: text_search.search throws "Unknown exception!" on current Memgraph; text_search.search_all is the correct procedure name.
Types ¶
type GraphAdapter ¶
type GraphAdapter struct {
// contains filtered or unexported fields
}
GraphAdapter wraps MemgraphStore and implements graph.Client. It is needed because graph.Client.SearchEntities has a different signature than store.Store.SearchEntities — Go does not allow two methods with the same name but different signatures on the same struct, so we use this thin adapter for the graph interface. All other methods delegate directly to the underlying MemgraphStore.
func NewGraphAdapter ¶
func NewGraphAdapter(s *MemgraphStore) *GraphAdapter
NewGraphAdapter creates a GraphAdapter that delegates to the given MemgraphStore.
func (*GraphAdapter) AppendEpisode ¶
func (g *GraphAdapter) AppendEpisode(ctx context.Context, factID, episodeID string) error
AppendEpisode adds an episode/session ID to a fact's episodes list.
func (*GraphAdapter) AppendMemoryToFact ¶
func (g *GraphAdapter) AppendMemoryToFact(ctx context.Context, factID, memoryID string) error
AppendMemoryToFact adds a memory ID to a fact's source_memory_ids list.
func (*GraphAdapter) Close ¶
func (g *GraphAdapter) Close() error
Close releases the driver resources. Delegates to MemgraphStore.
func (*GraphAdapter) CreateEpisode ¶ added in v0.8.0
Healthy returns true if the Memgraph database is reachable. CreateEpisode stores an Episode node in Memgraph.
func (*GraphAdapter) EnsureSchema ¶
func (g *GraphAdapter) EnsureSchema(ctx context.Context, vectorDim int) error
EnsureSchema creates indexes, constraints, and vector indexes on Memgraph. Memgraph does not support IF NOT EXISTS on constraints, so "already exists" errors are caught and logged as warnings.
func (*GraphAdapter) GetEntity ¶
GetEntity retrieves a single entity by ID. Delegates to MemgraphStore.
func (*GraphAdapter) GetEpisodesForMemory ¶ added in v0.8.0
func (g *GraphAdapter) GetEpisodesForMemory(ctx context.Context, memoryID string) ([]models.Episode, error)
GetEpisodesForMemory returns all Episode nodes whose memory_ids contain the given memoryID.
func (*GraphAdapter) GetFactsBetween ¶
func (g *GraphAdapter) GetFactsBetween(ctx context.Context, sourceID, targetID string) ([]models.Fact, error)
GetFactsBetween returns all active facts between two entities (bidirectional).
func (*GraphAdapter) GetFactsForEntity ¶
func (g *GraphAdapter) GetFactsForEntity(ctx context.Context, entityID string) ([]models.Fact, error)
GetFactsForEntity returns all active facts involving an entity (as source or target).
func (*GraphAdapter) GetMemoryFacts ¶
GetMemoryFacts returns all facts derived from a given memory ID.
func (*GraphAdapter) InvalidateFact ¶
func (g *GraphAdapter) InvalidateFact(ctx context.Context, id string, expiredAt, invalidAt time.Time) error
InvalidateFact sets ExpiredAt and InvalidAt on a RELATES_TO relationship.
func (*GraphAdapter) RecallByGraph ¶
func (g *GraphAdapter) RecallByGraph(ctx context.Context, query string, embedding []float32, limit int) ([]string, error)
RecallByGraph returns memory IDs relevant to a query via entity-aware graph traversal.
It delegates to RecallByGraphWithDepth with the default depth (2-hop). The function respects the context deadline — callers should wrap ctx with a tight timeout (≤ 120 ms) to stay within the 200 ms total recall latency budget.
func (*GraphAdapter) RecallByGraphWithDepth ¶ added in v0.8.0
func (g *GraphAdapter) RecallByGraphWithDepth(ctx context.Context, query string, embedding []float32, limit int, depth int) ([]string, error)
RecallByGraphWithDepth implements configurable-depth graph-aware recall.
Algorithm (Phase 4 – Graph-Aware Recall):
- Entity discovery: find Entity nodes whose name matches query terms via text search.
- 1-hop traversal: for each discovered entity, follow RELATES_TO edges (both directions) and collect source_memory_ids from adjacent fact relationships.
- 2-hop traversal (depth >= 2): for each neighbor entity found in step 2, repeat the 1-hop traversal to collect transitively connected memory IDs.
Memories found at 1-hop score 1.0; 2-hop memories score 0.5. Returns memory IDs sorted by graph distance score (descending).
func (*GraphAdapter) SearchEntities ¶
func (g *GraphAdapter) SearchEntities(ctx context.Context, query string, _ []float32, project string, limit int) ([]graph.EntityResult, error)
SearchEntities finds entities by text search, optionally filtered by project. This implements graph.Client.SearchEntities (different signature from store.Store.SearchEntities).
func (*GraphAdapter) SearchFacts ¶
func (g *GraphAdapter) SearchFacts(ctx context.Context, query string, _ []float32, limit int) ([]graph.FactResult, error)
SearchFacts performs a text search over RELATES_TO relationships using property-level CONTAINS matching (Memgraph does not support text indexes on edges).
func (*GraphAdapter) UpsertEntity ¶
UpsertEntity creates or updates an Entity node. Delegates to MemgraphStore.
func (*GraphAdapter) UpsertFact ¶
UpsertFact creates or updates a RELATES_TO relationship between two entities.
type MemgraphStore ¶
type MemgraphStore struct {
// contains filtered or unexported fields
}
MemgraphStore implements store.Store using Memgraph (Bolt-compatible).
func New ¶
func New(ctx context.Context, uri, username, password, database string, vectorDim int, logger *slog.Logger) (*MemgraphStore, error)
New creates a new MemgraphStore and verifies connectivity.
func (*MemgraphStore) Close ¶
func (s *MemgraphStore) Close() error
Close releases the driver connection.
func (*MemgraphStore) Delete ¶
func (s *MemgraphStore) Delete(ctx context.Context, id string) error
Delete removes a memory by ID. Returns store.ErrNotFound if nothing was deleted. If id is shorter than 36 characters (a full UUID), prefix matching is used instead of exact matching. If the prefix matches more than one memory, an error is returned.
func (*MemgraphStore) DeleteAllMemories ¶ added in v0.10.0
func (s *MemgraphStore) DeleteAllMemories(ctx context.Context) error
DeleteAllMemories removes all nodes and relationships from the graph. This is intended for eval benchmark isolation only — it is destructive.
Known limitation: `MATCH (n) DETACH DELETE n` runs as a single Bolt transaction. On a large or heavily-indexed graph this can exhaust the Memgraph transaction memory budget and fail even within memgraphDeleteAllTimeout. The eval harness synthetic datasets are small (O(100) nodes per QA pair), so this is safe in practice. For production stores with millions of nodes, batched deletion (WITH n LIMIT N) would be required; tracked in issue #91 alongside the --format json follow-up.
func (*MemgraphStore) EnsureCollection ¶
func (s *MemgraphStore) EnsureCollection(ctx context.Context) error
EnsureCollection creates all indexes, constraints, and vector indexes in Memgraph. Delegates to GraphAdapter.EnsureSchema which runs each DDL statement individually.
func (*MemgraphStore) FindDuplicates ¶
func (s *MemgraphStore) FindDuplicates(ctx context.Context, vector []float32, threshold float64) ([]models.SearchResult, error)
FindDuplicates returns memories whose vector similarity to the given vector is at or above the threshold.
func (*MemgraphStore) GetChain ¶
GetChain follows the supersedes_id chain and returns the full history, newest first. Stops when supersedes_id is empty, the referenced memory is not found, or a cycle is detected.
func (*MemgraphStore) GetHistory ¶ added in v0.8.0
GetHistory returns all versions of a memory chain, including invalidated ones. Uses the SupersedesID chain traversal (newest first).
func (*MemgraphStore) InvalidateMemory ¶ added in v0.8.0
InvalidateMemory sets valid_to on a memory without deleting it. Used when a superseding memory is stored (temporal versioning).
func (*MemgraphStore) LinkMemoryToEntity ¶
func (s *MemgraphStore) LinkMemoryToEntity(ctx context.Context, entityID, memoryID string) error
LinkMemoryToEntity appends a memory ID to an entity's memory_ids list (idempotent).
func (*MemgraphStore) List ¶
func (s *MemgraphStore) List(ctx context.Context, filters *store.SearchFilters, limit uint64, cursor string) ([]models.Memory, string, error)
List returns memories matching the given filters with cursor-based pagination. The cursor is the SKIP offset encoded as a decimal string; "" means page 0.
func (*MemgraphStore) MigrateTemporalFields ¶ added in v0.8.0
func (s *MemgraphStore) MigrateTemporalFields(ctx context.Context) error
MigrateTemporalFields backfills valid_from = created_at for all memories without valid_from. Idempotent — safe to run multiple times.
func (*MemgraphStore) Search ¶
func (s *MemgraphStore) Search(ctx context.Context, vector []float32, limit uint64, filters *store.SearchFilters) ([]models.SearchResult, error)
Search finds memories similar to the query vector using Memgraph's vector search.
func (*MemgraphStore) SearchEntities ¶
func (s *MemgraphStore) SearchEntities(ctx context.Context, name, entityType string, limit int) ([]models.Entity, error)
SearchEntities finds entities whose name contains the given string (case-insensitive). entityType filters by entity type (empty = all types). limit caps the number of results (0 = default 100).
func (*MemgraphStore) SetContradictionDetector ¶ added in v0.8.0
func (s *MemgraphStore) SetContradictionDetector(d store.ContradictionDetector)
SetContradictionDetector attaches a contradiction detector to the store. When set, Upsert will call FindContradictions before inserting and invalidate any memories that contradict the new one. Best-effort: errors are logged, not returned.
func (*MemgraphStore) Stats ¶
func (s *MemgraphStore) Stats(ctx context.Context) (*models.CollectionStats, error)
Stats returns collection statistics including type and scope counts plus health metrics.
func (*MemgraphStore) UpdateAccessMetadata ¶
func (s *MemgraphStore) UpdateAccessMetadata(ctx context.Context, id string) error
UpdateAccessMetadata increments access count and updates last_accessed time.
func (*MemgraphStore) UpdateConflictFields ¶
func (s *MemgraphStore) UpdateConflictFields(ctx context.Context, id, conflictGroupID, conflictStatus string) error
UpdateConflictFields sets ConflictGroupID and ConflictStatus on an existing memory.
func (*MemgraphStore) UpdateReinforcement ¶
func (s *MemgraphStore) UpdateReinforcement(ctx context.Context, id string, confidenceBoost float64) error
UpdateReinforcement boosts the confidence of an existing memory (capped at 1.0) and increments reinforced_count.
func (*MemgraphStore) Upsert ¶
Upsert inserts or updates a memory node with its embedding vector. When memory.SupersedesID is set, the superseded memory is invalidated (valid_to = now).
func (*MemgraphStore) UpsertEntity ¶
UpsertEntity inserts or updates an entity node.