<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title><![CDATA[Go - Elasticsearch Labs]]></title>
    <description><![CDATA[Articles and tutorials from the Search team at Elastic]]></description>
    <copyright><![CDATA[© 2026. Elasticsearch B.V. All Rights Reserved]]></copyright>
    <image>
      <title><![CDATA[Go - Elasticsearch Labs]]></title>
      <url>https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1121c0bf0e8a6e65/6a88da6340a1841030ef456f/search-labs-thumbnail.png</url>
      <link>https://www.elastic.co/jp/search-labs/blog/category/go-programming</link>
    </image>
    <link>https://www.elastic.co/jp/search-labs/blog/category/go-programming</link>
    <atom:link href="https://www.elastic.co/jp/search-labs/rss/category/go-programming.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[jp]]></language>
    <lastBuildDate>Mon, 21 Sep 2026 20:56:39 GMT</lastBuildDate>
  <item>
    <title><![CDATA[ElasticsearchとGoを使用して、ホリネズミ狩りをハイブリッド検索]]></title>
    <description><![CDATA[Elasticsearch と Elasticsearch Go クライアントを使用してキーワード検索とベクター検索を組み合わせることでハイブリッド検索を実現する方法を学びます。]]></description>
    <content:encoded><![CDATA[<p>このシリーズの前回の記事では、Elasticsearch Go クライアントを<a href="https://www.elastic.co/search-labs/blog/perform-text-queries-with-the-elasticsearch-go-client">従来のキーワード検索</a>と<a href="https://www.elastic.co/search-labs/blog/perform-vector-search-with-the-elasticsearch-go-client">ベクター検索</a>に使用する方法を説明しました。この第 3 部では、ハイブリッド検索について説明します。<a href="https://www.elastic.co/elasticsearch/">Elasticsearch</a> と<a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/index.html"> Elasticsearch</a> Go クライアント を使用して、ベクトル検索とキーワード検索の両方を組み合わせる方法の<a href="https://github.com/carlyrichmond/gopher-hunting-elasticsearch"> 例を</a> 紹介します。</p><h2>要件</h2><p>このシリーズのパート 1 と同様に、この例では次の前提条件が必要です。</p><ol><li><p>Goバージョン1.21以降のインストール</p></li><li><p><a href="https://go.dev/doc/code">Go ドキュメント</a>に記載されている推奨構造とパッケージ管理を使用して、独自の Go リポジトリを作成します。</p></li><li><p>独自の Elasticsearch クラスターを作成し、Wikipedia<a href="https://github.com/carlyrichmond/gopher-hunting-elasticsearch#sources"> のフレンドリーな</a><a href="https://en.wikipedia.org/wiki/Gopher"> Gopher</a> を含む、 げっ歯類ベースのページ セットを設定します。</p></li></ol><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6a436c42996e5172/6a1704cf0c48573d1c01a957/34fa81a9b4c292634c719b8303a9b6b7506d7920-1440x662.png" alt="Wikipedia Gopherページ" /><h2>Elasticsearchへの接続</h2><p>繰り返しになりますが、私たちの例では、Go クライアントが提供する<a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/typedapi.html">Typed API</a>を使用します。クエリに対して安全な接続を確立するには、次のいずれかを使用してクライアントを構成する必要があります。</p><ol><li><p>Elastic Cloud を利用する場合の Cloud ID と API キー</p></li><li><p>クラスターURL、ユーザー名、パスワード、証明書</p></li></ol><p>Elastic Cloud にあるクラスターに接続すると、次のようになります。</p>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:  &amp;elastictransport.ColorLogger{os.Stdout, true, true},
	})

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

	return es, nil
}
<p>後続のセクションで示すように、 <code>client</code>接続は検索に使用できます。</p><h2>ハイブリッド検索の手動ブースティング</h2><p>検索アルゴリズムのセットを組み合わせる場合、従来のアプローチでは、各クエリ タイプを強化するために定数を手動で構成していました。具体的には、クエリごとに係数が指定され、結合された結果セットが予想されるセットと比較され、クエリのリコールが決定されます。次に、いくつかの要因セットを繰り返し、希望する状態に最も近いものを選択します。</p><p>たとえば、 <code>0.8</code>倍の係数でブーストされた単一のテキスト検索クエリと、 <code>0.2</code>倍の係数が低い knn クエリを組み合わせるには、次の例に示すように、両方のクエリ タイプで<code>Boost</code>フィールドを指定します。</p>func HybridSearchWithBoost(client *elasticsearch.TypedClient, term string) ([]Rodent, error) {
	var k = 10
	var numCandidates = 10
	var knnBoost float32 = 0.2
	var queryBoost float32 = 0.8

	res, err := client.Search().
		Index("vector-search-rodents").
		Knn(types.KnnSearch{
			Field:         "text_embedding.predicted_value",
			Boost:         &amp;knnBoost,
			K:             &amp;k,
			NumCandidates: &amp;numCandidates,
			QueryVectorBuilder: &amp;types.QueryVectorBuilder{
				TextEmbedding: &amp;types.TextEmbedding{
					ModelId:   "sentence-transformers__msmarco-minilm-l-12-v3",
					ModelText: term,
				},
			}}).
		Query(&amp;types.Query{
			Match: map[string]types.MatchQuery{
				"title": {
					Query: term,
					Boost: &amp;queryBoost,
				},
			},
		}).
		Do(context.Background())

	if err != nil {
		return nil, err
	}

	return getRodents(res.Hits.Hits)
}
<p>各クエリの<code>Boost</code>オプションで指定された係数がドキュメント スコアに追加されます。一致クエリのスコアを knn クエリよりも大きな係数で増加させることにより、キーワード クエリの結果の重み付けがより大きくなります。</p><p>手動によるブースティングの課題は、特に検索の専門家でない場合、望ましい結果セットにつながる要因を見つけ出すために調整が必要になることです。ランダムな値を試してみて、希望する結果セットに近づくかどうかを調べるだけです。</p><h2>ハイブリッド検索とGoクライアントにおける相互ランク融合</h2><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/rrf.html">Reciprocal Rank Fusion</a> (RRF) は、Elasticsearch 8.9 のハイブリッド検索のテクニカル プレビューとしてリリースされました。チューニングに関連する学習曲線を短縮し、結果セットを最適化するための要素の実験にかかる時間を短縮することを目的としています。</p><p>RRF では、以下のアルゴリズムでスコアをブレンドしてドキュメント スコアが再計算されます。</p>score := 0.0
// q is a query in the set of queries (vector and keyword search)
for _, q := range queries {
    // result(q) is the results 
    if document in result(q) {
        // k is a ranking constant (default 60)
        // rank(result(q), d) is the document's rank within result(q) 
        // range from 1 to the window_size (default 100)
        score +=  1.0 / (k + rank(result(q), d))
    }
}

return score
<p>RRF を使用する利点は、Elasticsearch 内で適切なデフォルト値を利用できることです。ランキング定数<code>k</code>デフォルトは<code>60</code>です。大規模なデータ セットを検索するときに、返されるドキュメントの関連性とクエリ パフォーマンスの間のトレードオフを提供するために、検討される各クエリの結果セットのサイズは<code>window_size</code>の値に制限されます。この値は、<a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/rrf.html#rrf-api">ドキュメント</a>で説明されているように、デフォルトで<code>100</code>になります。</p><p><code>k</code> また、 <code>windows_size</code> 、以下の例のように、Go クライアントの<code>Rank</code>メソッド内の<code>Rrf</code>構成内で構成することもできます。</p>func HybridSearchWithRRF(client *elasticsearch.TypedClient, term string) ([]Rodent, error) {
	var k = 10
	var numCandidates = 10

	// Minimum required window size for the default result size of 10
	var windowSize int64 = 10
	var rankConstant int64 = 42

	res, err := client.Search().
		Index("vector-search-rodents").
		Knn(types.KnnSearch{
			Field:         "text_embedding.predicted_value",
			K:             &amp;k,
			NumCandidates: &amp;numCandidates,
			QueryVectorBuilder: &amp;types.QueryVectorBuilder{
				TextEmbedding: &amp;types.TextEmbedding{
					ModelId:   "sentence-transformers__msmarco-minilm-l-12-v3",
					ModelText: term,
				},
			}}).
		Query(&amp;types.Query{
			Match: map[string]types.MatchQuery{
				"title": {Query: term},
			},
		}).
		Rank(&amp;types.RankContainer{
			Rrf: &amp;types.RrfRank{
				WindowSize:   &amp;windowSize,
				RankConstant: &amp;rankConstant,
			},
		}).
		Do(context.Background())

	if err != nil {
		return nil, err
	}

	return getRodents(res.Hits.Hits)
}
<h2>まとめ</h2><p>ここでは、 <a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/index.html">Elasticsearch Go クライアント</a>を使用して Elasticsearch でベクトル検索とキーワード検索を組み合わせる方法について説明しました。</p><p>このシリーズのすべてのコードについては、 <a href="https://github.com/carlyrichmond/gopher-hunting-elasticsearch">GitHub リポジトリ</a>をご覧ください。まだご覧になっていない方は、このシリーズのすべてのコードについては<a href="https://www.elastic.co/search-labs/blog/perform-text-queries-with-the-elasticsearch-go-client">パート 1</a>と<a href="https://www.elastic.co/search-labs/blog/perform-vector-search-with-the-elasticsearch-go-client">パート 2</a>をご覧ください。</p><p><em>楽しいホリネズミ狩りを！</em></p><h2>各種資料</h2><ol><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html">Elasticsearchガイド</a></p></li><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/index.html">Elasticsearch Goクライアント</a></p></li><li><p><a href="https://www.elastic.co/what-is/vector-search">ベクトル検索とは何ですか?| 弾性</a></p></li><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/rrf.html">相互ランク融合</a></p></li></ol>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/hybrid-search-with-the-elasticsearch-go-client</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/hybrid-search-with-the-elasticsearch-go-client</guid>
    <category><![CDATA[Vector Database]]></category>
    <category><![CDATA[Go]]></category>
    <dc:creator><![CDATA[Carly Richmond,Laurent Saint-Félix]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdcae959696d55a9b/6a1704d5ab7f085a56db9d7c/491ef9efbb30b253e1d9e3b7f816a9a23c8f5264-721x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Thu, 02 Nov 2023 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elasticsearch Goクライアントを使用してElasticsearchでベクトル検索を実行する]]></title>
    <description><![CDATA[実際の例を通して、Elasticsearch Go クライアントを使用して Elasticsearch でベクトル検索を実行する方法を学びます。]]></description>
    <content:encoded><![CDATA[<p>Go を含むあらゆるプログラミング言語でソフトウェアを構築することは、生涯にわたる学習に取り組むことです。Carly は大学時代や仕事を通じて、ベクトル検索の最新かつ最高の実装を含む、数多くのプログラミング言語やテクノロジーに携わってきました。しかし、それだけでは十分ではありませんでした!それで最近カーリーも囲碁を始めました。</p><p>動物、プログラミング言語、そして親しみやすい著者と同じように、検索もさまざまな方法の進化を遂げており、独自の検索ユースケースに応じてどれを選択するかを決めるのは難しい場合があります。このブログでは、ベクトル検索の概要と、<a href="https://www.elastic.co/elasticsearch/"> Elasticsearch</a> および<a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/index.html"> Elasticsearch Go</a> クライアント を使用した各アプローチの<a href="https://github.com/carlyrichmond/gopher-hunting-elasticsearch"> 例を</a> 紹介します。これらの例では、Elasticsearch と Go のベクトル検索を使用して、ホリネズミを見つけて、その食べ物を特定する方法を説明します。</p><h2>要件</h2><p>この例を実行するには、次の前提条件が満たされていることを確認してください。</p><ol><li><p>Goバージョン1.21以降のインストール</p></li><li><p>独自のGoリポジトリを作成する</p></li><li><p>独自の Elasticsearch クラスターを作成し、Wikipedia のフレンドリーな<a href="https://en.wikipedia.org/wiki/Gopher">Gopher</a>を含む一連のげっ歯類ベースのページを設定します。</p></li></ol><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6a436c42996e5172/6a1704cf0c48573d1c01a957/34fa81a9b4c292634c719b8303a9b6b7506d7920-1440x662.png" alt="Wikipedia Gopherページ" /><h2>Elasticsearchへの接続</h2><p>この例では、Go クライアントが提供する<a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/typedapi.html">Typed API</a>を利用します。クエリに対して安全な接続を確立するには、次のいずれかを使用してクライアントを構成する必要があります。</p><ol><li><p>Elastic Cloud を利用する場合のクラウド ID と API キー。</p></li><li><p>クラスター URL、ユーザー名、パスワード、証明書。</p></li></ol><p>Elastic Cloud にあるクラスターに接続すると、次のようになります。</p>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:  &amp;elastictransport.ColorLogger{os.Stdout, true, true},
	})

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

	return es, nil
}
<p>後続のセクションに示すように、 <code>client</code>接続はベクトル検索に使用できます。</p><h2>ベクトル検索</h2><p>ベクトル検索は、検索問題をベクトルを使用した数学的な比較に変換することでこの問題を解決しようとします。ドキュメント埋め込みプロセスには、モデルを使用してドキュメントを高密度ベクトル表現、つまり単純な数値のストリームに変換する追加の段階があります。このアプローチの利点は、画像や音声などのテキスト以外のドキュメントをクエリと一緒にベクトルに変換して検索できることです。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc4b3b9b2ad1e8f46/6a1704d06234e0800fdb1927/b113358093e367358d684f7aaf0a6684ebb2d0dd-1440x653.png" alt="ベクトル探索図" /><p>簡単に言えば、ベクトル検索はベクトル距離の計算のセットです。下の図では、クエリ<code>Go Gopher</code>のベクトル表現がベクトル空間内のドキュメントと比較され、最も近い結果 (定数<code>k</code>で示される) が返されます。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5c736ecfc49bb038/6a1704d2cf4f25bcb6b2d075/54a17a4b41029644e7c66f33d428e8d01a6f4ce3-1184x743.png" alt="Gopherベクトル空間の例" /><p>ドキュメントの埋め込みを生成するために使用するアプローチに応じて、ホリネズミが何を食べるかを調べる方法が 2 つあります。</p><h3>アプローチ1: 独自のモデルを持ち込む</h3><p>Platinum ライセンスでは、モデルをアップロードし、推論 API を使用して Elasticsearch 内で埋め込みを生成できます。モデルの設定には 6 つのステップがあります。</p><ol><li><p>モデル リポジトリからアップロードする PyTorch モデルを選択します。この例では、Hugging Face の<a href="https://huggingface.co/sentence-transformers/msmarco-MiniLM-L-12-v3">sentence-transformers/msmarco-MiniLM-L-12-v3</a>を使用して埋め込みを生成します。</p></li><li><p>Elasticsearch クラスターとタスク タイプ<code>text_embeddings</code>の資格情報を使用して<a href="https://www.elastic.co/guide/en/elasticsearch/client/eland/current/overview.html">、Python 用の Eland Machine Learning クライアント</a>でモデルを Elastic にロードします。Eland がインストールされていない場合は、以下に示すように<a href="https://www.elastic.co/guide/en/machine-learning/current/ml-nlp-import-model.html#ml-nlp-import-docker">Docker を使用してインポート手順を実行</a>できます。</p></li></ol>docker run -it --rm --network host \
    docker.elastic.co/eland/eland \
    eland_import_hub_model \
      --cloud-id $ELASTIC_CLOUD_ID \
      --es-api-key $ELASTIC_API_KEY \
      --hub-model-id sentence-transformers/msmarco-MiniLM-L-12-v3 \
      --task-type text_embedding
<ol><li><p>アップロードしたら、サンプル ドキュメントを使用してモデル<code>sentence-transformers__msmarco-minilm-l-12-v3</code>をすぐにテストし、埋め込みが期待どおりに生成されることを確認します。</p></li></ol><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8a399e1f50ecfdaf/6a1704d4ab7f08935edb9d78/fbbdde621361a487eb07304bed029c228d0f7aa6-1440x789.png" alt="Elastic Test トレーニング済みモデルの例" /><ol><li><p>推論プロセッサを含む取り込みパイプラインを作成します。これにより、アップロードされたモデルを使用してベクター表現を生成できるようになります。</p></li></ol>PUT _ingest/pipeline/search-rodents-vector-embedding-pipeline
{
  "processors": [
    {
      "inference": {
        "model_id": "sentence-transformers__msmarco-minilm-l-12-v3",
        "target_field": "text_embedding",
        "field_map": {
          "body_content": "text_field"
        }
      }
    }
  ]
}
<ol><li><p>各ドキュメントに対して生成されたベクトル埋め込みを格納するための、タイプ<code>dense_vector</code>のフィールド<code>text_embedding.predicted_value</code>を含む新しいインデックスを作成します。</p></li></ol>PUT vector-search-rodents
{
  "mappings": {
    "properties": {
      "text_embedding.predicted_value": {
        "type": "dense_vector",
        "dims": 384,
        "index": true,
        "similarity": "cosine"
      },
      "text": {
        "type": "text"
      }
    }
  }
}
<ol><li><p>新しく作成された取り込みパイプラインを使用してドキュメントのインデックスを再作成し、各ドキュメントの追加フィールド<code>text_embedding.predicted_value</code>としてテキスト埋め込みを生成します。</p></li></ol>POST _reindex
{
  "source": {
    "index": "search-rodents"
  },
  "dest": {
    "index": "vector-search-rodents",
    "pipeline": "search-rodents-vector-embedding-pipeline"
  }
}
<p>次の例に示すように、新しいインデックス<code>vector-search-rodents</code>を使用して、同じ検索 API で<code>Knn</code>オプションを使用できるようになりました。</p>func VectorSearch(client *elasticsearch.TypedClient, term string) ([]Rodent, error) {
  var k = 10
	var numCandidates = 10

	res, err := client.Search().
		Index("vector-search-rodents").
		Knn(types.KnnSearch{
      # Field in document containing vector
			Field:         "text_embedding.predicted_value",
      # Number of neighbors to return
			K:             &amp;k,
      # Number of candidates to evaluate in comparison
			NumCandidates: &amp;numCandidates,
      # Generate query vector using the same model used in the inference processor
			QueryVectorBuilder: &amp;types.QueryVectorBuilder{
				TextEmbedding: &amp;types.TextEmbedding{
					ModelId:   "sentence-transformers__msmarco-minilm-l-12-v3",
					ModelText: term,
				},
			}}).Do(context.Background())

	if err != nil {
		return nil, fmt.Errorf("error in rodents vector search: %w", err)
	}

	return getRodents(res.Hits.Hits)
}
<p>アンマーシャリングによる JSON 結果オブジェクトの変換は、キーワード検索の例とまったく同じ方法で実行されます。定数<code>K</code>と<code>NumCandidates</code>使用すると、返される隣接ドキュメントの数と、シャードごとに考慮する候補の数を設定できます。候補の数を増やすと結果の精度は上がりますが、比較が多く実行されるためクエリの実行時間が長くなることに注意してください。</p><p>クエリ<code>What do Gophers eat?</code>を使用してコードを実行すると、返される結果は以下と同様になり、以前のキーワード検索とは異なり、Gopher の記事に要求された情報が含まれていることが強調表示されます。</p>[
  {ID:64f74ecd4acb3df024d91112 Title:Gopher - Wikipedia Url:https://en.wikipedia.org/wiki/Gopher} 
  {ID:64f74ed34acb3d71aed91fcd Title:Squirrel - Wikipedia Url:https://en.wikipedia.org/wiki/Squirrel} 
  //Other results omitted
]
<h3>アプローチ2：ハグフェイス推論API</h3><p>もう 1 つのオプションは、Elasticsearch の外部で同じ埋め込みを生成し、ドキュメントの一部として取り込むことです。このオプションは Elasticsearch 機械学習ノードを使用しないため、無料利用枠で実行できます。</p><p>Hugging Face は、無料で使用できるレート制限付きの<a href="https://huggingface.co/docs/api-inference/index">推論 API を</a>公開しています。アカウントと API トークンを使用すると、実験やプロトタイピングを開始するために同じ埋め込みを手動で生成できます。実稼働環境での使用は推奨されません。同様のアプローチを使用して、ローカルで独自のモデルを呼び出して埋め込みを生成したり、有料の API を使用したりすることもできます。</p><p>以下の関数<code>GetTextEmbeddingForQuery</code>では、クエリ文字列に対して推論 API を使用して、エンドポイントへの<code>POST</code>リクエストから返されるベクトルを生成します。</p>// HuggingFace text embedding helper
func GetTextEmbeddingForQuery(term string) []float32 {
    // HTTP endpoint
    model := "sentence-transformers/msmarco-minilm-l-12-v3"
    posturl := fmt.Sprintf("https://api-inference.huggingface.co/pipeline/feature-extraction/%s", model)

    // JSON body
    body := []byte(fmt.Sprintf(`{
        "inputs": "%s",
        "options": {"wait_for_model":True}
    }`, term))

    // Create a HTTP post request
    r, err := http.NewRequest("POST", posturl, bytes.NewBuffer(body))

    if err != nil {
        log.Fatal(err)
        return nil
    }

    token := os.Getenv("HUGGING_FACE_TOKEN")
    r.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))

    client := &amp;http.Client{}
    res, err := client.Do(r)
    if err != nil {
        panic(err)
    }

    defer res.Body.Close()

    var post []float32
    derr := json.NewDecoder(res.Body).Decode(&amp;post)

    if derr != nil {
        log.Fatal(derr)
        return nil
    }

    return post
}
<p>結果の<code>[]float32</code>型のベクトルは、 <code>QueryVectorBuilder</code>オプションを使用する代わりに<code>QueryVector</code>として渡され、以前に Elastic にアップロードされたモデルが活用されます。</p>func VectorSearchWithGeneratedQueryVector(client *elasticsearch.TypedClient, term string) ([]Rodent, error) {
	vector, err := GetTextEmbeddingForQuery(term)
	if err != nil {
		return nil, err
	}

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

  var k = 10
	var numCandidates = 10

	res, err := client.Search().
		Index("vector-search-rodents").
		Knn(types.KnnSearch{
      # Field in document containing vector
			Field:         "text_embedding.predicted_value",
      # Number of neighbors to return
			K:             &amp;k,
      # Number of candidates to evaluate in comparison
			NumCandidates: &amp;numCandidates,
      # Query vector returned from Hugging Face inference API
			QueryVector:   vector,
		}).
		Do(context.Background())

	if err != nil {
		return nil, err
	}

	return getRodents(res.Hits.Hits)
}
<p><code>K</code>と<code>NumCandidates</code>オプションは2つのオプションに関係なく同じままであり、埋め込みを生成するために同じモデルを使用しているため、同じ結果が生成されることに注意してください。</p><h2>まとめ</h2><p>ここでは、 <a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/index.html">Elasticsearch Go クライアント</a>を使用して Elasticsearch でベクトル検索を実行する方法について説明しました。このシリーズのすべてのコードについては、 <a href="https://github.com/carlyrichmond/gopher-hunting-elasticsearch">GitHub リポジトリ</a>をご覧ください。<a href="https://www.elastic.co/search-labs/blog/hybrid-search-with-the-elasticsearch-go-client">パート 3</a>に進み、<a href="https://www.elastic.co/search-labs/blog/perform-text-queries-with-the-elasticsearch-go-client">パート 1</a>で説明した Go のキーワード検索機能とベクトル検索を組み合わせる方法の概要を確認します。</p><p>それまでは、楽しいホリネズミ狩りを！</p><h2>各種資料</h2><ol><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html">Elasticsearchガイド</a></p></li><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/index.html">Elasticsearch Goクライアント</a></p></li><li><p><a href="https://www.elastic.co/what-is/vector-search">ベクトル検索とは何ですか?| 弾性</a></p></li></ol>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/perform-vector-search-with-the-elasticsearch-go-client</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/perform-vector-search-with-the-elasticsearch-go-client</guid>
    <category><![CDATA[Vector Database]]></category>
    <category><![CDATA[Go]]></category>
    <dc:creator><![CDATA[Carly Richmond,Laurent Saint-Félix]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdcae959696d55a9b/6a1704d5ab7f085a56db9d7c/491ef9efbb30b253e1d9e3b7f816a9a23c8f5264-721x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Wed, 01 Nov 2023 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elasticsearch Go クライアントでテキストクエリを実行する]]></title>
    <description><![CDATA[実際の例を通して、Elasticsearch Go クライアントを使用して Elasticsearch で従来のテキスト クエリを実行する方法を学びます。]]></description>
    <content:encoded><![CDATA[<p>Go を含むあらゆるプログラミング言語でソフトウェアを構築することは、生涯にわたる学習に取り組むことです。大学時代および仕事のキャリアを通じて、Carly は多言語話者になることに適応し、Python、C、JavaScript、TypeScript、Java など、多くのプログラミング言語に触れる必要がありました。しかし、それだけでは十分ではありませんでした!それで最近彼女も囲碁を始めました！</p><p>動物、プログラミング言語、そして親切な著者の一人と同じように、検索もさまざまな方法の進化を遂げており、独自の検索ユースケースに応じてどれを選択するかを決めるのは難しい場合があります。このブログでは、従来のキーワード検索の概要と、<a href="https://www.elastic.co/elasticsearch/"> Elasticsearch</a> と<a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/index.html"> Elasticsearch</a> Go<a href="https://github.com/carlyrichmond/gopher-hunting-elasticsearch"> クライアント を使用した 例を</a> 紹介します。</p><h2>要件</h2><p>この例を実行するには、次の前提条件が満たされていることを確認してください。</p><ol><li><p>Goバージョン1.21以降のインストール</p></li><li><p><a href="https://go.dev/doc/code">Go ドキュメント</a>に記載されている推奨構造とパッケージ管理を使用して、独自の Go リポジトリを作成します。</p></li><li><p>独自の Elasticsearch クラスターを作成し、Wikipedia<a href="https://github.com/carlyrichmond/gopher-hunting-elasticsearch#sources"> のフレンドリーな</a> <a href="https://en.wikipedia.org/wiki/Gopher">Gopher を含む一連の げっ歯類ベースのページ を設定します。</a></p></li></ol><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6a436c42996e5172/6a1704cf0c48573d1c01a957/34fa81a9b4c292634c719b8303a9b6b7506d7920-1440x662.png" alt="Wikipedia Gopherページ" /><h2>Elasticsearchへの接続</h2><p>この例では、Go クライアントが提供する<a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/typedapi.html">Typed API</a>を使用します。クエリに対して安全な接続を確立するには、次のいずれかを使用してクライアントを構成する必要があります。</p><ol><li><p>Elastic Cloud を利用する場合のクラウド ID と API キー。</p></li><li><p>クラスター URL、ユーザー名、パスワード、証明書。</p></li></ol><p>Elastic Cloud にあるクラスターに接続すると、次のようになります。</p>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:  &amp;elastictransport.ColorLogger{os.Stdout, true, true},
	})

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

	return es, nil
}
<p>後ほど示すように、 <code>client</code>接続は検索に使用できます。</p><h2>キーワード検索</h2><p>キーワード検索は、1990 年に初めて文書化されたインターネット検索エンジンである<a href="https://en.wikipedia.org/wiki/Archie_(search_engine)">Archie</a>の誕生以来、私たちがよく知っている基本的な検索タイプです。</p><p>キーワード検索の中心的な要素は、ドキュメントを転置インデックスに変換することです。教科書の巻末にある索引とまったく同じように、転置索引にはトークンのリストと各文書内でのその位置とのマッピングが含まれています。以下の図は、インデックス生成の主要な段階を示しています。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt366681a12027f14b/6a17e7aa1d1b831c2093e452/9cd7b2a60d9aa54facb37738b821bba6ca925830-1440x581.png" alt="転置インデックス生成" /><p>上記のように、Elasticsearch でのトークンの生成は、次の 3 つの主要な段階で構成されます。</p><ol><li><p>0 個以上の<a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-charfilters.html"><code>char_filters</code></a>を使用して不要な文字を削除します。この例では、 <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-htmlstrip-charfilter.html"><code>html_strip</code></a>フィルターを使用して<code>body_content</code>フィールド内の HTML 要素を削除しています。</p></li><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-tokenizers.html"><code>standard</code></a><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-tokenizers.html">トークナイザー</a>を使用してコンテンツからトークンを分割します。スペースとキーの句読点によって分割されます。</p></li><li><p>不要なトークンを削除したり、 <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-lowercase-tokenfilter.html"><code>lowercase</code></a><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-lowercase-tokenfilter.html">トークン フィルター</a>などの 0 個以上の<code>filter</code>オプションや、 <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-snowball-tokenfilter.html"><code>snowball</code></a><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-snowball-tokenfilter.html">ステマー</a>などのステマーを使用してトークンを言語ルートに戻すことで、トークナイザーの出力ストリームからトークンを変換します。</p></li></ol><h2>Go で Elasticsearch を検索する</h2><p>Go クライアントでクエリを実行するときは、以下の例のように、検索するインデックスを指定し、クエリとその他のオプションを渡します。</p>func KeywordSearch(client *elasticsearch.TypedClient, term string) ([]Rodent, error) {
	res, err := client.Search().
		Index("search-rodents").
		Query(&amp;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)
}
<p>上記の例では、標準の<a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html"><code>match</code></a><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html">クエリ</a>を実行して、関数に渡された特定の文字列を含むインデックス内のドキュメントを検索します。<code>Do(context.Background())</code>を介して<a href="https://pkg.go.dev/context#Background">新しい空のコンテキストを</a>検索実行に渡すことに注意してください。さらに、Elasticsearch によって返されたエラーは、ログ記録とエラー処理のために<code>err</code>属性に出力されます。</p><p>結果は、ドキュメント自体を JSON 形式で含む<code>_Source</code>属性とともに<code>res.Hits.Hits</code>に返されます。このソースを Go 対応の構造体に変換するには、次の例に示すように、Go encoding/json<a href="https://pkg.go.dev/encoding/json"> パッケージを</a> 使用して JSON 応答を<a href="https://pkg.go.dev/encoding/json#Unmarshal"> アンマーシャリングする</a> 必要があります。</p>func getRodents(hits []types.Hit) ([]Rodent, error) {
	var rodents []Rodent

	for _, hit := range hits {
		var currentRodent Rodent
		err := json.Unmarshal(hit.Source_, &amp;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
}
<p>クエリ<code>gopher</code>を検索してアンマーシャリングすると、期待どおりに Gopher の Wikipedia ページが返されます。</p>[
  {ID:64f74ecd4acb3df024d91112 Title:Gopher - Wikipedia Url:https://en.wikipedia.org/wiki/Gopher}
]
<p>しかし、 <code>What do Gophers eat?</code>に問い合わせても、期待する結果は得られません。</p>[]
<p>シンプルなキーワード検索により、私たちが普段使用しているアプリケーションと同じように、Go アプリケーションに高いパフォーマンスで結果を返すことができます。また、特定の会社や用語を検索するなどのシナリオに関連する用語の完全一致にも最適です。</p><p>しかし、上で見たように、語彙の不一致の問題により、文脈と意味を識別するのが困難です。さらに、画像や音声などのテキスト以外のファイル形式のサポートも困難です。</p><h2>まとめ</h2><p>ここでは、 <a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/index.html">Elasticsearch Go クライアント</a>を使用して Elasticsearch で従来のテキスト クエリを実行する方法について説明しました。Go はインフラストラクチャのスクリプトや Web サーバーの構築に広く使用されているため、Go で検索する方法を知っておくと便利です。</p><p>このシリーズのすべてのコードについては、 <a href="https://www.elastic.co/search-labs/blog/perform-vector-search-with-the-elasticsearch-go-client">GitHub リポジトリ</a>をご覧ください。<a href="https://www.elastic.co/search-labs/blog/perform-vector-search-with-the-elasticsearch-go-client">パート 2</a>に進み、ベクトル検索の概要と、Go でベクトル検索を実行する方法について説明します。それまでは、楽しいホリネズミ狩りを！</p><h2>各種資料</h2><ol><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html">Elasticsearchガイド</a></p></li><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/index.html">Elasticsearch Goクライアント</a></p></li><li><p><a href="https://codingexplained.com/coding/elasticsearch/understanding-analysis-in-elasticsearch-analyzers">Elasticsearch の分析（アナライザー）を理解する by Bo Andersen | #CodingExplained</a></p></li></ol>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/perform-text-queries-with-the-elasticsearch-go-client</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/perform-text-queries-with-the-elasticsearch-go-client</guid>
    <category><![CDATA[Go]]></category>
    <dc:creator><![CDATA[Carly Richmond,Laurent Saint-Félix]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdcae959696d55a9b/6a1704d5ab7f085a56db9d7c/491ef9efbb30b253e1d9e3b7f816a9a23c8f5264-721x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Tue, 31 Oct 2023 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>