class

Engram::Search

Inherits Reference < Object

Ranks the memories materialized in a Store's SQLite cache: FTS5 bm25 full-text search blended with a recency boost, optionally fused with brute-force cosine similarity over embeddings (Reciprocal Rank Fusion) when both an embedder and stored embeddings are available.

Store deliberately exposes only CRUD (no raw FTS5/bm25 query surface), so Search opens its own independent connection to the same sqlite file — the pattern spec/store_spec.cr already establishes with its raw_match helper. Point Search.new at the same db_path used to build the Store.

Constants

RECENCY_WEIGHT = 1.0

Recency boost weight: recency_boost = w * (id - oldest) / (newest - oldest) (spec-mandated, w = 1.0).

RRF_K = 60

Reciprocal Rank Fusion smoothing constant (spec-mandated).

SNIPPET_LENGTH = 160

Characters kept in a snippet before truncation.

Constructors

new(db_path : String, embedder : Embedder | Nil = nil)

Opens a connection to the sqlite database at db_path (already created and populated via Store + sync). embedder, if given, turns query text into a query embedding for cosine/RRF blending; omit it to search FTS5-only.

Source

Instance methods

close

Closes the underlying database connection.

Source
recent(topic : String | Nil = nil, limit : Int32 = 10, include_superseded : Bool = false) : Array(SearchResult)

Newest-first memories, optionally filtered by topic. Superseded memories are excluded unless include_superseded is true. score on each result is its recency boost.

Source
search(query : String, topic : String | Nil = nil, limit : Int32 = 10, include_superseded : Bool = false) : Array(SearchResult)

Full-text search over memories: bm25-ranked and recency-boosted, and RRF-fused with cosine similarity over embeddings when the store has them and an embedder was supplied. A blank/whitespace query degrades to newest-first (like recent); a non-blank query with no matchable token (e.g. all-CJK, pure punctuation) returns no matches. Superseded memories are excluded unless include_superseded is true.

Source

Nested types