search

package
v0.11.0 Latest Latest
Warning

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

Go to latest
Published: Jun 19, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package search adds vector (sqlite-vec), full-text (FTS5), and hybrid (reciprocal-rank-fusion) search to liteorm's SQLite backend, over the typed surface of the sibling driver gosqlite.org. It is SQLite-specific and capability-gated: every constructor takes a liteorm.Session opened by liteorm.org/dialect/sqlite and returns ErrUnsupportedBackend for any other dialect.

Indexes are keyed by your model's int64 primary key — the canonical recipe is "your table owns the rows, the sidecar index owns the embeddings/terms, the primary key ties them together." A search returns ranked keys (or scored keys); Fetch fetches the model rows by key, preserving rank order. Hybrid runs a vector KNN and a full-text query and fuses the two rankings with reciprocal-rank-fusion.

Index

Constants

View Source
const (
	L2      = vec.L2
	Cosine  = vec.Cosine
	L1      = vec.Dot
	Hamming = vec.Hamming
)

Variables

View Source
var ErrUnsupportedBackend = errors.New("liteorm/search: session is not a SQLite database opened by dialect/sqlite")

ErrUnsupportedBackend is returned by a constructor when the session was not opened by liteorm.org/dialect/sqlite (the advanced features are SQLite-only).

Functions

func Fetch added in v0.9.0

func Fetch[T any](ctx context.Context, sess liteorm.Session, keys []int64) ([]T, error)

Fetch fetches model rows of type T by primary key, preserving the ranked order of the supplied keys. Missing keys are skipped. T must be a model the query front-end can address (a TableName and an int64 primary key). It issues one Get per key, which is the right shape for the small top-k slices search returns.

func FetchScored added in v0.9.0

func FetchScored[T any](ctx context.Context, sess liteorm.Session, scored []Scored) ([]T, error)

FetchScored is Fetch over the keys of a scored result set (Vector.SearchScored or Hybrid), preserving order.

Types

type CorrectOption added in v0.10.0

type CorrectOption = spellfix1.CorrectOption

CorrectOption bounds a Correct search.

func WithLimit added in v0.10.0

func WithLimit(n int) CorrectOption

WithLimit caps the number of returned corrections (SQL LIMIT).

func WithMaxDistance added in v0.10.0

func WithMaxDistance(n int) CorrectOption

WithMaxDistance caps the edit distance of returned corrections (default 4).

type Correction added in v0.10.0

type Correction = spellfix1.Match

Correction is one fuzzy match: a vocabulary word and how far it is from the query term (Damerau-Levenshtein distance; smaller is closer).

type FullText

type FullText struct {
	// contains filtered or unexported fields
}

FullText is an FTS5 index over a single text column, keyed by your model's int64 primary key.

func NewFullText

func NewFullText(ctx context.Context, sess liteorm.Session, name string) (*FullText, error)

NewFullText creates (idempotently) or opens an FTS5 index. The default unicode61 tokenizer and BM25 ranking are used.

func OpenFullText added in v0.9.0

func OpenFullText(sess liteorm.Session, name string, cols ...string) (*FullText, error)

OpenFullText attaches to an existing FTS5 sidecar (no CREATE) given its indexed columns — the read-path counterpart to NewFullText for the external-content tables AutoMigrate provisions.

func (*FullText) Add

func (f *FullText) Add(ctx context.Context, key int64, text string) error

Add indexes text under a model key. Re-adding the same key replaces it.

func (*FullText) Search

func (f *FullText) Search(ctx context.Context, q Query, k int) ([]int64, error)

Search returns up to k model keys matching the query, best (BM25) rank first.

func (*FullText) SearchScored added in v0.9.0

func (f *FullText) SearchScored(ctx context.Context, q Query, k int) ([]Scored, error)

SearchScored runs a full-text query and returns each matching key with its BM25 rank (the scored counterpart of FullText.Search).

type Hit added in v0.9.0

type Hit[T any] struct {
	Model T
	// Score's meaning depends on the search: vector distance (smaller is nearer)
	// for Vector, BM25 rank for FullText, and the reciprocal-rank-fusion score
	// (larger is better) for Hybrid.
	Score float64
}

Hit is one search result: the loaded model and its relevance score.

type Metric

type Metric = vec.Metric

Metric mirrors gosqlite/vec's distance functions. Cosine is the usual choice for normalized text embeddings; L2 is the default; L1 is Manhattan; Hamming applies to bit vectors.

type Option

type Option = fusion.Option

Option tunes reciprocal rank fusion (e.g. WithK, WithWeights).

func WithK

func WithK(k float64) Option

WithK overrides the RRF damping constant (default 60).

func WithWeights

func WithWeights(weights ...float64) Option

WithWeights weights the vector and full-text rankings, in that order.

type Query

type Query = fts.Query

Full-text query builders, re-exported so callers need not import gosqlite/fts.

func And

func And(qs ...Query) Query

func Column

func Column(name string, q Query) Query

func Near

func Near(distance int, terms ...string) Query

func Not

func Not(positive Query, negatives ...Query) Query

func Or

func Or(qs ...Query) Query

func Phrase

func Phrase(tokens ...string) Query

func Prefix

func Prefix(s string) Query

func Raw

func Raw(s string) Query

func Term

func Term(s string) Query

type Scored

type Scored struct {
	Key   int64
	Score float64
}

Scored is one ranked result: a model primary key and its score. For Vector the score is the raw distance (smaller is nearer); for Hybrid it is the reciprocal-rank-fusion score (larger is better). Each search documents which.

func Hybrid

func Hybrid(ctx context.Context, v *Vector, f *FullText, embedding []float32, q Query, k int, opts ...Option) ([]Scored, error)

Hybrid runs a vector KNN and a full-text query, then fuses the two rankings with reciprocal rank fusion (RRF). The result is ordered by descending fusion score (larger is better) and capped at k. RRF lets a key that ranks well in either modality surface, while one that ranks well in both surfaces highest — without tuning a brittle score-scale blend.

type Searcher added in v0.9.0

type Searcher[T any] struct {
	// contains filtered or unexported fields
}

Searcher runs schema-aware searches for model T against its declared indexes, returning loaded models in ranked order. Build one with For.

func For added in v0.9.0

func For[T any](sess liteorm.Session) *Searcher[T]

For begins a search for model T over sess. The sidecar tables, dimension, metric, and columns all come from T's declared search indexes:

hits, err := search.For[Article](db).Vector(ctx, queryVec, 5)

func (*Searcher[T]) Field added in v0.9.0

func (s *Searcher[T]) Field(name string) *Searcher[T]

Field selects which index to use when the model declares more than one of the same kind, naming the model field the index covers. Returns a new Searcher.

func (*Searcher[T]) FullText added in v0.9.0

func (s *Searcher[T]) FullText(ctx context.Context, q Query, k int) ([]Hit[T], error)

FullText runs a full-text search over T's FTS index, best (BM25) rank first. Soft-deleted models are excluded.

func (*Searcher[T]) Hybrid added in v0.9.0

func (s *Searcher[T]) Hybrid(ctx context.Context, query []float32, q Query, k int, fuse ...Option) ([]Hit[T], error)

Hybrid runs a vector and a full-text search over T's indexes and fuses the rankings with reciprocal rank fusion (larger score is better). Soft-deleted models are excluded. The RRF tuning options (WithK, WithWeights) pass via fuse.

func (*Searcher[T]) Vector added in v0.9.0

func (s *Searcher[T]) Vector(ctx context.Context, query []float32, k int) ([]Hit[T], error)

Vector runs a nearest-neighbour search over T's vector index, nearest first. Soft-deleted models are excluded.

type Spellfix added in v0.10.0

type Spellfix struct {
	// contains filtered or unexported fields
}

Spellfix is a spellfix1 fuzzy-match vocabulary — a "did you mean…" word list you populate with words and query for the nearest spelling corrections by edit distance. Unlike Vector and FullText it is not keyed by a model primary key: it is a standalone vocabulary, not a per-row sidecar. Importing this package registers the spellfix1 module, so a Spellfix works with no extra wiring; every step is typed, so callers never hand-write the vocabulary's SQL.

func NewSpellfix added in v0.10.0

func NewSpellfix(ctx context.Context, sess liteorm.Session, name string) (*Spellfix, error)

NewSpellfix creates (idempotently — no error if it already exists) or opens a spellfix1 vocabulary named `name` on the session.

func OpenSpellfix added in v0.10.0

func OpenSpellfix(sess liteorm.Session, name string) (*Spellfix, error)

OpenSpellfix returns a handle to an existing spellfix1 vocabulary without creating it (no I/O; a missing table surfaces at first use).

func (*Spellfix) Add added in v0.10.0

func (s *Spellfix) Add(ctx context.Context, words ...string) error

Add inserts words into the vocabulary in a single transaction; duplicates are ignored (the vocabulary is a set).

func (*Spellfix) Correct added in v0.10.0

func (s *Spellfix) Correct(ctx context.Context, term string, opts ...CorrectOption) ([]Correction, error)

Correct returns the vocabulary words closest to term, nearest (smallest edit distance) first. Bound the search with WithMaxDistance / WithLimit.

func (*Spellfix) Drop added in v0.10.0

func (s *Spellfix) Drop(ctx context.Context) error

Drop deletes the vocabulary table; the handle is unusable afterward.

func (*Spellfix) Name added in v0.10.0

func (s *Spellfix) Name() string

Name returns the vocabulary's table name.

func (*Spellfix) Size added in v0.10.0

func (s *Spellfix) Size(ctx context.Context) (int64, error)

Size reports the number of distinct words in the vocabulary.

type Vector

type Vector struct {
	// contains filtered or unexported fields
}

Vector is a sqlite-vec virtual table of fixed-dimension embeddings, keyed by your model's int64 primary key (stored as the vec rowid).

func NewVector

func NewVector(ctx context.Context, sess liteorm.Session, name string, dim int, metric Metric) (*Vector, error)

NewVector creates (idempotently — CREATE VIRTUAL TABLE IF NOT EXISTS) or opens a sqlite-vec table of the given dimension and distance metric.

func OpenVector added in v0.9.0

func OpenVector(sess liteorm.Session, name string, dim int, metric Metric) (*Vector, error)

OpenVector attaches to an existing vec0 sidecar (no CREATE), the shape AutoMigrate provisions — the read-path counterpart to NewVector.

func (*Vector) Add

func (v *Vector) Add(ctx context.Context, key int64, embedding []float32) error

Add upserts the embedding for a model key. Re-adding the same key replaces it.

func (*Vector) Search

func (v *Vector) Search(ctx context.Context, query []float32, k int) ([]int64, error)

Search returns the k nearest model keys to the query embedding, nearest first.

func (*Vector) SearchScored

func (v *Vector) SearchScored(ctx context.Context, query []float32, k int) ([]Scored, error)

SearchScored is Search but also reports each neighbour's raw distance (smaller is nearer).

Jump to

Keyboard shortcuts

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