search

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 17, 2026 License: MIT Imports: 3 Imported by: 0

Documentation

Overview

Package search provides a full-text search engine abstraction built on top of Bleve. It supports indexing, batch indexing, deletion, complex queries (keyword, term, phrase, prefix, wildcard, regex, fuzzy, range), facets, highlighting, and auto-complete suggestions.

Basic usage:

eng, err := search.NewDefault("/tmp/myindex")
if err != nil { log.Fatal(err) }
defer eng.Close()

eng.Index(ctx, search.Doc{
    ID:   "doc1",
    Type: "article",
    Fields: map[string]any{
        "title":   "Hello World",
        "content": "This is a test document",
        "tags":    "test,example",
    },
})

res, _ := eng.Search(ctx, search.SearchRequest{
    Keyword: "hello",
    Size:    10,
})
for _, hit := range res.Hits {
    fmt.Println(hit.ID, hit.Score)
}

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrClosed       = errors.New("search engine closed")
	ErrEmptyDocID   = errors.New("document id cannot be empty")
	ErrNilDoc       = errors.New("document cannot be nil")
	ErrIndexNotOpen = errors.New("index is not open")
)

Sentinel errors for the search engine.

Functions

This section is empty.

Types

type AggregationBucket

type AggregationBucket struct {
	Key   any `json:"key"`
	Count int `json:"count"`
}

AggregationBucket is a single bucket in a bucket aggregation.

type AggregationRequest

type AggregationRequest struct {
	// Name is the aggregation name in the response.
	Name string

	// Type is the aggregation type:
	// "terms", "histogram", "date_histogram", "stats", "cardinality",
	// "avg", "sum", "min", "max", "percentiles"
	Type string

	// Field is the field to aggregate on.
	Field string

	// Size is the number of buckets for terms aggregations (default 10).
	Size int

	// Interval is the bucket interval for histogram/date_histogram.
	// For date_histogram, use "1d", "1h", "1m", etc.
	Interval string

	// Format is the date format for date_histogram key (e.g. "yyyy-MM-dd").
	Format string

	// Percentiles is the list of percentiles for the percentiles aggregation.
	Percentiles []float64
}

AggregationRequest defines a named aggregation to compute during search.

type AggregationResult

type AggregationResult struct {
	// Name matches the AggregationRequest.Name.
	Name string

	// Buckets for bucket aggregations (terms, histogram, date_histogram).
	Buckets []AggregationBucket

	// Stats for metrics aggregations (stats, avg, sum, min, max).
	Stats *AggregationStats

	// Percentiles for percentiles aggregation.
	Percentiles map[string]float64

	// Cardinality for cardinality aggregation.
	Cardinality int64
}

AggregationResult holds the result of an aggregation.

type AggregationStats

type AggregationStats struct {
	Count int64   `json:"count"`
	Min   float64 `json:"min"`
	Max   float64 `json:"max"`
	Avg   float64 `json:"avg"`
	Sum   float64 `json:"sum"`
}

AggregationStats holds basic statistics for a metrics aggregation.

type ClauseFuzzy

type ClauseFuzzy struct {
	Field     string
	Term      string
	Fuzziness int // 0, 1, 2…
	Prefix    int // prefix length to match exactly
	Boost     *float64
}

ClauseFuzzy matches documents with fuzzy (edit-distance) matching.

type ClauseMatch

type ClauseMatch struct {
	Field    string
	Query    string
	Boost    *float64
	Operator string // "and"/"or", default "or"
}

ClauseMatch matches a single field with a text query.

type ClausePhrase

type ClausePhrase struct {
	Field  string
	Phrase string
	Slop   int // allowed word distance
	Boost  *float64
}

ClausePhrase matches an exact phrase in a field.

type ClausePrefix

type ClausePrefix struct {
	Field  string
	Prefix string
	Boost  *float64
}

ClausePrefix matches documents where a field starts with a prefix.

type ClauseQueryString

type ClauseQueryString struct {
	Query  string
	Fields []string // if non-empty, expands to field:(q) OR ...
	Boost  *float64
}

ClauseQueryString uses Bleve's query string syntax directly.

type ClauseRegex

type ClauseRegex struct {
	Field   string
	Pattern string
	Boost   *float64
}

ClauseRegex matches documents using a regular expression.

type ClauseWildcard

type ClauseWildcard struct {
	Field   string
	Pattern string
	Boost   *float64
}

ClauseWildcard matches documents using wildcard patterns (* and ?).

type CompletionSuggestion

type CompletionSuggestion struct {
	Text  string
	Score float64
}

CompletionSuggestion is a single completion suggestion result.

type CompletionSuggestionRequest

type CompletionSuggestionRequest struct {
	// Field is the completion field name.
	Field string

	// Prefix is the prefix to match.
	Prefix string

	// Size is the max number of suggestions (default 5).
	Size int

	// Fuzzy enables fuzzy matching for the prefix.
	Fuzzy bool

	// Fuzziness is the max edit distance (1-2, default 1).
	Fuzziness int
}

CompletionSuggestionRequest defines a completion field suggestion.

type Config

type Config struct {
	// IndexPath is the filesystem path for the Bleve index.
	// Leave empty for in-memory indexes (use NewMemory).
	IndexPath string

	// DefaultAnalyzer is the Bleve analyzer name (e.g. "standard", "keyword").
	// Empty defaults to "standard".
	DefaultAnalyzer string

	// DefaultSearchFields are the fields searched when SearchRequest.SearchFields
	// is not specified.
	DefaultSearchFields []string

	// OpenTimeout is the timeout for opening an existing index (unused in current impl).
	OpenTimeout time.Duration

	// QueryTimeout is the max duration for individual index/search operations.
	// 0 means no timeout.
	QueryTimeout time.Duration

	// BatchSize is the number of documents per batch in IndexBatch.
	// 0 defaults to 100.
	BatchSize int
}

Config holds search engine configuration.

type Doc

type Doc struct {
	ID     string         `json:"id"`
	Type   string         `json:"type"`
	Fields map[string]any `json:"fields"`
}

Doc represents a document to be indexed.

func NewDoc

func NewDoc(id, docType string, fields map[string]any) Doc

NewDoc creates a Doc with the given ID, type, and fields.

type Engine

type Engine interface {
	// Index adds or updates a single document.
	Index(ctx context.Context, doc Doc) error
	// IndexBatch adds or updates multiple documents in batches.
	IndexBatch(ctx context.Context, docs []Doc) error
	// Delete removes a document by ID.
	Delete(ctx context.Context, id string) error
	// Search executes a search request and returns matching hits.
	Search(ctx context.Context, req SearchRequest) (SearchResult, error)
	// GetAutoCompleteSuggestions returns prefix-based suggestions.
	GetAutoCompleteSuggestions(ctx context.Context, keyword string) ([]string, error)
	// GetSearchSuggestions returns match-based suggestions.
	GetSearchSuggestions(ctx context.Context, keyword string) ([]string, error)
	// DocCount returns the total number of documents in the index.
	DocCount(ctx context.Context) (uint64, error)
	// Stats returns index statistics.
	Stats() map[string]any
	// Close releases index resources.
	Close() error
}

Engine defines the full-text search interface. Implementations include:

  • bleve (in-process, disk or memory)
  • elasticsearch (remote cluster)

type ExtendedEngine

type ExtendedEngine interface {
	Engine

	// GetByID retrieves a single document by ID.
	GetByID(ctx context.Context, id string) (Doc, error)

	// Update partially updates a document (merge fields).
	Update(ctx context.Context, id string, fields map[string]any) error

	// BulkDelete removes multiple documents by ID.
	BulkDelete(ctx context.Context, ids []string) error

	// BulkUpdate partially updates multiple documents.
	BulkUpdate(ctx context.Context, updates map[string]map[string]any) error

	// DeleteByQuery removes all documents matching the search request.
	DeleteByQuery(ctx context.Context, req SearchRequest) (int64, error)

	// UpdateByQuery updates all documents matching the search request
	// with the given fields (partial merge).
	UpdateByQuery(ctx context.Context, req SearchRequest, fields map[string]any) (int64, error)

	// Scroll returns a cursor for deep pagination. Call ScrollNext with
	// the returned scrollID to fetch subsequent pages.
	Scroll(ctx context.Context, req SearchRequest, keepAlive time.Duration) (ScrollResult, error)

	// ScrollNext fetches the next batch of results using a scroll ID.
	ScrollNext(ctx context.Context, scrollID string, keepAlive time.Duration) (ScrollResult, error)

	// ClearScroll releases server-side resources for a scroll context.
	ClearScroll(ctx context.Context, scrollID string) error

	// SearchAfter performs cursor-based pagination using sort values
	// from the last hit. More efficient than scroll for sequential access.
	SearchAfter(ctx context.Context, req SearchRequest, after []any) (SearchResult, error)

	// Refresh makes recent index/delete operations visible to search.
	Refresh(ctx context.Context) error

	// Flush persists index changes to disk (backend-dependent).
	Flush(ctx context.Context) error

	// HealthCheck returns nil if the backend is healthy.
	HealthCheck(ctx context.Context) error
}

ExtendedEngine defines additional operations beyond basic CRUD. Not all backends implement this — use a type assertion to check:

if ee, ok := eng.(search.ExtendedEngine); ok {
    doc, err := ee.GetByID(ctx, "doc1")
}

type FacetRequest

type FacetRequest struct {
	Name  string // result name
	Field string // field to facet on
	Size  int    // top N terms
}

FacetRequest requests a term facet aggregation.

type FacetResult

type FacetResult struct {
	Total int         `json:"total"`
	Terms []FacetTerm `json:"terms"`
}

FacetResult holds the result of a facet aggregation.

type FacetTerm

type FacetTerm struct {
	Term  string `json:"term"`
	Count int    `json:"count"`
}

FacetTerm is a single term in a facet result.

type Hit

type Hit struct {
	ID        string              `json:"id"`
	Score     float64             `json:"score"`
	Fields    map[string]any      `json:"fields"`
	Fragments map[string][]string `json:"fragments,omitempty"`
	Sort      []any               `json:"sort,omitempty"` // sort values for SearchAfter
	Version   int64               `json:"version,omitempty"`
	Index     string              `json:"index,omitempty"` // source index (multi-index search)
}

Hit represents a single search result.

type NumericRangeFilter

type NumericRangeFilter struct {
	Field   string
	GTE, GT *float64
	LTE, LT *float64
}

NumericRangeFilter filters documents by a numeric field range.

type ScrollResult

type ScrollResult struct {
	ScrollID string
	Total    uint64
	Hits     []Hit
	Took     time.Duration
}

ScrollResult holds one page of scroll results plus the scroll ID for fetching the next page.

type SearchRequest

type SearchRequest struct {
	// Keyword is the simple keyword search (legacy interface).
	Keyword      string
	SearchFields []string

	// Structured term filters.
	MustTerms    map[string][]string
	MustNotTerms map[string][]string
	ShouldTerms  map[string][]string

	// Numeric and time range filters.
	NumericRanges []NumericRangeFilter
	TimeRanges    []TimeRangeFilter

	// Advanced query clauses.
	QueryString *ClauseQueryString
	Matches     []ClauseMatch
	Phrases     []ClausePhrase
	Prefixes    []ClausePrefix
	Wildcards   []ClauseWildcard
	Regexps     []ClauseRegex
	Fuzzies     []ClauseFuzzy

	// MinShould is the minimum number of should clauses that must match.
	MinShould int

	// Facets to compute.
	Facets []FacetRequest

	// Aggregations to compute (richer than Facets).
	Aggregations []AggregationRequest

	// Sorting and pagination.
	SortBy []string
	From   int
	Size   int

	// SearchAfter provides cursor-based pagination using sort values
	// from the last hit. Only supported by ExtendedEngine backends.
	SearchAfter []any

	// Field selection and highlighting.
	IncludeFields   []string
	ExcludeFields   []string
	Highlight       bool
	HighlightFields []string
	FragmentSize    int
	MaxFragments    int

	// TrackTotalHits: if true, the engine returns the exact total hit
	// count (may be expensive for large result sets). Default: true.
	TrackTotalHits *bool

	// MinScore: if > 0, only return hits with score >= MinScore.
	MinScore float64

	// Explain: if true, return score explanation for each hit.
	Explain bool

	// Version: if true, return document version for each hit.
	Version bool
}

SearchRequest defines a search query with all supported features.

func NewKeywordSearch

func NewKeywordSearch(keyword string, size int) SearchRequest

NewKeywordSearch creates a simple keyword search request.

func NewMatchSearch

func NewMatchSearch(field, query string, size int) SearchRequest

NewMatchSearch creates a search request with a match clause on a specific field.

func NewPhraseSearch

func NewPhraseSearch(field, phrase string, size int) SearchRequest

NewPhraseSearch creates a search request with a phrase clause.

func NewTermSearch

func NewTermSearch(field, value string, size int) SearchRequest

NewTermSearch creates a search request that filters by exact term match.

type SearchResult

type SearchResult struct {
	Total        uint64                       `json:"total"`
	Took         time.Duration                `json:"took"`
	Hits         []Hit                        `json:"hits"`
	Facets       map[string]FacetResult       `json:"facets,omitempty"`
	Aggregations map[string]AggregationResult `json:"aggregations,omitempty"`
	MaxScore     float64                      `json:"maxScore,omitempty"`
}

SearchResult is the response to a SearchRequest.

type TermSuggestion

type TermSuggestion struct {
	Text        string
	Suggestions []string
}

TermSuggestion is a single term suggestion result.

type TermSuggestionRequest

type TermSuggestionRequest struct {
	// Field is the text field to suggest on.
	Field string

	// Text is the input text to correct.
	Text string

	// Size is the max number of suggestions per term (default 5).
	Size int

	// SuggestMode: "missing" (default), "popular", "always".
	SuggestMode string
}

TermSuggestionRequest defines a term-level suggestion for spell correction.

type TimeRangeFilter

type TimeRangeFilter struct {
	Field   string
	From    *time.Time
	To      *time.Time
	IncFrom bool
	IncTo   bool
}

TimeRangeFilter filters documents by a time field range.

Directories

Path Synopsis
bleve module

Jump to

Keyboard shortcuts

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