memgraph

package
v0.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 22, 2026 License: MIT Imports: 13 Imported by: 0

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

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildEntityVectorIndexDDL added in v0.10.0

func BuildEntityVectorIndexDDL(dim int) string

BuildEntityVectorIndexDDL returns the CREATE VECTOR INDEX DDL for entities.

func BuildMemoryVectorIndexDDL added in v0.10.0

func BuildMemoryVectorIndexDDL(dim int) string

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

func (g *GraphAdapter) CreateEpisode(ctx context.Context, episode models.Episode) error

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

func (g *GraphAdapter) GetEntity(ctx context.Context, id string) (*models.Entity, error)

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

func (g *GraphAdapter) GetMemoryFacts(ctx context.Context, memoryID string) ([]models.Fact, error)

GetMemoryFacts returns all facts derived from a given memory ID.

func (*GraphAdapter) Healthy

func (g *GraphAdapter) Healthy(ctx context.Context) bool

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):

  1. Entity discovery: find Entity nodes whose name matches query terms via text search.
  2. 1-hop traversal: for each discovered entity, follow RELATES_TO edges (both directions) and collect source_memory_ids from adjacent fact relationships.
  3. 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

func (g *GraphAdapter) UpsertEntity(ctx context.Context, entity models.Entity) error

UpsertEntity creates or updates an Entity node. Delegates to MemgraphStore.

func (*GraphAdapter) UpsertFact

func (g *GraphAdapter) UpsertFact(ctx context.Context, fact models.Fact) error

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) Get

func (s *MemgraphStore) Get(ctx context.Context, id string) (*models.Memory, error)

Get retrieves a single memory by ID.

func (*MemgraphStore) GetChain

func (s *MemgraphStore) GetChain(ctx context.Context, id string) ([]models.Memory, error)

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) GetEntity

func (s *MemgraphStore) GetEntity(ctx context.Context, id string) (*models.Entity, error)

GetEntity retrieves a single entity by ID.

func (*MemgraphStore) GetHistory added in v0.8.0

func (s *MemgraphStore) GetHistory(ctx context.Context, id string) ([]models.Memory, error)

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

func (s *MemgraphStore) InvalidateMemory(ctx context.Context, id string, validTo time.Time) error

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

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

func (s *MemgraphStore) Upsert(ctx context.Context, memory models.Memory, vector []float32) error

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

func (s *MemgraphStore) UpsertEntity(ctx context.Context, entity models.Entity) error

UpsertEntity inserts or updates an entity node.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL