Documentation
¶
Overview ¶
Package opensearch provides a Go client for the OpenSearch REST API.
This client provides a type-safe, ergonomic interface for interacting with OpenSearch clusters. It supports all major OpenSearch features including:
- Document CRUD operations
- Full-text search and complex queries
- Aggregations and analytics
- Index lifecycle management
- Cross-cluster replication
- Security and access control
- And many more features
Quick Start ¶
Create a client:
import (
"github.com/disaster37/opensearch/v4"
"github.com/sirupsen/logrus"
)
func main() {
logger := logrus.NewEntry(logrus.StandardLogger())
client, err := opensearch.New(&opensearch.Config{
URL: "https://localhost:9200",
Username: "admin",
Password: "admin",
TLSSkipVerify: true, // For development only
}, logger)
if err != nil {
log.Fatal(err)
}
// Use the client to interact with OpenSearch
// ...
}
Package Organization ¶
The client is organized into several sub-packages:
- types: Common types and error handling
- api: Service interfaces for OpenSearch REST APIs
- querydsl: Query and aggregation builder DSL
Most users will only need to import the root package. The sub-packages are automatically re-exported for convenience.
Service Access ¶
Access OpenSearch features through service methods on the Client interface:
// Document operations
client.Document().Index(ctx, "my-index", doc, "doc-id", nil)
client.Document().Get(ctx, "my-index", "doc-id", nil)
client.Document().Delete(ctx, "my-index", "doc-id", nil)
// Search operations
client.Search().Search(ctx, []string{"my-index"}, query, nil)
client.Search().Count(ctx, []string{"my-index"}, query)
// Index operations
client.Indices().Create(ctx, "my-index", nil)
client.Indices().Delete(ctx, "my-index", nil)
// Cluster operations
client.Cluster().Health(ctx, []string{"my-index"}, nil)
client.Cluster().Stats(ctx, nil)
Using the Query DSL ¶
For complex queries, use the querydsl sub-package to build type-safe queries:
import "github.com/disaster37/opensearch/v4/querydsl"
// Build a bool query
query := querydsl.BoolQuery().
Must(querydsl.MatchQuery("status", "published")).
Filter(querydsl.RangeQuery("date").Gte("2024-01-01")).
Should(querydsl.TermQuery("featured", true))
// Execute the search
result, err := client.Search().Search(ctx, []string{"my-index"}, query.JSON(), nil)
Error Handling ¶
All operations can return an OpenSearchError. Use the helper functions to check for specific error conditions:
result, err := client.Document().Get(ctx, "my-index", "doc-id", nil)
if err != nil {
if os.IsNotFound(err) {
log.Println("Document not found")
} else if os.IsConflict(err) {
log.Println("Version conflict")
} else {
log.Fatal(err)
}
}
Type Aliases ¶
For convenience, common types from the types sub-package are re-exported in the root package:
- OpenSearchError
- AcknowledgedResponse
- ShardsInfo
- BroadcastResponse
- DocumentVersion
You can use these directly without importing the types package:
version := os.DocumentVersion{SeqNo: 1, PrimaryTerm: 1}
client.Document().Index(ctx, "my-index", doc, "doc-id", &version)
Index ¶
- func DefaultRetryConditions() []resty.RetryConditionFunc
- func IsConflict(err error) bool
- func IsNotFound(err error) bool
- func PITSearchRetryConditions() []resty.RetryConditionFunc
- type AcknowledgedResponse
- type BroadcastResponse
- type Client
- type CommonParams
- type Config
- type DefaultClient
- func (c *DefaultClient) AD() api.AdService
- func (c *DefaultClient) Alerting() api.AlertingService
- func (c *DefaultClient) AsyncSearch() api.AsyncSearchService
- func (c *DefaultClient) CCR() api.CcrService
- func (c *DefaultClient) Cat() api.CatService
- func (c *DefaultClient) Cluster() api.ClusterService
- func (c *DefaultClient) Document() api.DocumentService
- func (c *DefaultClient) ISM() api.IsmService
- func (c *DefaultClient) Indices() api.IndicesService
- func (c *DefaultClient) Info() api.InfoService
- func (c *DefaultClient) Ingest() api.IngestService
- func (c *DefaultClient) KNN() api.KnnService
- func (c *DefaultClient) ML() api.MlService
- func (c *DefaultClient) Neural() api.NeuralService
- func (c *DefaultClient) Nodes() api.NodesService
- func (c *DefaultClient) RestyClient() *resty.Client
- func (c *DefaultClient) Rollup() api.RollupService
- func (c *DefaultClient) SM() api.SmService
- func (c *DefaultClient) SQL() api.SqlService
- func (c *DefaultClient) Script() api.ScriptService
- func (c *DefaultClient) Search() api.SearchService
- func (c *DefaultClient) Security() api.SecurityService
- func (c *DefaultClient) Snapshot() api.SnapshotService
- func (c *DefaultClient) Tasks() api.TasksService
- func (c *DefaultClient) Transform() api.TransformService
- type DocumentVersion
- type ErrorDetails
- type FailedNodeException
- type ListResponse
- type OpenSearchError
- type OpenSearchErrorDetails
- type ScriptErrorPosition
- type ShardOperationFailedException
- type ShardsInfo
- type UnixMilliTime
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DefaultRetryConditions ¶
func DefaultRetryConditions() []resty.RetryConditionFunc
DefaultRetryConditions returns the default retry conditions that handle: - Network errors (no response received) - 429 Too Many Requests status code - 5xx server error status codes (excluding 501 Not Implemented)
These conditions are automatically applied when RetryCount > 0, but you can use this function to build custom retry logic that includes the defaults.
func IsConflict ¶
IsConflict returns true when err is an OpenSearchError with status 409. This typically indicates a version conflict during an optimistic concurrency operation (see DocumentVersion).
func IsNotFound ¶
IsNotFound returns true when err is an OpenSearchError with status 404. Use this to branch on "document or index not found" cases without inspecting the error details manually:
res, err := client.Document().Get(ctx, "my-index", "doc-id", nil)
if err != nil {
if opensearch.IsNotFound(err) {
log.Printf("document missing; creating fresh copy")
// insert new document
} else {
return err
}
}
_ = res
Example ¶
package main
import (
"context"
"fmt"
"log"
opensearch "github.com/disaster37/opensearch/v4"
"github.com/disaster37/opensearch/v4/api"
"github.com/sirupsen/logrus"
)
func main() {
logger := logrus.NewEntry(logrus.StandardLogger())
client, err := opensearch.New(&opensearch.Config{
URL: "http://localhost:9200",
}, logger)
if err != nil {
log.Fatal(err)
}
_, err = client.Document().Get(context.Background(), &api.GetRequest{
Index: "my-index",
Id: "missing-id",
})
if err != nil {
if opensearch.IsNotFound(err) {
fmt.Println("document not found; creating fresh one")
} else if opensearch.IsConflict(err) {
fmt.Println("version conflict: refetch and retry")
} else {
log.Fatal(err)
}
}
}
Output:
func PITSearchRetryConditions ¶
func PITSearchRetryConditions() []resty.RetryConditionFunc
PITSearchRetryConditions returns retry conditions specifically optimized for Point-in-Time (PIT) search queries and other long-running OpenSearch operations. Includes default conditions plus additional OpenSearch-specific scenarios.
Types ¶
type AcknowledgedResponse ¶
type AcknowledgedResponse = types.AcknowledgedResponse
AcknowledgedResponse is the common response for operations that are simply acknowledged or rejected. Returned by most indices and cluster operations.
type BroadcastResponse ¶
type BroadcastResponse = types.BroadcastResponse
BroadcastResponse is the common response for broadcast-style operations (operations applied to all shards in a set of indices).
type Client ¶
type Client interface {
// RestyClient returns the underlying resty client for middleware
// configuration (e.g., adding OpenTelemetry tracing).
RestyClient() *resty.Client
Document() api.DocumentService
Search() api.SearchService
Indices() api.IndicesService
Cluster() api.ClusterService
Nodes() api.NodesService
Cat() api.CatService
Ingest() api.IngestService
Snapshot() api.SnapshotService
Tasks() api.TasksService
Script() api.ScriptService
Security() api.SecurityService
ISM() api.IsmService
SM() api.SmService
Alerting() api.AlertingService
Transform() api.TransformService
CCR() api.CcrService
Info() api.InfoService
Rollup() api.RollupService
ML() api.MlService
SQL() api.SqlService
AD() api.AdService
AsyncSearch() api.AsyncSearchService
KNN() api.KnnService
Neural() api.NeuralService
}
Client is the main entry point for all OpenSearch operations.
Obtain a Client via New. All API groups are accessible as methods on this interface:
client, err := opensearch.New(&opensearch.Config{...}, logger)
client.Document().Index(ctx, "idx", doc, "id", nil)
client.Search().Search(ctx, []string{"idx"}, query, nil)
client.Indices().Create(ctx, "new-idx", settings)
client.Cluster().Health(ctx, nil, nil)
func New ¶
New creates a new Client connecting to an OpenSearch cluster.
The returned client builds a resty HTTP client internally, applies TLS and authentication from cfg, and instantiates all 18 service interfaces.
Example with retry configuration for long-running queries (like Point-in-Time searches):
client, err := opensearch.New(&opensearch.Config{
URL: "https://localhost:9200",
Username: "admin",
Password: "admin",
RetryCount: 3,
RetryWaitTime: 500 * time.Millisecond,
RetryMaxWaitTime: 5 * time.Second,
RetryConditions: opensearch.PITSearchRetryConditions(),
}, logrus.NewEntry(logrus.StandardLogger()))
Example ¶
package main
import (
"context"
"fmt"
"log"
opensearch "github.com/disaster37/opensearch/v4"
"github.com/sirupsen/logrus"
)
func main() {
logger := logrus.NewEntry(logrus.StandardLogger())
client, err := opensearch.New(&opensearch.Config{
URL: "https://localhost:9200",
Username: "admin",
Password: "admin",
}, logger)
if err != nil {
log.Fatal(err)
}
health, err := client.Cluster().Health(
context.Background(),
nil,
)
if err != nil {
log.Fatal(err)
}
fmt.Printf("cluster %s: %s\n", health.ClusterName, health.Status)
}
Output:
Example (DefaultRetry) ¶
package main
import (
"fmt"
"log"
"time"
"github.com/disaster37/opensearch/v4"
"github.com/sirupsen/logrus"
)
func main() {
logger := logrus.NewEntry(logrus.New())
// Example: Use default retry conditions (network errors, 429, 5xx)
client, err := opensearch.New(&opensearch.Config{
URL: "https://localhost:9200",
Username: "admin",
Password: "admin",
RetryCount: 2,
RetryWaitTime: 100 * time.Millisecond,
RetryMaxWaitTime: 2 * time.Second,
RetryConditions: opensearch.DefaultRetryConditions(),
}, logger)
if err != nil {
log.Fatal(err)
}
_ = client
fmt.Println("Client with default retry conditions")
}
Output: Client with default retry conditions
Example (WithRetry) ¶
package main
import (
"fmt"
"log"
"time"
"github.com/disaster37/opensearch/v4"
"github.com/sirupsen/logrus"
)
func main() {
logger := logrus.NewEntry(logrus.New())
// Example: Configure client with retry for long-running queries like PIT searches
client, err := opensearch.New(&opensearch.Config{
URL: "https://localhost:9200",
Username: "admin",
Password: "admin",
RetryCount: 3,
RetryWaitTime: 500 * time.Millisecond,
RetryMaxWaitTime: 5 * time.Second,
RetryConditions: opensearch.PITSearchRetryConditions(),
}, logger)
if err != nil {
log.Fatal(err)
}
// The client will now automatically retry failed requests up to 3 times
// with exponential backoff between 500ms and 5s, including OpenSearch-specific
// transient errors like search_phase_execution_exception.
_ = client
fmt.Println("Client configured with retry settings")
}
Output: Client configured with retry settings
type CommonParams ¶
type CommonParams = types.CommonParams
CommonParams are the query parameters common to all OpenSearch API requests. They are forwarded to all service methods via [DocumentService], [SearchService], etc.
type Config ¶
type Config struct {
// URL is the OpenSearch cluster address. Required.
// Examples: "https://localhost:9200", "http://cluster:9200"
URL string
// Username for HTTP basic authentication.
Username string
// Password for HTTP basic authentication.
Password string
// TLSSkipVerify disables TLS certificate verification.
// WARNING: Only set to true for development. For production, use CACert.
TLSSkipVerify bool
// CACert is a PEM-encoded CA certificate used to verify the server.
// If empty and TLSSkipVerify is false, the system cert pool is used.
CACert []byte
// Timeout is the HTTP request timeout. Zero means no timeout.
Timeout time.Duration
// IdleConnTimeout is the maximum amount of time an idle (keep-alive)
// connection is kept in the pool before being closed.
// Set it below the keep-alive timeout of any intermediate proxy
// (e.g. an nginx ingress, default 75s) to avoid reusing a connection
// the peer has already closed, which surfaces as
// "connection reset by peer". Zero keeps the Go default (90s).
IdleConnTimeout time.Duration
// DisableHTTP2 forces the client to use HTTP/1.1 instead of negotiating
// HTTP/2 via TLS ALPN.
//
// HTTP/2 multiplexes every request onto a single TCP connection. When an
// intermediary (load balancer, firewall, ingress front proxy) resets that
// connection, all in-flight streams fail at once and surface as
// "connection reset by peer". For sequential workloads (e.g. paginated
// PIT/search_after exports) HTTP/2 brings no benefit, so forcing HTTP/1.1
// isolates each request and makes transient resets cheap to retry.
DisableHTTP2 bool
// RetryCount is the maximum number of retry attempts for failed requests.
// Default is 0 (no retries). Set to a positive integer to enable retries.
RetryCount int
// RetryWaitTime is the minimum wait time between retry attempts.
// Default is 100ms if not specified.
RetryWaitTime time.Duration
// RetryMaxWaitTime is the maximum wait time between retry attempts.
// Default is 2s if not specified.
RetryMaxWaitTime time.Duration
// RetryConditions are custom functions that determine if a request should be retried.
// By default, resty retries on network errors, 429 Too Many Requests, and 5xx server errors.
// Add custom conditions to extend the default behavior.
RetryConditions []resty.RetryConditionFunc
}
Config holds configuration for the OpenSearch client.
type DefaultClient ¶
type DefaultClient struct {
// contains filtered or unexported fields
}
DefaultClient is the default Client implementation returned by New.
func (*DefaultClient) AD ¶
func (c *DefaultClient) AD() api.AdService
func (*DefaultClient) Alerting ¶
func (c *DefaultClient) Alerting() api.AlertingService
func (*DefaultClient) AsyncSearch ¶
func (c *DefaultClient) AsyncSearch() api.AsyncSearchService
func (*DefaultClient) CCR ¶
func (c *DefaultClient) CCR() api.CcrService
func (*DefaultClient) Cat ¶
func (c *DefaultClient) Cat() api.CatService
func (*DefaultClient) Cluster ¶
func (c *DefaultClient) Cluster() api.ClusterService
func (*DefaultClient) Document ¶
func (c *DefaultClient) Document() api.DocumentService
func (*DefaultClient) ISM ¶
func (c *DefaultClient) ISM() api.IsmService
func (*DefaultClient) Indices ¶
func (c *DefaultClient) Indices() api.IndicesService
func (*DefaultClient) Info ¶
func (c *DefaultClient) Info() api.InfoService
func (*DefaultClient) Ingest ¶
func (c *DefaultClient) Ingest() api.IngestService
func (*DefaultClient) KNN ¶
func (c *DefaultClient) KNN() api.KnnService
func (*DefaultClient) ML ¶
func (c *DefaultClient) ML() api.MlService
func (*DefaultClient) Neural ¶
func (c *DefaultClient) Neural() api.NeuralService
func (*DefaultClient) Nodes ¶
func (c *DefaultClient) Nodes() api.NodesService
func (*DefaultClient) RestyClient ¶
func (c *DefaultClient) RestyClient() *resty.Client
func (*DefaultClient) Rollup ¶
func (c *DefaultClient) Rollup() api.RollupService
func (*DefaultClient) SM ¶
func (c *DefaultClient) SM() api.SmService
func (*DefaultClient) SQL ¶
func (c *DefaultClient) SQL() api.SqlService
func (*DefaultClient) Script ¶
func (c *DefaultClient) Script() api.ScriptService
func (*DefaultClient) Search ¶
func (c *DefaultClient) Search() api.SearchService
func (*DefaultClient) Security ¶
func (c *DefaultClient) Security() api.SecurityService
func (*DefaultClient) Snapshot ¶
func (c *DefaultClient) Snapshot() api.SnapshotService
func (*DefaultClient) Tasks ¶
func (c *DefaultClient) Tasks() api.TasksService
func (*DefaultClient) Transform ¶
func (c *DefaultClient) Transform() api.TransformService
type DocumentVersion ¶
type DocumentVersion = types.DocumentVersion
DocumentVersion carries the seq_no and primary_term used for optimistic concurrency control in document write operations.
Pass a DocumentVersion to [DocumentService.Index], [DocumentService.Update], or [DocumentService.Delete] to fail the operation if the document has been modified since it was last fetched.
Example ¶
package main
import (
"context"
"fmt"
"log"
opensearch "github.com/disaster37/opensearch/v4"
"github.com/disaster37/opensearch/v4/api"
"github.com/sirupsen/logrus"
)
func main() {
logger := logrus.NewEntry(logrus.StandardLogger())
client, err := opensearch.New(&opensearch.Config{
URL: "http://localhost:9200",
}, logger)
if err != nil {
log.Fatal(err)
}
doc, err := client.Document().Get(context.Background(), &api.GetRequest{
Index: "my-index",
Id: "doc-1",
})
if err != nil {
log.Fatal(err)
}
newSource := map[string]any{"name": "updated"}
if doc.SeqNo == nil || doc.PrimaryTerm == nil {
log.Fatal("document has no seq_no/primary_term; refetch")
}
_, err = client.Document().Update(
context.Background(),
&api.UpdateRequest{
Index: "my-index",
Id: "doc-1",
Body: newSource,
Params: &api.UpdateParams{
IfSeqNo: doc.SeqNo,
IfPrimaryTerm: doc.PrimaryTerm,
},
},
)
if err != nil {
if opensearch.IsConflict(err) {
fmt.Println("conflict; retry the read-modify-write cycle")
} else {
log.Fatal(err)
}
}
}
Output:
type ErrorDetails ¶
type ErrorDetails = types.OpenSearchErrorDetails
ErrorDetails is an alias for OpenSearchErrorDetails for backward compatibility.
type FailedNodeException ¶
type FailedNodeException = types.FailedNodeException
FailedNodeException represents a failure that occurred on a specific node during a multi-node operation (e.g., [NodesService.Info]).
type ListResponse ¶
type ListResponse[T any] = types.ListResponse[T]
ListResponse is a generic list-response wrapper used by plugin services (ISM, SM, Alerting, Transform).
type OpenSearchError ¶
type OpenSearchError = types.OpenSearchError
OpenSearchError is the structured error returned by OpenSearch when a request fails. Use IsNotFound and IsConflict for common checks.
type OpenSearchErrorDetails ¶
type OpenSearchErrorDetails = types.OpenSearchErrorDetails
OpenSearchErrorDetails contains the detailed error payload of an OpenSearchError, including root causes and stack traces for scripting errors.
type ScriptErrorPosition ¶
type ScriptErrorPosition = types.ScriptErrorPosition
ScriptErrorPosition describes where in a script an error occurred (used inside OpenSearchErrorDetails for scripting errors).
type ShardOperationFailedException ¶
type ShardOperationFailedException = types.ShardOperationFailedException
ShardOperationFailedException describes a single shard failure in a ShardsInfo response.
type ShardsInfo ¶
type ShardsInfo = types.ShardsInfo
ShardsInfo represents the "_shards" section of most OpenSearch responses. Reports the number of successful, failed, and pending shard operations.
type UnixMilliTime ¶
type UnixMilliTime = types.UnixMilliTime
UnixMilliTime is a time.Time that serializes to/from Unix milliseconds. Used by the CCR and plugin APIs to represent timestamps.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package api provides service interfaces for interacting with OpenSearch REST API endpoints.
|
Package api provides service interfaces for interacting with OpenSearch REST API endpoints. |
|
Package querydsl provides a programmatic, type-safe query builder DSL for constructing OpenSearch queries and aggregations.
|
Package querydsl provides a programmatic, type-safe query builder DSL for constructing OpenSearch queries and aggregations. |
|
trace
|
|
|
Package types provides the common types and error handling used throughout the OpenSearch client.
|
Package types provides the common types and error handling used throughout the OpenSearch client. |