search

package
v0.104.0 Latest Latest
Warning

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

Go to latest
Published: Oct 18, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package search is ContentKit's keyword retrieval over content_search_documents: exact names and aliases, literal substrings, prefixes and bounded typos for every language, with eligibility applied inside every indexed route.

Index

Constants

View Source
const MaxCandidateLimit = 10_000

MaxCandidateLimit bounds one route's document window.

Variables

View Source
var ErrInvalidQuery = errors.New("search: invalid query")

ErrInvalidQuery is a request query beyond retrieval's size/token bounds.

Functions

func DeleteKeywordDocuments

func DeleteKeywordDocuments(ctx context.Context, db Executor, schema string, keys []DocumentKey) error

DeleteKeywordDocuments removes the documents; unknown keys are ignored.

func EligibilityJoin

func EligibilityJoin(e *Eligibility, args pgx.NamedArgs) (join, priority string, err error)

EligibilityJoin renders the eligibility query as the lateral join every route applies to a candidate row aliased sd, binding its named args. It returns the join clause (empty without eligibility) and the priority expression to select.

func MarkDirty

func MarkDirty(ctx context.Context, db Executor, schema string, marks []DirtyMark) error

MarkDirty queues documents for the worker, in the transaction that changes their records; the queue trigger assigns each row a new revision.

func QuoteSchema

func QuoteSchema(schema string) (string, error)

QuoteSchema validates and quotes a schema identifier for embedding in SQL.

func UpsertKeywordDocuments

func UpsertKeywordDocuments(ctx context.Context, db Executor, schema string, docs []KeywordDocument) error

UpsertKeywordDocuments derives every lexical projection from structured input for a batch of documents of any tenant, kind or language.

Types

type Candidate

type Candidate struct {
	contentref.ContentRef
	Language string
	Score    float32
}

Candidate is one document proposed by another retrieval source.

type DirtyMark

type DirtyMark struct {
	DocumentKey
	Deleted bool
	Reason  string
}

DirtyMark asks the worker to rebuild (or delete) one document.

type DocumentKey

type DocumentKey struct {
	contentref.ContentRef
	Language string
}

DocumentKey identifies one keyword document: a content reference in one language. The language is metadata of the document, never of the content.

type Eligibility

type Eligibility struct {
	SQL  string
	Args map[string]any
}

Eligibility is ContentKit's own SQL (the discovery routes' rendering of the visibility rule) joined laterally to every candidate document (alias sd: tenant_id, content_kind, content_id, content_version_id, language). It returns no row when the document is not eligible for this request, or one row with the column priority (integer: preferred document among a content item's equal matches, lower first). Ownership, access, publication and every requested version trait must hold on that one row; sibling documents never make each other eligible.

type Executor

type Executor interface {
	Exec(context.Context, string, ...any) (pgconn.CommandTag, error)
}

Executor lets a pool or a transaction own document and queue writes.

type Hit

type Hit struct {
	contentref.ContentRef
	Language string
	// Priority orders same-item documents at equal match; lower is preferred.
	Priority int32
	Score    float32
}

Hit is one matched document.

func Eligible

func Eligible(ctx context.Context, pool *pgxpool.Pool, opts Options, candidates []Candidate) ([]Hit, error)

Eligible returns the candidates that exist as documents of the request tenant and language and pass the eligibility join, in their input order with Priority filled. Candidates another source proposes are never trusted with eligibility: this is the same join every keyword route runs.

type IndexRetirement added in v0.104.0

type IndexRetirement struct {
	Validated []string
	Dropped   []string
	Absent    []string
}

IndexRetirement reports one retirement pass: the replacement indexes it validated and the superseded objects it dropped or found already gone.

func RetireLegacyIndexes added in v0.104.0

func RetireLegacyIndexes(ctx context.Context, pool *pgxpool.Pool, schema string, legacyWritersStopped bool) (IndexRetirement, error)

RetireLegacyIndexes removes four superseded search indexes and their two wrappers after every legacy reader/writer has stopped. This is an explicit operator action, never a migration/startup step. Replacement indexes must be healthy; unexpected tracked SQL dependencies prevent any planned drops. The identity normalizer and all current search/management indexes remain untouched.

Drops are concurrent and individually committed, so a canceled/failed pass is safe to retry. Use an operator pool with DDL authority and a bounded ctx.

type KeywordDocument

type KeywordDocument struct {
	DocumentKey
	Title    string
	Aliases  []string
	Keywords []string
}

KeywordDocument is the search input for one document, built by ContentKit from its own records. Derived search text belongs to ContentKit; callers never write it. An empty Title deletes the document. Aliases are alternate names; Keywords are contextual terms (for example trusted tags), not descriptions.

func (KeywordDocument) Validate added in v0.58.4

func (d KeywordDocument) Validate() error

Validate checks a document before it crosses into the keyword index. An empty title is a deletion, so only its key needs validation.

type NameSource added in v0.104.0

type NameSource uint8

NameSource is a trusted indexed source, never a request-supplied relation.

const (
	PublishedNames NameSource = iota
	CurrentContentNames
	CurrentEntityNames
)

type Options

type Options struct {
	Schema   string
	Tenant   string
	Language string
	// ContentKinds limits the kinds searched; empty means every kind.
	ContentKinds []string
	Limit        int

	// Eligibility binds pgx '@name' placeholders other than the reserved
	// tenant, language, q, prefix, contains, limit, kinds and candidates.
	Eligibility *Eligibility
}

Options selects one tenant, language and window of a keyword request.

type RRFContribution

type RRFContribution struct {
	ListIndex    int     `json:"list_index"` // zero-based source-list index
	Rank         int     `json:"rank"`       // one-based rank within the source list
	Weight       float32 `json:"weight"`
	Contribution float32 `json:"contribution"`
}

type RRFHit

type RRFHit struct {
	RRFKey
	Score float32
}

func FuseRRF

func FuseRRF(lists [][]RRFKey, opts RRFOptions) []RRFHit

FuseRRF fuses multiple ranked lists (best-first) into one ranked list.

type RRFKey

type RRFKey struct {
	contentref.ContentKey
	Language string
}

RRFKey identifies one document across fused lists.

type RRFOptions

type RRFOptions struct {
	// K is the stabilizer constant; higher K flattens rank differences.
	// Defaults to 60 when <= 0.
	K int
	// Finite weights apply to each list; missing weights default to 1.
	// Zero excludes a list. Negative weights subtract its contributions.
	Weights []float32
}

RRF (Reciprocal Rank Fusion) combines ranked lists without relying on raw score calibration: score(doc) = Σ weight_i / (k + rank_i), rank 1-based.

type RRFTraceHit

type RRFTraceHit struct {
	Hit           RRFHit            `json:"-"`
	Key           RRFTraceKey       `json:"key"`
	Score         float32           `json:"score"`
	Contributions []RRFContribution `json:"contributions"`
}

func FuseRRFWithTrace

func FuseRRFWithTrace(lists [][]RRFKey, opts RRFOptions) ([]RRFTraceHit, error)

FuseRRFWithTrace returns the same ordered hits as FuseRRF plus the exact source-list contributions used to compute each score.

type RRFTraceKey

type RRFTraceKey struct {
	TenantID         string `json:"tenant_id"`
	ContentKind      string `json:"content_kind"`
	ContentID        string `json:"content_id"`
	ContentVersionID string `json:"content_version_id,omitempty"`
	Language         string `json:"language"`
}

type Result

type Result struct {
	// Hits are documents ordered by score, content kind, content id and version.
	Hits []Hit
	// Truncated reports that a route filled its SQL window or that more scored
	// documents existed than Limit: documents beyond the window were never ranked.
	Truncated bool
}

Result is one language's scored document window.

func KeywordSearch

func KeywordSearch(ctx context.Context, pool *pgxpool.Pool, query string, opts Options) (Result, error)

KeywordSearch preserves names and aliases, including native scripts. Exact names precede aliases, name prefixes/substrings, contextual token matches, then conservative one-edit typos. Common English fillers are search-only normalization, never entity identity normalization. PostgreSQL retrieves bounded candidates; Go never scans the document catalog. The eligibility join runs inside every route before its limit.

func NameSearch added in v0.104.0

func NameSearch(ctx context.Context, pool *pgxpool.Pool, query string, opts Options) (Result, error)

NameSearch matches literal substrings of a document's own title or aliases. Exact names and prefixes precede interior matches. Contextual keywords and typos belong to KeywordSearch. Every indexed retrieval applies eligibility before its bounded limit; no catalog is scanned in Go.

func NameSearchFrom added in v0.104.0

func NameSearchFrom(ctx context.Context, pool *pgxpool.Pool, query string, opts Options, source NameSource) (Result, error)

NameSearchFrom uses the same literal matcher against current management names in every language. Management callers must supply their authorization as Eligibility; the requested display language does not hide editable names.

Jump to

Keyboard shortcuts

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