ブログ

Elasticsearch Go クライアントでテキストクエリを実行する

実際の例を通して、Elasticsearch Go クライアントを使用して Elasticsearch で従来のテキスト クエリを実行する方法を学びます。

Go を含むあらゆるプログラミング言語でソフトウェアを構築することは、生涯にわたる学習に取り組むことです。大学時代および仕事のキャリアを通じて、Carly は多言語話者になることに適応し、Python、C、JavaScript、TypeScript、Java など、多くのプログラミング言語に触れる必要がありました。しかし、それだけでは十分ではありませんでした!それで最近彼女も囲碁を始めました!

動物、プログラミング言語、そして親切な著者の一人と同じように、検索もさまざまな方法の進化を遂げており、独自の検索ユースケースに応じてどれを選択するかを決めるのは難しい場合があります。このブログでは、従来のキーワード検索の概要と、 Elasticsearch Elasticsearch Go クライアント を使用した 例を 紹介します。

要件

この例を実行するには、次の前提条件が満たされていることを確認してください。

  1. Goバージョン1.21以降のインストール

  2. Go ドキュメントに記載されている推奨構造とパッケージ管理を使用して、独自の Go リポジトリを作成します。

  3. 独自の Elasticsearch クラスターを作成し、Wikipedia のフレンドリーな Gopher を含む一連の げっ歯類ベースのページ を設定します。

Wikipedia Gopherページ

Elasticsearchへの接続

この例では、Go クライアントが提供するTyped APIを使用します。クエリに対して安全な接続を確立するには、次のいずれかを使用してクライアントを構成する必要があります。

  1. Elastic Cloud を利用する場合のクラウド ID と API キー。

  2. クラスター URL、ユーザー名、パスワード、証明書。

Elastic Cloud にあるクラスターに接続すると、次のようになります。

func GetElasticsearchClient() (*elasticsearch.TypedClient, error) {
	var cloudID = os.Getenv("ELASTIC_CLOUD_ID")
	var apiKey = os.Getenv("ELASTIC_API_KEY")

	var es, err = elasticsearch.NewTypedClient(elasticsearch.Config{
		CloudID: cloudID,
		APIKey:  apiKey,
		Logger:  &elastictransport.ColorLogger{os.Stdout, true, true},
	})

	if err != nil {
		return nil, fmt.Errorf("unable to connect: %w", err)
	}

	return es, nil
}

後ほど示すように、 client接続は検索に使用できます。

キーワード検索

キーワード検索は、1990 年に初めて文書化されたインターネット検索エンジンであるArchieの誕生以来、私たちがよく知っている基本的な検索タイプです。

キーワード検索の中心的な要素は、ドキュメントを転置インデックスに変換することです。教科書の巻末にある索引とまったく同じように、転置索引にはトークンのリストと各文書内でのその位置とのマッピングが含まれています。以下の図は、インデックス生成の主要な段階を示しています。

転置インデックス生成

上記のように、Elasticsearch でのトークンの生成は、次の 3 つの主要な段階で構成されます。

  1. 0 個以上のchar_filtersを使用して不要な文字を削除します。この例では、 html_stripフィルターを使用してbody_contentフィールド内の HTML 要素を削除しています。

  2. standardトークナイザーを使用してコンテンツからトークンを分割します。スペースとキーの句読点によって分割されます。

  3. 不要なトークンを削除したり、 lowercaseトークン フィルターなどの 0 個以上のfilterオプションや、 snowballステマーなどのステマーを使用してトークンを言語ルートに戻すことで、トークナイザーの出力ストリームからトークンを変換します。

Go で Elasticsearch を検索する

Go クライアントでクエリを実行するときは、以下の例のように、検索するインデックスを指定し、クエリとその他のオプションを渡します。

func KeywordSearch(client *elasticsearch.TypedClient, term string) ([]Rodent, error) {
	res, err := client.Search().
		Index("search-rodents").
		Query(&types.Query{
			Match: map[string]types.MatchQuery{
				"title": {Query: term},
			},
		}).
		From(0).
		Size(10).
		Do(context.Background())

	if err != nil {
		return nil, fmt.Errorf("could not search for rodents: %w", err)
	}

	return getRodents(res.Hits.Hits)
}

上記の例では、標準のmatchクエリを実行して、関数に渡された特定の文字列を含むインデックス内のドキュメントを検索します。Do(context.Background())を介して新しい空のコンテキストを検索実行に渡すことに注意してください。さらに、Elasticsearch によって返されたエラーは、ログ記録とエラー処理のためにerr属性に出力されます。

結果は、ドキュメント自体を JSON 形式で含む_Source属性とともにres.Hits.Hitsに返されます。このソースを Go 対応の構造体に変換するには、次の例に示すように、Go encoding/json パッケージを 使用して JSON 応答を アンマーシャリングする 必要があります。

func getRodents(hits []types.Hit) ([]Rodent, error) {
	var rodents []Rodent

	for _, hit := range hits {
		var currentRodent Rodent
		err := json.Unmarshal(hit.Source_, &currentRodent)

		if err != nil {
			return nil, fmt.Errorf("an error occurred while unmarshaling rodent %s: %w", hit.Id_, err)
		}

		currentRodent.ID = hit.Id_
		rodents = append(rodents, currentRodent)
	}

	return rodents, nil
}

クエリgopherを検索してアンマーシャリングすると、期待どおりに Gopher の Wikipedia ページが返されます。

[
  {ID:64f74ecd4acb3df024d91112 Title:Gopher - Wikipedia Url:https://en.wikipedia.org/wiki/Gopher}
]

しかし、 What do Gophers eat?に問い合わせても、期待する結果は得られません。

[]

シンプルなキーワード検索により、私たちが普段使用しているアプリケーションと同じように、Go アプリケーションに高いパフォーマンスで結果を返すことができます。また、特定の会社や用語を検索するなどのシナリオに関連する用語の完全一致にも最適です。

しかし、上で見たように、語彙の不一致の問題により、文脈と意味を識別するのが困難です。さらに、画像や音声などのテキスト以外のファイル形式のサポートも困難です。

まとめ

ここでは、 Elasticsearch Go クライアントを使用して Elasticsearch で従来のテキスト クエリを実行する方法について説明しました。Go はインフラストラクチャのスクリプトや Web サーバーの構築に広く使用されているため、Go で検索する方法を知っておくと便利です。

このシリーズのすべてのコードについては、 GitHub リポジトリをご覧ください。パート 2に進み、ベクトル検索の概要と、Go でベクトル検索を実行する方法について説明します。それまでは、楽しいホリネズミ狩りを!

各種資料

  1. Elasticsearchガイド

  2. Elasticsearch Goクライアント

  3. Elasticsearch の分析(アナライザー)を理解する by Bo Andersen | #CodingExplained

関連記事

Elasticsearch Goクライアントを使用してElasticsearchでベクトル検索を実行する

Carly Richmond

ElasticsearchとGoを使用して、ホリネズミ狩りをハイブリッド検索

Carly Richmond

最先端の検索体験を構築する準備はできましたか?

十分に高度な検索は 1 人の努力だけでは実現できません。Elasticsearch は、データ サイエンティスト、ML オペレーター、エンジニアなど、あなたと同じように検索に情熱を傾ける多くの人々によって支えられています。ぜひつながり、協力して、希望する結果が得られる魔法の検索エクスペリエンスを構築しましょう。

はじめましょう