OpenSearchを利用する場合、何かしらのプログラムから利用することにあるかと思います。
今回はGoからOpenSearchを利用してみようと思います。
といっても、OpenSearch公式に一通りのサンプルが用意されているため、記載されている方法にて実装します。
ドキュメントはこちらです
https://opensearch.org/docs/latest/clients/go/
早速コード
公式ドキュメントを流用しています。
package main
import (
"context"
"crypto/tls"
"fmt"
"net/http"
"os"
"strings"
opensearch "github.com/opensearch-project/opensearch-go"
opensearchapi "github.com/opensearch-project/opensearch-go/opensearchapi"
)
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://localhost: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()
}
上記を実行すると、以下のような実行結果が得られます。
インデックス作成からデータの追加、検索、そしてインデックス削除まで一連の流れがgoから行うことができます。
使い方も比較的シンプルですね
サンプルデータに対して検索をかけてみる
次はOpenSearchのサンプルデータ「opensearch_dashboards_sample_data_ecommerce」に対して検索を行ってみます。
package main
import (
"context"
"crypto/tls"
"fmt"
"net/http"
"os"
"strings"
opensearch "github.com/opensearch-project/opensearch-go"
opensearchapi "github.com/opensearch-project/opensearch-go/opensearchapi"
)
const IndexName = "opensearch_dashboards_sample_data_ecommerce"
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://localhost: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())
// Search for the document.
content := strings.NewReader(`{
"size": 5,
"query": {
"match": {
"customer_full_name" : "Mary"
}
}
}`)
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()
}
検索だけならこれだけで実行できます。
サンプルデータに対して、顧客名が「Mary」を含むデータを検索しています。
実行結果は以下の通り。
思ったよりデータがたくさん帰ってきたため(154件)、すべての結果は載せていませんが、JSON形式でデータが返ってきました。
これなら、json.Unmarshalで構造体に変換するもの簡単にできそうです。
ただクエリの部分はJSON形式の文字列で渡す必要があるので、プログラムでクエリを組み立てるのが少し大変そうです。
別途、ヘルパーのような仕組みが無いか、調べてみるつもりです。
created by Rinker
¥3,300
(2024/10/27 14:16:59時点 楽天市場調べ-詳細)
created by Rinker
¥4,180
(2024/10/27 14:06:47時点 楽天市場調べ-詳細)