bleve

package module
v0.0.0-...-957b774 Latest Latest
Warning

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

Go to latest
Published: Jul 17, 2026 License: BSD-3-Clause Imports: 6 Imported by: 0

README

go-ruby-bleve/bleve

bleve — go-ruby-bleve

Docs License Go Coverage

A pure-Go (no cgo) full-text search library with a clean, idiomatic Ruby search API. It indexes Hash-shaped documents in memory or on disk, and answers match / phrase / term / prefix / fuzzy / wildcard / regexp / range / boolean / query-string queries with scoring, highlighting and faceting — without any C extension and without a running search server.

Unlike most go-ruby-* siblings, there is no single canonical Ruby bleve gem to mirror: bleve is Go-native. This module therefore exposes that Go capability through the shape a Bleve Ruby gem would have — Bleve::Index, a Bleve::Query DSL, Bleve::Mapping, and Hash-shaped results — rather than porting an existing library.

It builds on github.com/blevesearch/bleve/v2 (all indexing and searching is delegated to bleve) and is the search backend for go-embedded-ruby, but is a standalone, reusable module with no dependency on the Ruby runtime.

CGO-free on every arch. The default in-memory (gtreap) and on-disk (scorch

  • bbolt) indexes build and pass the full suite with CGO_ENABLED=0 on all six supported 64-bit targets — amd64, arm64, riscv64, loong64, ppc64le and the big-endian s390x. bleve's optional faiss-backed vector search (which needs cgo) is gated behind a build tag and is not used.

Features

  • In-memory and on-disk indexesNewMemIndex for ephemeral search, New / Open for a persistent index that survives close/reopen.
  • Hash documents — index, fetch, and delete documents that are plain map[string]interface{}; batch many operations atomically.
  • Full query DSLMatch, MatchPhrase, Term, Prefix, Fuzzy, Wildcard, Regexp, NumericRange, DateRange, Bool, QueryString, MatchAll, MatchNone, each with fluent Field / Boost / Fuzziness.
  • Rich results — hits with id, score and stored fields; Total, MaxScore, Took; pagination (Size / From); sorting (SortBy); field selection.
  • Highlighting — per-field match fragments via Highlight / HighlightStyle.
  • Faceting — term, numeric-range and date-range aggregations via WithFacet.
  • Typed mappings — text (with analyzers), keyword, numeric, datetime and boolean fields, or a zero-config dynamic default.

Install

go get github.com/go-ruby-bleve/bleve

Usage

package main

import (
	"fmt"

	bleve "github.com/go-ruby-bleve/bleve"
)

func main() {
	// A typed mapping (or pass nil for the dynamic default).
	m := bleve.NewMapping().
		AddTextField("title").
		AddKeywordField("category").
		AddNumericField("views")

	idx, _ := bleve.NewMemIndex(m)
	defer idx.Close()

	idx.Index("post-1", map[string]interface{}{
		"title": "hello world", "category": "news", "views": 42.0,
	})
	idx.Index("post-2", map[string]interface{}{
		"title": "goodbye world", "category": "blog", "views": 7.0,
	})

	res, _ := idx.Search(
		bleve.Match("world").Field("title"),
		bleve.Size(10),
		bleve.Highlight(),
		bleve.WithFacet("by_category", bleve.TermFacet("category", 10)),
	)

	fmt.Println("total:", res.Total())
	for _, h := range res.Hits() {
		fmt.Printf("%s  score=%.3f  %v\n", h.ID, h.Score, h.Fragments["title"])
	}
	for _, tc := range res.Facets()["by_category"].Terms {
		fmt.Printf("category %q: %d\n", tc.Term, tc.Count)
	}
}
Ruby shape (via rbgo)
index = Bleve.new_mem_index(Bleve::Mapping.new.add_text_field("title"))
index.index("post-1", { "title" => "hello world", "views" => 42 })

res = index.search(Bleve::Query.match("world").field("title"),
                   size: 10, highlight: true)
res.hits.each { |h| puts "#{h.id} #{h.score}" }

Query builders

Builder Purpose
Match / MatchPhrase analyzed full-text match / ordered phrase
Term / Prefix exact term / prefix match
Fuzzy / Wildcard / Regexp edit-distance / glob / regex match
NumericRange / DateRange half-open range over numeric / datetime fields
Bool must (AND) / should (OR) / must_not (NOT) composition
QueryString bleve query-string mini-language
MatchAll / MatchNone match everything / nothing

Tests & coverage

The suite is deterministic, network-free (fixed UTC times, on-disk indexes under t.TempDir) and holds 100 % statement coverage, run with -race:

go test -race -cover ./...

CI runs nine jobs: -race + 100 %-coverage on Linux, macOS and Windows, plus the six 64-bit targets (amd64/arm64 native; riscv64/loong64/ppc64le/s390x under qemu-user) built with CGO_ENABLED=0.

License

BSD-3-Clause — see LICENSE. Copyright (c) 2026, the go-ruby-bleve/bleve authors.

WebAssembly

Unlike the rest of the go-ruby family, this library does not target WebAssembly: its backing engine — blevesearch/bleve (memory-mapped index segments) — relies on mmap and native filesystem syscalls that the js/wasm and wasip1/wasm sandboxes do not provide. It ships for the six 64-bit native/qemu arches only.

Documentation

Overview

Package bleve is a pure-Go (CGO=0) full-text search library for the Ruby / rbgo ecosystem.

Not a port of an existing gem

Unlike most go-ruby-* siblings, there is no single canonical Ruby "bleve" gem to mirror: bleve is a Go-native search engine. This package therefore exposes that Go capability through a clean, idiomatic Ruby-shaped search API -- the shape a hypothetical Bleve Ruby gem would have -- rather than reproducing a specific upstream Ruby library.

It is a thin, ergonomic wrapper over github.com/blevesearch/bleve/v2. All indexing and searching is delegated to bleve; this package only provides the Hash-shaped documents/results, snake_case-friendly method names, and query DSL a Ruby developer would expect. When bound into rbgo it surfaces as:

index = Bleve.new_mem_index(Bleve::Mapping.new)
index.index("doc-1", { "title" => "hello world", "views" => 42 })
res = index.search(Bleve::Query.match("hello"), size: 10, highlight: true)
res.hits.each { |h| puts "#{h.id} #{h.score}" }

Go surface

Index construction:

NewMemIndex(mapping)   // in-memory (Bleve.new_mem_index)
New(path, mapping)     // on-disk, fresh   (Bleve.new)
Open(path)             // on-disk, existing (Bleve.open)

Index operations: Index, Batch, Delete, Document, Count, Close, Search.

Query builders (Bleve::Query.*): Match, MatchPhrase, Term, Prefix, Fuzzy, Wildcard, Regexp, NumericRange, DateRange, Bool, QueryString, MatchAll, MatchNone. Each returns a Query with fluent Field/Boost/Fuzziness setters.

Search options: Size, From, Fields, Highlight, HighlightStyle, SortBy, WithFacet. Results are a SearchResult exposing Hits, Total, MaxScore, Took and Facets.

Mapping (Bleve::Mapping) configures document and field mappings (text, keyword, numeric, datetime, boolean) and analyzers, or a sensible default.

Portability

The default in-memory (gtreap) and on-disk (scorch) indexes build with CGO_ENABLED=0 on every supported 64-bit target -- amd64, arm64, riscv64, loong64, ppc64le and s390x (big-endian) -- so the library is fully pure-Go. bleve's optional faiss-backed vector search (which needs cgo) is gated behind a build tag and is not used here.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrClosed is returned when an operation is attempted on a closed index.
	ErrClosed = errors.New("bleve: index is closed")
	// ErrNotFound is returned when a document id is not present in the index.
	ErrNotFound = errors.New("bleve: document not found")
)

Sentinel errors at the root of the Bleve::Error tree. Callers may test for them with errors.Is; every wrapped Error unwraps to one of these (or to the underlying bleve error).

Functions

func F64

func F64(v float64) *float64

F64 returns a pointer to v. It is a convenience for the open-ended bounds of NumericRange (a nil bound means unbounded on that side).

Types

type Batch

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

Batch is an accumulator for a group of index/delete operations applied atomically. Obtain one via Index.Batch.

func (*Batch) Delete

func (b *Batch) Delete(id string)

Delete queues a document id for deletion in the batch.

func (*Batch) Index

func (b *Batch) Index(id string, doc map[string]interface{}) error

Index queues a document for indexing in the batch.

type Error

type Error struct {
	// Op is the high-level operation that failed, e.g. "index" or "search".
	Op string
	// Err is the wrapped cause.
	Err error
}

Error is the common error type returned by this package. It records the operation that failed and wraps the underlying cause, which may be a sentinel (ErrClosed, ErrNotFound) or an error from the underlying bleve engine.

func (*Error) Error

func (e *Error) Error() string

Error implements the error interface.

func (*Error) Unwrap

func (e *Error) Unwrap() error

Unwrap exposes the wrapped cause so errors.Is / errors.As work.

type Facet

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

Facet describes an aggregation over the result set. Build a term facet with TermFacet, then optionally attach numeric or date buckets.

func TermFacet

func TermFacet(field string, size int) *Facet

TermFacet counts the top-size distinct values of field.

func (*Facet) AddDateRange

func (f *Facet) AddDateRange(name string, start, end time.Time) *Facet

AddDateRange adds a named date bucket [start, end) to the facet.

func (*Facet) AddNumericRange

func (f *Facet) AddNumericRange(name string, min, max *float64) *Facet

AddNumericRange adds a named numeric bucket [min, max) to the facet. A nil bound is unbounded.

type FacetResult

type FacetResult struct {
	Field         string
	Total         int
	Missing       int
	Other         int
	Terms         []TermCount
	NumericRanges []RangeCount
	DateRanges    []RangeCount
}

FacetResult is the aggregated result for a single named facet.

type Hit

type Hit struct {
	ID        string
	Score     float64
	Fields    map[string]interface{}
	Fragments map[string][]string
}

Hit is a single search result: the document id, its relevance score, any requested stored fields (as a Hash) and, when highlighting is on, the highlighted fragments per field.

type Index

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

Index is a full-text index. It mirrors the Ruby Bleve::Index surface: index Hash-shaped documents, search them, and (for on-disk indexes) persist across open/close. An Index is safe to use until Close is called.

func New

func New(path string, m *Mapping) (*Index, error)

New creates a fresh on-disk index at path (Bleve.new). It is an error if path already exists. Pass nil for the default dynamic mapping.

func NewMemIndex

func NewMemIndex(m *Mapping) (*Index, error)

NewMemIndex creates an in-memory index (Bleve.new_mem_index). Pass nil to use the default dynamic mapping. Nothing is written to disk.

func Open

func Open(path string) (*Index, error)

Open opens an existing on-disk index at path (Bleve.open).

func (*Index) Batch

func (ix *Index) Batch(fn func(*Batch) error) error

Batch runs fn against a Batch and, if fn returns nil, applies all queued operations atomically (Bleve::Index#batch { |b| ... }).

func (*Index) Close

func (ix *Index) Close() error

Close releases the index. Further operations return ErrClosed.

func (*Index) Count

func (ix *Index) Count() (uint64, error)

Count returns the number of documents in the index.

func (*Index) Delete

func (ix *Index) Delete(id string) error

Delete removes the document with the given id. Deleting an absent id is not an error.

func (*Index) Document

func (ix *Index) Document(id string) (map[string]interface{}, error)

Document returns the stored fields of the document with the given id as a Hash. It returns an error wrapping ErrNotFound if the id is absent.

func (*Index) Index

func (ix *Index) Index(id string, doc map[string]interface{}) error

Index adds or replaces the document with the given id. The document is a Hash (map) of field name to value.

func (*Index) Path

func (ix *Index) Path() string

Path returns the on-disk location of the index, or "" for a memory index.

func (*Index) Search

func (ix *Index) Search(q Query, opts ...SearchOption) (*SearchResult, error)

Search runs q against the index with the given options and returns a SearchResult (Bleve::Index#search).

type Mapping

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

Mapping describes how documents and their fields are indexed. It mirrors the Ruby Bleve::Mapping surface: start from a sensible default and, optionally, declare typed fields (text, keyword, numeric, datetime, boolean) and analyzers. A zero-configuration Mapping dynamically indexes every field.

func NewMapping

func NewMapping() *Mapping

NewMapping returns a Mapping seeded with bleve's default dynamic mapping.

func (*Mapping) AddBooleanField

func (m *Mapping) AddBooleanField(name string) *Mapping

AddBooleanField declares a boolean field.

func (*Mapping) AddDateTimeField

func (m *Mapping) AddDateTimeField(name string) *Mapping

AddDateTimeField declares a datetime field.

func (*Mapping) AddKeywordField

func (m *Mapping) AddKeywordField(name string) *Mapping

AddKeywordField declares a non-tokenized text field (exact-match keyword).

func (*Mapping) AddNumericField

func (m *Mapping) AddNumericField(name string) *Mapping

AddNumericField declares a numeric field (float64/int).

func (*Mapping) AddTextField

func (m *Mapping) AddTextField(name string) *Mapping

AddTextField declares a tokenized, analyzed, stored text field.

func (*Mapping) AddTextFieldWithAnalyzer

func (m *Mapping) AddTextFieldWithAnalyzer(name, analyzer string) *Mapping

AddTextFieldWithAnalyzer declares a text field indexed with a named analyzer.

func (*Mapping) SetDefaultAnalyzer

func (m *Mapping) SetDefaultAnalyzer(name string) *Mapping

SetDefaultAnalyzer sets the analyzer used for fields that do not name their own. Returns the Mapping for chaining.

type Query

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

Query wraps a bleve query. Build one with the package-level constructors (mirroring Bleve::Query.*) and, where applicable, refine it with the fluent Field, Boost and Fuzziness setters.

func Bool

func Bool(must, should, mustNot []Query) Query

Bool builds a boolean query from must (AND), should (OR) and mustNot (NOT) sub-queries. Any slice may be nil.

func DateRange

func DateRange(start, end time.Time) Query

DateRange builds a date range query over [start, end).

func Fuzzy

func Fuzzy(term string) Query

Fuzzy builds a fuzzy (edit-distance) query.

func Match

func Match(text string) Query

Match builds an analyzed full-text match query (Bleve::Query.match).

func MatchAll

func MatchAll() Query

MatchAll matches every document.

func MatchNone

func MatchNone() Query

MatchNone matches no document.

func MatchPhrase

func MatchPhrase(text string) Query

MatchPhrase builds a phrase query preserving term order and adjacency.

func NumericRange

func NumericRange(min, max *float64) Query

NumericRange builds a numeric range query. A nil bound is unbounded; use F64 to take the address of a literal.

func Prefix

func Prefix(prefix string) Query

Prefix builds a prefix query.

func QueryString

func QueryString(s string) Query

QueryString builds a query from bleve's query-string mini-language.

func Regexp

func Regexp(pattern string) Query

Regexp builds a regular-expression query.

func Term

func Term(term string) Query

Term builds an exact, un-analyzed term query.

func Wildcard

func Wildcard(pattern string) Query

Wildcard builds a wildcard query (* and ? metacharacters).

func (Query) Boost

func (q Query) Boost(b float64) Query

Boost scales the query's contribution to the score.

func (Query) Field

func (q Query) Field(field string) Query

Field restricts the query to a single field. It is a no-op for queries that are not field-scoped (e.g. MatchAll, Bool, QueryString).

func (Query) Fuzziness

func (q Query) Fuzziness(f int) Query

Fuzziness sets the allowed edit distance. It is a no-op for query types that do not support fuzziness.

type RangeCount

type RangeCount struct {
	Name  string
	Count int
}

RangeCount is one bucket of a numeric or date range facet.

type SearchOption

type SearchOption func(*searchOpts)

SearchOption configures a Search call. Mirrors the Ruby keyword arguments size:, from:, fields:, highlight:, sort:, facets:.

func Fields

func Fields(fields ...string) SearchOption

Fields requests that the given stored fields be loaded onto each hit. Use "*" to load every stored field.

func From

func From(n int) SearchOption

From sets the offset of the first hit to return (for pagination).

func Highlight

func Highlight() SearchOption

Highlight enables highlighting with the default fragmenter/formatter.

func HighlightStyle

func HighlightStyle(style string) SearchOption

HighlightStyle enables highlighting with a named style (e.g. "html", "ansi").

func Size

func Size(n int) SearchOption

Size sets the maximum number of hits to return.

func SortBy

func SortBy(fields ...string) SearchOption

SortBy sets the sort order. Each entry is a field name; prefix with "-" for descending, and use "_score" / "_id" for the built-in sorts.

func WithFacet

func WithFacet(name string, f *Facet) SearchOption

WithFacet adds a named facet (aggregation) to the search.

type SearchResult

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

SearchResult is the outcome of a Search (Bleve::SearchResult).

func (*SearchResult) Facets

func (r *SearchResult) Facets() map[string]*FacetResult

Facets returns the computed facets keyed by the name given to WithFacet.

func (*SearchResult) Hits

func (r *SearchResult) Hits() []Hit

Hits returns the page of matches.

func (*SearchResult) MaxScore

func (r *SearchResult) MaxScore() float64

MaxScore is the highest score among the matches.

func (*SearchResult) Took

func (r *SearchResult) Took() time.Duration

Took is the wall-clock time the search took.

func (*SearchResult) Total

func (r *SearchResult) Total() uint64

Total is the number of documents that matched (independent of paging).

type TermCount

type TermCount struct {
	Term  string
	Count int
}

TermCount is one bucket of a term facet.

Jump to

Keyboard shortcuts

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