search

package
v1.15.0 Latest Latest
Warning

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

Go to latest
Published: Nov 12, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package search is full-text search for an app's data and content: in SQLite with FTS5, in PostgreSQL with tsvector and a GIN index, or in memory, for content collections and other data that fits in it.

An index has fields, such as a title and a body, and documents with an ID, a scope and a value for each field:

idx, err := search.New(db, "links", search.Options{
	Fields: []search.Field{{Name: "title", Boost: 2}, {Name: "url"}},
})
err = idx.Migrate(ctx)
err = idx.Put(ctx, search.Doc{ID: "42", Scope: "user:7", Fields: map[string]string{"title": "Go 1.26", "url": "https://go.dev"}})
res, err := idx.Search(ctx, search.Query{Text: "go", Scope: "user:7"})

Searches match words as typed, as prefixes of words in the documents, so results come in while someone types, and rank them with BM25 (SQLite and memory) or ts_rank (PostgreSQL). Each hit has highlighted snippets of its fields, as segments of text rather than HTML. Tern UI's SearchBox shows them.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Text

func Text(html string) string

Text is the text of an HTML document or fragment, such as a content entry's HTML, without its tags, for indexing.

func Words

func Words(text string) []string

Words splits text into lowercase words, as queries and memory indexes see them: letters and digits, with accents removed.

Types

type Doc

type Doc struct {
	// ID identifies the document, such as its row's key or a page's slug.
	ID string
	// Scope is who the document belongs to, such as "user:7" or "team:3":
	// a query with a scope finds only its documents. "" is no one's.
	Scope string
	// Fields holds the text of each field. Fields not in the index are ignored.
	Fields map[string]string
}

Doc is a document in an index.

type Field

type Field struct {
	// Name is the field's name, a letter followed by letters, digits and
	// underscores.
	Name string
	// Boost weighs matches in the field: 2 counts them twice. Default 1.
	Boost float64
}

Field is a field of an index's documents.

type Hit

type Hit struct {
	ID    string  `json:"id"`
	Scope string  `json:"scope,omitempty"`
	Score float64 `json:"score"`
	// Snippets are the fields' text around what matched, with the matches
	// marked; long fields are cut to a few words around the first match.
	Snippets map[string][]Segment `json:"snippets"`
}

Hit is a document that matched.

type Index

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

Index is a search index. It's safe for concurrent use.

func New

func New(db *sql.DB, name string, opts Options) (*Index, error)

New returns an index named name in db, SQLite or PostgreSQL. Call Migrate to create its table.

func NewMemory

func NewMemory(opts Options) (*Index, error)

NewMemory returns an index in memory, for content collections and other documents that fit in memory and are indexed when the app starts.

func (*Index) Delete

func (x *Index) Delete(ctx context.Context, id string) error

Delete removes the document with this ID; there may be none.

func (*Index) Migrate

func (x *Index) Migrate(ctx context.Context) error

Migrate creates the index's table, if it doesn't exist yet.

func (*Index) Put

func (x *Index) Put(ctx context.Context, d Doc) error

Put adds a document, or replaces the one with its ID.

func (*Index) Reset

func (x *Index) Reset(ctx context.Context) error

Reset removes every document, to index everything again.

func (*Index) Search

func (x *Index) Search(ctx context.Context, q Query) (Results, error)

Search returns the documents that match q, the best first.

type Options

type Options struct {
	// Fields are the documents' fields, the most important first.
	Fields []Field
	// Language is PostgreSQL's text search configuration, for word stems
	// such as "running" matching "run": "english" by default, "simple"
	// for none. SQLite and memory indexes match words without stems.
	Language string
}

Options configure an index.

type Query

type Query struct {
	// Text is what was typed. Each word must match, as a word or the
	// start of one; quotes and operators are taken as text.
	Text string
	// Scope limits the search to documents with this scope; "" searches
	// documents of every scope.
	Scope string
	// Limit is how many hits to return, 20 by default; Offset skips some, for pages.
	Limit, Offset int
}

Query is a search.

type Results

type Results struct {
	Hits []Hit `json:"hits"`
	// Total is how many documents match in all.
	Total int `json:"total"`
}

Results are a page of hits.

type Segment

type Segment struct {
	Text  string `json:"text"`
	Match bool   `json:"match,omitempty"`
}

Segment is a piece of a snippet: text that matched the query, or text around it.

Jump to

Keyboard shortcuts

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