Go 客户端
OpenSearch Go 客户端允许您将 Go 应用程序连接到 OpenSearch 集群中的数据。本入门指南演示了如何连接到 OpenSearch、索引文档和运行查询。有关客户端的完整 API 文档和更多示例,请参阅Go 客户端 API 文档。
有关客户端源代码,请参阅opensearch-go 仓库。
设置
如果您要启动一个新项目,请运行以下命令创建一个新模块
go mod init <mymodulename>
要将 Go 客户端添加到您的项目,像导入其他模块一样导入它
go get github.com/opensearch-project/opensearch-go
连接到 OpenSearch
要连接到默认的 OpenSearch 主机,如果您正在使用安全插件,请使用地址 https://:9200
创建一个客户端对象
client, err := opensearch.NewClient(opensearch.Config{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
Addresses: []string{"https://:9200"},
Username: "admin", // For testing only. Don't store credentials in code.
Password: "admin",
})
如果您没有使用安全插件,请使用地址 https://:9200
创建一个客户端对象
client, err := opensearch.NewClient(opensearch.Config{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
Addresses: []string{"https://:9200"},
})
连接到 Amazon OpenSearch 服务
以下示例演示了连接到 Amazon OpenSearch 服务
package main
import (
"context"
"log"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
opensearch "github.com/opensearch-project/opensearch-go/v4"
opensearchapi "github.com/opensearch-project/opensearch-go/v4/opensearchapi"
requestsigner "github.com/opensearch-project/opensearch-go/v4/signer/awsv2"
)
const endpoint = "" // e.g. https://opensearch-domain.region.com or Amazon OpenSearch Serverless endpoint
func main() {
ctx := context.Background()
awsCfg, err := config.LoadDefaultConfig(ctx,
config.WithRegion("<AWS_REGION>"),
config.WithCredentialsProvider(
getCredentialProvider("<AWS_ACCESS_KEY>", "<AWS_SECRET_ACCESS_KEY>", "<AWS_SESSION_TOKEN>"),
),
)
if err != nil {
log.Fatal(err) // Do not log.fatal in a production ready app.
}
// Create an AWS request Signer and load AWS configuration using default config folder or env vars.
signer, err := requestsigner.NewSignerWithService(awsCfg, "es")
if err != nil {
log.Fatal(err) // Do not log.fatal in a production ready app.
}
// Create an opensearch client and use the request-signer
client, err := opensearch.NewClient(opensearch.Config{
Addresses: []string{endpoint},
Signer: signer,
})
if err != nil {
log.Fatal("client creation err", err)
}
_ = client
// your code here
}
func getCredentialProvider(accessKey, secretAccessKey, token string) aws.CredentialsProviderFunc {
return func(ctx context.Context) (aws.Credentials, error) {
c := &aws.Credentials{
AccessKeyID: accessKey,
SecretAccessKey: secretAccessKey,
SessionToken: token,
}
return *c, nil
}
}
连接到 Amazon OpenSearch Serverless
以下示例演示了连接到 Amazon OpenSearch 无服务器服务
package main
import (
"context"
"log"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
opensearch "github.com/opensearch-project/opensearch-go/v4"
requestsigner "github.com/opensearch-project/opensearch-go/v4/signer/awsv2"
)
const endpoint = "" // e.g. https://opensearch-domain.region.com or Amazon OpenSearch Serverless endpoint
func main() {
ctx := context.Background()
awsCfg, err := config.LoadDefaultConfig(ctx,
config.WithRegion("<AWS_REGION>"),
config.WithCredentialsProvider(
getCredentialProvider("<AWS_ACCESS_KEY>", "<AWS_SECRET_ACCESS_KEY>", "<AWS_SESSION_TOKEN>"),
),
)
if err != nil {
log.Fatal(err) // Do not log.fatal in a production ready app.
}
// Create an AWS request Signer and load AWS configuration using default config folder or env vars.
signer, err := requestsigner.NewSignerWithService(awsCfg, "aoss")
if err != nil {
log.Fatal(err) // Do not log.fatal in a production ready app.
}
// Create an opensearch client and use the request-signer
client, err := opensearch.NewClient(opensearch.Config{
Addresses: []string{endpoint},
Signer: signer,
})
if err != nil {
log.Fatal("client creation err", err)
}
_ = client
// your code here
}
func getCredentialProvider(accessKey, secretAccessKey, token string) aws.CredentialsProviderFunc {
return func(ctx context.Context) (aws.Credentials, error) {
c := &aws.Credentials{
AccessKeyID: accessKey,
SecretAccessKey: secretAccessKey,
SessionToken: token,
}
}
}
Go 客户端构造函数接受一个 opensearch.Config{}
类型,可以通过选项(例如 OpenSearch 节点地址列表或用户名和密码组合)进行自定义。
要连接到多个 OpenSearch 节点,请在 Addresses
参数中指定它们
var (
urls = []string{"https://:9200", "https://:9201", "https://:9202"}
)
client, err := opensearch.NewClient(opensearch.Config{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
Addresses: urls,
})
Go 客户端默认最多重试请求三次。要自定义重试次数,请设置 MaxRetries
参数。此外,您可以通过设置 RetryOnStatus
参数来更改要重试请求的响应代码列表。以下代码片段创建了一个具有自定义 MaxRetries
和 RetryOnStatus
值的新 Go 客户端
client, err := opensearch.NewClient(opensearch.Config{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
Addresses: []string{"https://:9200"},
MaxRetries: 5,
RetryOnStatus: []int{502, 503, 504},
})
创建索引
要创建 OpenSearch 索引,请使用 IndicesCreateRequest
方法。您可以使用以下代码构建具有自定义设置的 JSON 对象
settings := strings.NewReader(`{
'settings': {
'index': {
'number_of_shards': 1,
'number_of_replicas': 0
}
}
}`)
res := opensearchapi.IndicesCreateRequest{
Index: "go-test-index1",
Body: settings,
}
索引文档
您可以使用 IndexRequest
方法将文档索引到 OpenSearch 中
document := strings.NewReader(`{
"title": "Moneyball",
"director": "Bennett Miller",
"year": "2011"
}`)
docId := "1"
req := opensearchapi.IndexRequest{
Index: "go-test-index1",
DocumentID: docId,
Body: document,
}
insertResponse, err := req.Do(context.Background(), client)
执行批量操作
您可以使用客户端的 Bulk
方法同时执行多项操作。这些操作可以是相同类型,也可以是不同类型。
blk, err := client.Bulk(
strings.NewReader(`
{ "index" : { "_index" : "go-test-index1", "_id" : "2" } }
{ "title" : "Interstellar", "director" : "Christopher Nolan", "year" : "2014"}
{ "create" : { "_index" : "go-test-index1", "_id" : "3" } }
{ "title" : "Star Trek Beyond", "director" : "Justin Lin", "year" : "2015"}
{ "update" : {"_id" : "3", "_index" : "go-test-index1" } }
{ "doc" : {"year" : "2016"} }
`),
)
搜索文档
搜索文档最简单的方法是构建查询字符串。以下代码使用 multi_match
查询在标题和导演字段中搜索“miller”。它提高了“miller”出现在标题字段中的文档的权重
content := strings.NewReader(`{
"size": 5,
"query": {
"multi_match": {
"query": "miller",
"fields": ["title^2", "director"]
}
}
}`)
search := opensearchapi.SearchRequest{
Index: []string{"go-test-index1"},
Body: content,
}
searchResponse, err := search.Do(context.Background(), client)
删除文档
您可以使用 DeleteRequest
方法删除文档
delete := opensearchapi.DeleteRequest{
Index: "go-test-index1",
DocumentID: "1",
}
deleteResponse, err := delete.Do(context.Background(), client)
删除索引
您可以使用 IndicesDeleteRequest
方法删除索引
deleteIndex := opensearchapi.IndicesDeleteRequest{
Index: []string{"go-test-index1"},
}
deleteIndexResponse, err := deleteIndex.Do(context.Background(), client)
示例程序
以下示例程序创建一个客户端,添加一个具有非默认设置的索引,插入一个文档,执行批量操作,搜索该文档,删除该文档,然后删除该索引
package main
import (
"os"
"context"
"crypto/tls"
"fmt"
opensearch "github.com/opensearch-project/opensearch-go"
opensearchapi "github.com/opensearch-project/opensearch-go/opensearchapi"
"net/http"
"strings"
)
const IndexName = "go-test-index1"
func main() {
// Initialize the client with SSL/TLS enabled.
client, err := opensearch.NewClient(opensearch.Config{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
Addresses: []string{"https://:9200"},
Username: "admin", // For testing only. Don't store credentials in code.
Password: "admin",
})
if err != nil {
fmt.Println("cannot initialize", err)
os.Exit(1)
}
// Print OpenSearch version information on console.
fmt.Println(client.Info())
// Define index settings.
settings := strings.NewReader(`{
'settings': {
'index': {
'number_of_shards': 1,
'number_of_replicas': 2
}
}
}`)
// Create an index with non-default settings.
res := opensearchapi.IndicesCreateRequest{
Index: IndexName,
Body: settings,
}
fmt.Println("Creating index")
fmt.Println(res)
// Add a document to the index.
document := strings.NewReader(`{
"title": "Moneyball",
"director": "Bennett Miller",
"year": "2011"
}`)
docId := "1"
req := opensearchapi.IndexRequest{
Index: IndexName,
DocumentID: docId,
Body: document,
}
insertResponse, err := req.Do(context.Background(), client)
if err != nil {
fmt.Println("failed to insert document ", err)
os.Exit(1)
}
fmt.Println("Inserting a document")
fmt.Println(insertResponse)
defer insertResponse.Body.Close()
// Perform bulk operations.
blk, err := client.Bulk(
strings.NewReader(`
{ "index" : { "_index" : "go-test-index1", "_id" : "2" } }
{ "title" : "Interstellar", "director" : "Christopher Nolan", "year" : "2014"}
{ "create" : { "_index" : "go-test-index1", "_id" : "3" } }
{ "title" : "Star Trek Beyond", "director" : "Justin Lin", "year" : "2015"}
{ "update" : {"_id" : "3", "_index" : "go-test-index1" } }
{ "doc" : {"year" : "2016"} }
`),
)
if err != nil {
fmt.Println("failed to perform bulk operations", err)
os.Exit(1)
}
fmt.Println("Performing bulk operations")
fmt.Println(blk)
// Search for the document.
content := strings.NewReader(`{
"size": 5,
"query": {
"multi_match": {
"query": "miller",
"fields": ["title^2", "director"]
}
}
}`)
search := opensearchapi.SearchRequest{
Index: []string{IndexName},
Body: content,
}
searchResponse, err := search.Do(context.Background(), client)
if err != nil {
fmt.Println("failed to search document ", err)
os.Exit(1)
}
fmt.Println("Searching for a document")
fmt.Println(searchResponse)
defer searchResponse.Body.Close()
// Delete the document.
delete := opensearchapi.DeleteRequest{
Index: IndexName,
DocumentID: docId,
}
deleteResponse, err := delete.Do(context.Background(), client)
if err != nil {
fmt.Println("failed to delete document ", err)
os.Exit(1)
}
fmt.Println("Deleting a document")
fmt.Println(deleteResponse)
defer deleteResponse.Body.Close()
// Delete the previously created index.
deleteIndex := opensearchapi.IndicesDeleteRequest{
Index: []string{IndexName},
}
deleteIndexResponse, err := deleteIndex.Do(context.Background(), client)
if err != nil {
fmt.Println("failed to delete index ", err)
os.Exit(1)
}
fmt.Println("Deleting the index")
fmt.Println(deleteIndexResponse)
defer deleteIndexResponse.Body.Close()
}