You are currently viewing GoからOpenSearchを利用してみる その2

GoからOpenSearchを利用してみる その2

前回の投稿でGoからOpenSearchに検索を行ってみました。
クエリ文字列をそのまま利用していたので、今回は構造体でクエリ構造を再現できないか実験してみます。

今回のコード

package main

import (
	"context"
	"crypto/tls"
	"encoding/json"
	"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"

type QueryStructure struct {
	Size  int `json:"size"`
	Query struct {
		Match struct {
			CustomerFullName string `json:"customer_full_name"`
		} `json:"match"`
	} `json:"query"`
}

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)
	}

	// クエリ構造体に設定
	query := QueryStructure{}
	query.Size = 10
	query.Query.Match.CustomerFullName = "Eddie"

	// Search for the document.
	queryStr, _ := json.Marshal(query)
	content := strings.NewReader(string(queryStr))

	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()
}

新規でクエリ構造体を定義し、その構造体をもとに「json.Marshal」でjson文字列に変換。
そしてクエリを発行できるところまで確認ができました。

構造体を利用したことに対しての疑問

今回使用した方法だと、構造体のフィールドにインデックスのフィールド名をそのまま利用しているため、汎用性が皆無です!
ただ、QueryDSLをそのままGoの構造体に変換すると、こうならざるを得ない気がするので、クエリ作成部分の処理はもう少し考える必要がありそうです。

現実的には、検索条件用の構造体を準備して、実際のクエリ文字列を作成する時に条件分岐に利用する感じで作るのが良いのかなぁ・・・
GoとOpenSearchがうまく連携できるように、もう少し色々見て見る予定です。

コメントを残す