opensearch

package module
v0.18.0 Latest Latest
Warning

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

Go to latest
Published: Sep 10, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package opensearch exposes the official opensearch-go v4 client through the Core vector-store capability interfaces. Documents are indexed JSON objects with a `knn_vector` field for the embedding and a nested `object` field for metadata. Documents containing media are rejected before indexing I/O because this adapter persists document text and metadata only.

Requirements: OpenSearch 2.x+ with the k-NN plugin (built-in on every recent release).

Space types — five distance variants are recognized; coverage depends on the engine:

Engines: EngineLucene (default, ships with core), EngineNMSLib, EngineFaiss. The chosen value is baked into the index mapping at creation time and cannot be changed without rebuilding.

An index that already exists is checked rather than taken on trust. OpenSearch derives _score from the vector field's own space — "(2 - d) / 2" for cosinesimil is not "1 / (1 + d)" for l2 — and innerproduct is the only space whose score runs above 1. A store configured for one space against a field built for another therefore either applies the inner-product inverse to a number it does not describe, or clamps unbounded inner-product scores onto Core's ceiling so an exact match and a mediocre one become the same value. NewStore reads the mapping and refuses a disagreement with ErrIncompatibleIndex, which also covers a field that is absent, is not a knn_vector, or holds a different width. The space type is read from the field, then from its method — "this value can also be specified within the method" — and otherwise resolved to its documented l2 default; a field trained from a model states none of them, and is reported rather than assumed.

Search uses approximate k-NN:

POST <index>/_search
{
  "size": K,
  "query": {"knn": {"embedding": {
    "vector": [...], "k": K,
    "filter": {"query_string": {"query": "<lucene>"}}
  }}}
}

Filter visitor produces Lucene query-string syntax under the configured metadata prefix — same dialect as the Elasticsearch store, intentionally so callers can swap between the two.

Result completeness. OpenSearch reports lost shards, query timeouts, version conflicts, and per-document failures inside a successful response. Search rejects a result missing any targeted shard, and filtered deletion rejects an incomplete deletion while the documents it already removed stay removed.

Metadata mapping. Metadata keys are unknown when the index is created, so their fields map dynamically. The default for a JSON string is "text with a .keyword sub-field" and the text field is analyzed, which would make `metadata.author:"Alice"` a tokenized, case-insensitive match — it would match an author of "Alice Smith" or of "alice". A dynamic template maps strings under the metadata path straight to keyword instead, so the field the filter compiler queries is the whole-value, case-sensitive one, and the sub-field's ignore_above cutoff never applies. An index created before this mapping needs a reindex for filters to compare exactly.

Filterable keys. A metadata key is written into the Lucene query as text, and query_string cannot quote a field name, so a filter can only name a key that is a plain identifier. An indexed key is a string literal in the filter DSL, so without that limit metadata['a:1 OR b'] compiled to metadata.a:1 OR b and the caller's key became a term boundary and a boolean operator. A document whose metadata key is anything at all still stores and reads back fine; this is only about which keys a filter can name.

See https://docs.opensearch.org/latest/search-plugins/knn/ for the k-NN plugin reference.

Index

Constants

View Source
const (
	DefaultIndexName      = "scope-vector-index"
	DefaultEmbeddingField = "embedding"
	DefaultContentField   = "content"
	DefaultMetadataField  = "metadata"
	DefaultSpaceType      = SpaceTypeCosine
	DefaultEngine         = EngineLucene
	DefaultMethodName     = "hnsw"
)

Exported defaults keep constructor behavior visible and overridable.

View Source
const Provider = "OpenSearch"

Provider is the stable backend name for host-side attribution.

Variables

View Source
var (
	// ErrIndexMissing reports an absent index that this store was not asked to
	// create.
	ErrIndexMissing = errors.New("opensearch: index not found")

	// ErrIncompatibleIndex reports an existing index whose vector field cannot
	// serve this store: it is absent, not a knn_vector, or built for a
	// different space type or width.
	ErrIncompatibleIndex = errors.New("opensearch: index is incompatible")
)

Functions

This section is empty.

Types

type Engine

type Engine string

Engine identifies the ANN implementation stored in an OpenSearch index mapping. Lucene is available in OpenSearch core; NMSLib and Faiss require compatible server plugins and unlock space/method combinations Lucene does not support.

const (
	EngineLucene Engine = "lucene"
	EngineNMSLib Engine = "nmslib"
	EngineFaiss  Engine = "faiss"
)

These are the provider values this adapter recognizes.

func (Engine) String

func (e Engine) String() string

func (Engine) Valid

func (e Engine) Valid() bool

type SpaceType

type SpaceType string

SpaceType selects the vector similarity space recorded in an OpenSearch knn_vector mapping. Because OpenSearch converts each space to a different raw-score representation, Store also uses this value to normalize scores into Core's provider-neutral contract.

const (
	SpaceTypeCosine SpaceType = "cosinesimil"
	SpaceTypeL2     SpaceType = "l2"
	SpaceTypeIP     SpaceType = "innerproduct"
	SpaceTypeL1     SpaceType = "l1"
	SpaceTypeLInf   SpaceType = "linf"
)

The metric is a closed vocabulary because score direction and threshold semantics depend on it: the same raw number means "near" under one metric and "far" under another, so an unrecognized value must be rejected rather than guessed.

func (SpaceType) String

func (s SpaceType) String() string

func (SpaceType) Valid

func (s SpaceType) Valid() bool

type Store

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

Store implements vector-store capabilities with OpenSearch.

func NewStore

func NewStore(ctx context.Context, config StoreConfig) (*Store, error)

NewStore performs schema setup during construction, which is why it takes a context: a store returned before its index mapping exists would fail on the first index rather than at wiring, where the misconfiguration actually is.

func (*Store) DeleteIDs

func (s *Store) DeleteIDs(ctx context.Context, ids []string) (err error)

func (*Store) DeleteWhere

func (s *Store) DeleteWhere(ctx context.Context, expr filter.Predicate) (err error)

func (*Store) Index

func (s *Store) Index(ctx context.Context, request *vectorstore.IndexRequest) (err error)

func (*Store) Search

func (s *Store) Search(ctx context.Context, req *vectorstore.SearchRequest) (response *vectorstore.SearchResponse, err error)

type StoreConfig

type StoreConfig struct {
	// Client is the typed OpenSearch transport.
	Client *opensearchapi.Client

	// IndexName names the OpenSearch index. An empty value selects
	// [DefaultIndexName].
	IndexName string

	// EmbeddingField is the knn_vector field name. An empty value selects
	// [DefaultEmbeddingField].
	EmbeddingField string

	// ContentField stores document text. An empty value selects
	// [DefaultContentField].
	ContentField string

	// MetadataField owns document metadata. An empty value selects
	// [DefaultMetadataField]; OpenSearch filters therefore address metadata
	// beneath this field rather than flattening it into the document root.
	MetadataField string

	// EmbeddingModel produces vectors for indexed documents and search queries.
	EmbeddingModel embedding.Model

	// DocumentBatcher bounds each OpenSearch bulk request.
	DocumentBatcher vectorstore.Batcher

	// Dimensions fixes the knn_vector width when creating an index. Zero defers
	// discovery to EmbeddingModel, but only when the index must be created.
	Dimensions int

	// SpaceType selects the index similarity space. An empty value selects
	// [SpaceTypeCosine].
	SpaceType SpaceType

	// Engine selects the index ANN implementation. An empty value selects
	// [EngineLucene].
	Engine Engine

	// MethodName selects the ANN method. An empty value selects hnsw; ivf is
	// valid only with [EngineFaiss].
	MethodName string

	// InitializeSchema permits NewStore to create a missing index. When false,
	// a missing index is reported as [ErrIndexMissing]. Either way an index
	// that already exists is checked against these settings and refused with
	// [ErrIncompatibleIndex] when it disagrees.
	InitializeSchema bool
}

StoreConfig defines one OpenSearch index binding. Field names and ANN settings become persistent index-schema policy, while Client, EmbeddingModel, and DocumentBatcher are runtime collaborators retained by Store.

func (StoreConfig) Validate

func (s StoreConfig) Validate() error

Jump to

Keyboard shortcuts

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