<?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[Fernando Briano - 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[Fernando Briano - 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/author/fernando-briano</link>
    </image>
    <link>https://www.elastic.co/jp/search-labs/author/fernando-briano</link>
    <atom:link href="https://www.elastic.co/jp/search-labs/rss/author/fernando-briano.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[jp]]></language>
    <lastBuildDate>Mon, 28 Sep 2026 07:34:07 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Elasticsearch Ruby クライアント向け ES|QL クエリビルダーのご紹介]]></title>
    <description><![CDATA[Elasticsearch Ruby クライアント用に最近リリースされた ES|QL クエリ ビルダーの使用方法を学習します。Ruby コードを使用して ES|QL クエリをより簡単に構築するためのツール。]]></description>
    <content:encoded><![CDATA[<p>最近、Apache 2 ライセンスに基づいて公開された Ruby gem、 <a href="https://github.com/elastic/esql-ruby/"><code>elastic-esql</code></a>をリリースしました。この gem を使用すると、Elastic の<a href="https://www.elastic.co/docs/explore-analyze/query-filter/languages/esql">ES|QL</a>クエリを慣用的な Ruby で構築し、ES|QL クエリ API で使用できるようになります。ES|QL を使用すると、開発者はクエリを介して Elasticsearch に保存されているデータをフィルタリング、変換、分析できます。「パイプ」（ <code>|</code> ）を使用して、データを段階的に処理します。代わりに gem は Ruby 関数を使用します。これを元のオブジェクトに連鎖して、より複雑なクエリを構築できます。</p><p><strong>ESQL:</strong></p><p><strong>ルビー：</strong></p>Elastic::ESQL.from('sample_data').limit(2).sort('@timestamp').descending<h2>インストール</h2><p>この gem は、RubyGems から次のようにインストールできます。</p>gem install elastic-esql<p>または、プロジェクトの Gemfile に追加することもできます。</p>gem 'elastic-esql'<h2>使用法</h2><p>完全なクエリを一度に構築することも、 <code>from</code>や<code>row</code>などのソース コマンドを使用してクエリ オブジェクトを作成し、それに基づいて ES|QL メソッドを連鎖して構築することもできます。</p>query = Elastic::ESQL.from('sample_data')
query.limit(2).sort('@timestamp')<p>gem は<code>to_s</code>メソッドでコードを ES|QL に変換するので、印刷されるか文字列としてキャストされるときに ES|QL クエリを返します。</p>query = Elastic::ESQL.from('sample_data').limit(2).sort('@timestamp').descending
query.to_s
# =&gt; "FROM sample_data | LIMIT 2 | SORT @timestamp DESC"<p>各関数の<code>!</code>に相当するものを使用して、クエリ オブジェクトをインスタンス化し、その初期状態を変更できます。</p>query = Elastic::ESQL.from('sample_data')
query.to_s
# =&gt; "FROM sample_data"
query.limit!(2).sort!('@timestamp')
query.to_s
# =&gt; "FROM sample_data | LIMIT 2 | SORT @timestamp"<p>このツールは、 <code>enrich</code>や<code>sort</code>などの追加ステップを ES|QL 関数に連鎖させる便利な方法を提供します。<code>Elastic::ESQL</code>オブジェクトで<code>enrich</code>呼び出すと、それに<code>on</code>と<code>with</code>を連鎖できます。</p>esql.enrich!('policy').on('a').with({ name: 'language_name' })<p><code>sort</code>を使用した後、クエリに<code>desc</code> 、 <code>asc</code> 、 <code>nulls_first</code> 、 <code>nulls_last</code>を連鎖させることもできます。</p>Elastic::ESQL.from('sample_data').sort('@timestamp').asc.to_s
# =&gt; 'FROM sample_data | SORT @timestamp ASC'

Elastic::ESQL.from('sample_data').sort('@timestamp').desc.nulls_first.to_s
# =&gt; 'FROM sample_data | SORT @timestamp DESC NULLS FIRST'<p>また、ES|QL クエリを自分で記述する場合や、ライブラリにまだ追加されていない機能を使用する場合に備えて、カスタム文字列もサポートされています。<code>custom</code>クエリの末尾の文字列を結合します。パイプ文字を追加せずに、関数に送信されるとそれらが追加されます。これらはスペース文字によってクエリの残りの部分に結合されます。</p>esql = Elastic::ESQL.from('sample_data')
esql.custom('| MY_VALUE = "test value"').to_s
# =&gt; 'FROM sample_data | MY_VALUE = "test value"'<p><code>custom</code>関数を連鎖させることもできます:</p>esql.custom('| MY_VALUE = "test value"').custom('| ANOTHER, VALUE')
'FROM sample_data | MY_VALUE = "test value" | ANOTHER, VALUE'<h2>Ruby クライアントで ES|QL クエリビルダーを使用する</h2><p>クエリ オブジェクトを送信することで、 <a href="https://github.com/elastic/elasticsearch-ruby">elasticsearch-ruby</a>と<code>esql.query</code> API でクエリ ビルダーを直接使用できます。</p>require 'elasticsearch'
require 'elastic/esql'

client = Elasticsearch::Client.new
index = 'sample_data'

query = Elastic::ESQL.from(index)
                     .sort('@timestamp')
                     .desc
                     .where('event_duration &gt; 5000000')
                     .limit(3)
                     .eval({ duration_ms: 'ROUND(event_duration/1000000.0, 1)' })
client.esql.query(body: { query: query })<p>Elasticsearch Ruby クライアントの ES|QL Helper と一緒に使用することもできます。<a href="https://www.elastic.co/search-labs/blog/esql-ruby-helper-elasticsearch">詳細については</a>、以下を参照してください。</p>require 'elasticsearch/helpers/esql_helper'

Elasticsearch::Helpers::ESQLHelper.query(client, query)<h2>スタンドアロンツールとして</h2><p>この gem は、ES|QL クエリを慣用的な方法で構築するためのスタンドアロン ツールとして設計されています。ランタイム依存関係がないため、公式の Elasticsearch Ruby クライアントと一緒に使用することも、単独で使用することもできます。</p><p>生成されたクエリは、アプリケーションが Elasticsearch API (Ruby かどうかに関係なく) と対話するあらゆる方法で<a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-esql-query"><code>esql.query</code></a> API で使用できます。<code>elastic-esql</code>を使用してクエリを構築すると、生成された文字列をリクエスト本文の<code>query</code>パラメータとして API に送信できます。 </p><p>以前、 <a href="https://www.elastic.co/search-labs/blog/elasticsearch-ruby-tools">Elasticsearch を一般的な Ruby ツールと併用する方法</a>について書きました。この gem は、一般的な Ruby ツールと組み合わせて使用し、ES|QL を使用して Elasticsearch をクエリできます。</p><h2>まとめ</h2><p>このライブラリは現在開発中であり、最終的な API はまだ完成していません。現在はテクニカルプレビューとしてリリースされています。現在の API または一般的な使用方法に関してフィードバックがある場合は、遠慮なく<a href="https://github.com/elastic/esql-ruby/issues">新しい問題を開いて</a>ください。Ruby ES|QL クエリ ビルダーの詳細については、 <a href="https://github.com/elastic/esql-ruby/?tab=readme-ov-file#ruby-esql-query-builder">README</a>を参照してください。</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/esql-query-builder-elasticsearch-ruby-client</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/esql-query-builder-elasticsearch-ruby-client</guid>
    <category><![CDATA[ES|QL]]></category>
    <category><![CDATA[Ruby]]></category>
    <dc:creator><![CDATA[Fernando Briano]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt85d112ccca541b9e/6a17dccb4b055d6bfd4320cc/f8e1263ab53d356824a4fc539084151be80899db-720x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Wed, 17 Sep 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[RubyアプリをOpenSearchからElasticsearchに移行する方法]]></title>
    <description><![CDATA[Ruby コードベースを OpenSearch クライアントから Elasticsearch クライアントに移行するためのガイド。]]></description>
    <content:encoded><![CDATA[<p>OpenSearch Ruby クライアントは、バージョン<code>7.x</code>の Elasticsearch Ruby クライアントからフォークされたため、コードベースは比較的似ています。つまり、Ruby コードベースを OpenSearch から Elasticsearch に移行すると、それぞれのクライアント ライブラリのコードは非常に馴染みのあるものになります。このブログ記事では、OpenSearch を使用する Ruby アプリの例と、このコードを Elasticsearch に移行する手順を紹介します。</p><p>どちらのクライアントも、一般的な Apache License 2.0 に基づいてリリースされているため、オープンソースかつフリーソフトウェアです。Elasticsearch のライセンスは最近更新され、Elasticsearch と Kibana のコアはバージョン 8.16 以降、OSI 承認のオープン ソース ライセンス AGPL に基づいて公開されています。</p><h2>Rubyアプリの移行時にElasticsearchのバージョンを考慮する</h2><p>移行時に考慮すべき点の 1 つは、どのバージョンの Elasticsearch を使用するかということです。最新の安定リリース (この記事の執筆時点では<code>8.17.0</code>を使用することをお勧めします。Elasticsearch Ruby クライアントのマイナー バージョンは、Elasticsearch のマイナー バージョンに従います。したがって、Elasticsearch <code>8.17.x</code>では、Ruby gem のバージョン<code>8.17.x</code>を使用できます。</p><p>OpenSearch は Elasticsearch 7.10.2 からフォークされました。そのため、API が変更され、どちらでも異なる機能が使用される可能性があります。しかし、それはこの記事の範囲外なので、サンプル アプリで最も一般的な操作についてのみ説明します。</p><p>Ruby on Rails の場合、公式の Elasticsearch クライアント、または<a href="https://github.com/elastic/elasticsearch-rails/">Rails 統合ライブラリ</a>を使用できます。Elasticsearch とクライアントの最新の安定バージョンに移行することをお勧めします。<code>elasticsearch-rails</code> gem バージョン<code>8.0.0</code> Rails <code>6.1</code> 、 <code>7.0</code> 、 <code>7.1</code> 、および Elasticsearch <code>8.x</code>をサポートします。</p><h2>コード</h2><p>この例では、 <a href="https://opensearch.org/docs/latest/install-and-configure/install-opensearch/tar/">tarball から OpenSearch をインストールする</a>手順に従いました。tarball をダウンロードして解凍した後、後でクライアントをインスタンス化するために使用する初期管理者パスワードを設定する必要がありました。</p><p>次のような<code>Gemfile</code>を持つディレクトリを作成しました:</p>source 'https://rubygems.org'

gem 'opensearch-ruby'<p><code>bundle install</code>を実行すると、プロジェクトに gem がインストールされます。インストールされた opensearch-ruby バージョン<code>3.4.0</code>と、実行している OpenSearch のバージョンは<code>2.18.0</code>です。同じディレクトリ内の<code>example_code.rb</code>ファイルにコードを記述しました。このファイルの初期コードは、OpenSearch クライアントのインスタンス化です。</p>require 'opensearch'

client = OpenSearch::Client.new(
  host: 'https://localhost:9200',
  user: 'admin',
  password: ENV['OPENSEARCH_INITIAL_ADMIN_PASSWORD'],
  transport_options: { ssl: { verify: false } }
)<p>テストを容易にするために、ユーザー ガイドに従ってトランスポート オプション<code>ssl: { verify: false}</code>パラメータが渡されます。本番環境では、OpenSearch の展開に応じてこれを設定する必要があります。</p><p>OpenSearch バージョン 2.12.0 以降では、インストール スクリプトを実行するときに、 <code>OPENSEARCH_INITIAL_ADMIN_PASSWORD</code>環境変数を強力なパスワードに設定する必要があります。tarball から OpenSearch をインストールする手順に従って、コンソールで変数をエクスポートし、Ruby スクリプトで使用できるようになりました。</p><p>クライアントが OpenSearch に接続していることを確認するための簡単な API は、 <code>cluster.health</code> API を使用しています。</p>puts 'HEALTH:'
pp client.cluster.health<p>そして実際にそれは機能します:</p>$ be ruby example_code.rb
HEALTH:
{"cluster_name"=&gt;"opensearch",
"status"=&gt;"yellow",
 "timed_out"=&gt;false,
 "number_of_nodes"=&gt;1,
 "number_of_data_nodes"=&gt;1,<p>Elasticsearch Ruby クライアントのドキュメントにある一般的な例をいくつかテストしたところ、期待どおりに動作しました。</p>index = 'books'
puts 'Creating index'
response = client.indices.create(index: index)
puts response
# Creating index
# {"acknowledged"=&gt;true, "shards_acknowledged"=&gt;true, "index"=&gt;"books"}

puts 'Indexing a document'
document = { title: 'The Time Machine', author: 'H. G. Wells', year: 1895 }
response = client.index(index: index, body: document, refresh: true)
puts response
# Indexing document
# {"_index"=&gt;"books", "_id"=&gt;"esalT5MB4vnuJz5TtqOc", "_version"=&gt;1, "result"=&gt;"created", "forced_refresh"=&gt;true, "_shards"=&gt;{"total"=&gt;2, "successful"=&gt;1, "failed"=&gt;0}, "_seq_no"=&gt;0, "_primary_term"=&gt;1}

id = response['_id']
puts 'Getting document'
response = client.get(index: index, id: id)
puts response
# Getting document
# {"_index"=&gt;"books", "_id"=&gt;"esalT5MB4vnuJz5TtqOc", "_version"=&gt;1, "_seq_no"=&gt;0, "_primary_term"=&gt;1, "found"=&gt;true, "_source"=&gt;{"title"= &gt;"The Time Machine", "author"=&gt;"H. G. Wells", "year"=&gt;1895}}

puts "Does an index exist?"
puts client.indices.exists(index: 'imaginary_index')
# Does an index exist?
# false

puts 'Processing Bulk request'
body = [
  { index: { _index: 'books', data: { name: 'Leviathan Wakes', author: 'James S.A. Corey', release_date: '2011-06-02', page_count: 561 } } },
  { index: { _index: 'books', data: { name: 'Hyperion', author: 'Dan Simmons', release_date: '1989-05-26', page_count: 482 } } },
  { index: { _index: 'books', data: { name: 'Dune', author: 'Frank Herbert', release_date: '1965-06-01', page_count: 604 } } },
  { index: { _index: 'books', data: { name: 'Dune Messiah', author: 'Frank Herbert', release_date: '1969-10-15', page_count: 331 } } },
  { index: { _index: 'books', data: { name: 'Children of Dune', author: 'Frank Herbert', release_date: '1976-04-21', page_count: 408 } } },
  { index: { _index: 'books', data: { name: 'God Emperor of Dune', author: 'Frank Herbert', release_date: '1981-05-28', page_count: 454 } } },
  { index: { _index: 'books', data: { name: 'Consider Phlebas', author: 'Iain M. Banks', release_date: '1987-04-23', page_count: 471 } } },
  { index: { _index: 'books', data: { name: 'Pandora\'s Star', author: 'Peter F. Hamilton', release_date: '2004-03-02', page_count: 768 } } },
  { index: { _index: 'books', data: { name: 'Revelation Space', author: 'Alastair Reynolds', release_date: '2000-03-15', page_count: 585 } } },
  { index: { _index: 'books', data: { name: 'A Fire Upon the Deep', author: 'Vernor Vinge', release_date: '1992-06-01', page_count: 613 } } },
  { index: { _index: 'books', data: { name: 'Ender\'s Game', author: 'Orson Scott Card', release_date: '1985-06-01', page_count: 324 } } },
  { index: { _index: 'books', data: { name: '1984', author: 'George Orwell', release_date: '1985-06-01', page_count: 328 } } },
  { index: { _index: 'books', data: { name: 'Fahrenheit 451', author: 'Ray Bradbury', release_date: '1953-10-15', page_count: 227 } } },
  { index: { _index: 'books', data: { name: 'Brave New World', author: 'Aldous Huxley', release_date: '1932-06-01', page_count: 268 } } },
  { index: { _index: 'books', data: { name: 'Foundation', author: 'Isaac Asimov', release_date: '1951-06-01', page_count: 224 } } },
  { index: { _index: 'books', data: { name: 'The Giver', author: 'Lois Lowry', release_date: '1993-04-26', page_count: 208 } } },
  { index: { _index: 'books', data: { name: 'Slaughterhouse-Five', author: 'Kurt Vonnegut', release_date: '1969-06-01', page_count: 275 } } },
  { index: { _index: 'books', data: { name: 'The Hitchhiker\'s Guide to the Galaxy', author: 'Douglas Adams', release_date: '1979-10-12', page_count: 180 } } },
  { index: { _index: 'books', data: { name: 'Snow Crash', author: 'Neal Stephenson', release_date: '1992-06-01', page_count: 470 } } },
  { index: { _index: 'books', data: { name: 'Neuromancer', author: 'William Gibson', release_date: '1984-07-01', page_count: 271 } } },
  { index: { _index: 'books', data: { name: 'The Handmaid\'s Tale', author: 'Margaret Atwood', release_date: '1985-06-01', page_count: 311 } } },
  { index: { _index: 'books', data: { name: 'Starship Troopers', author: 'Robert A. Heinlein', release_date: '1959-12-01', page_count: 335 } } },
  { index: { _index: 'books', data: { name: 'The Left Hand of Darkness', author: 'Ursula K. Le Guin', release_date: '1969-06-01', page_count: 304 } } },
  { index: { _index: 'books', data: { name: 'The Moon is a Harsh Mistress', author: 'Robert A. Heinlein', release_date: '1966-04-01', page_count: 288 } } }
]
puts client.bulk(body: body, refresh: true)
# Processing Bulk request
# {"took"=&gt;38, "errors"=&gt;false, "items"=&gt;[{"index"=&gt;{"_index"=&gt;"books", "_id"=&gt;" ...

query = { query: { multi_match: { query: 'dune', fields: ['name'] } } }
puts 'Search results'
response = client.search(index: index, body: query)
puts response
# Search results
# {"_index"=&gt;"books", "_id"=&gt;"oEawT5MBOXHuGXdEu5Wu", "_score"=&gt;2.2886353, "_source"=&gt;{"name"=&gt;"Dune", "author"=&gt;"Frank Herbert", "release_date"=&gt;"1965-06-01", "page_count"=&gt;604}}
# {"_index"=&gt;"books", "_id"=&gt;"oUawT5MBOXHuGXdEu5Wu", "_score"=&gt;1.8893257, "_source"=&gt;{"name"=&gt;"Dune Messiah", "author"=&gt;"Frank Herbert", "release_date"=&gt;"1969-10-15", "page_count"=&gt;331}}
# {"_index"=&gt;"books", "_id"=&gt;"okawT5MBOXHuGXdEu5Wu", "_score"=&gt;1.6086557, "_source"=&gt;{"name"=&gt;"Children of Dune", "author"=&gt;"Frank Herbert", "release_date"=&gt;"1976-04-21", "page_count"=&gt;408}}
# {"_index"=&gt;"books", "_id"=&gt;"o0awT5MBOXHuGXdEu5Wu", "_score"=&gt;1.40059, "_source"=&gt;{"name"=&gt;"God Emperor of Dune", "author"=&gt;"Frank Herbert", "release_date"=&gt;"1981-05-28", "page_count"=&gt;454}}

puts 'Updating document'
document = { title: 'Walkaway', author: 'Cory Doctorow', release_date: '2017' }
response = client.index(index: index, body: document, refresh: true)
id = response['_id']
response = client.update(index: index, id: id, body: { doc: { release_date: '2017-04-26' } })
puts response
# Updating document
# {"_index"=&gt;"books", "_id"=&gt;"degnZJMBIGr4X0Yim55L", "_version"=&gt;2, "result"=&gt;"updated", "_shards"=&gt;{"total"=&gt;2, "successful"=&gt;1, "failed"=&gt;0}, "_seq_no"=&gt;26, "_primary_term"=&gt;1}

puts 'Retrieveing multiple documents'
response = client.search(index: index, body: { query: { match_all: {} }, size: 3, stored_fields: '_id' })
ids = response['hits']['hits']
ids.map { |a| a.delete('_score') }
response = client.mget(body: { docs: [{ _index: index, _id: ids }] })
puts response
# Retrieveing multiple documents
# {"docs"=&gt;[{"_index"=&gt;"books", "_id"=&gt;"qeg2ZJMBIGr4X0YiiqD2", "_version"=&gt;1, "_seq_no"=&gt;0, "_primary_term"=&gt;1, "found"=&gt;true, "_source"=&gt;{"title"=&gt;"The Time Machine", "author"=&gt;"H. G. Wells", "year"=&gt;1895}}, {"_index"=&gt;"books", "_id"=&gt;"q-g2ZJMBIGr4X0Yii6Ah", "_version"=&gt;1, "_seq_no"=&gt;1, "_primary_term"=&gt;1, "found"=&gt;true, "_source"=&gt;{"name"=&gt;"Leviathan Wakes", "author"=&gt;"James S.A. Corey", "release_date"=&gt;"2011-06-02", "page_count"=&gt;561}}, {"_index"=&gt;"books", "_id"=&gt;"rOg2ZJMBIGr4X0Yii6Ah", "_version"=&gt;1, "_seq_no"=&gt;2, "_primary_term"=&gt;1, "found"=&gt;true, "_source"=&gt;{"name"=&gt;"Hyperion", "author"=&gt;"Dan Simmons", "release_date"=&gt;"1989-05-26", "page_count"=&gt;482}}]}

puts "Count #{client.count(index: index)['count']}"
puts 'Deleting by query'
response = client.delete_by_query(index: index, body: { query: { match: { author: 'Robert A. Heinlein' } } }, refresh: true)
puts response
puts "Count #{client.count(index: index)['count']}"
# Count 26
# Deleting by query
# {"took"=&gt;16, "timed_out"=&gt;false, "total"=&gt;2, "deleted"=&gt;2, "batches"=&gt;1, "version_conflicts"=&gt;0, "noops"=&gt;0, "retries"=&gt;{"bulk"=&gt;0, "search"=&gt;0}, "throttled_millis"=&gt;0, "requests_per_second"=&gt;-1.0, "throttled_until_millis"=&gt;0, "failures"=&gt;[]}
# Count 24

puts 'Deleting document'
response = client.delete(index: index, id: id)
puts response
# Deleting document
# {"_index"=&gt;"books", "_id"=&gt;"nEawT5MBOXHuGXdEu5WA", "_version"=&gt;2, "result"=&gt;"deleted", "_shards"=&gt;{"total"=&gt;2, "successful"=&gt;1, "failed"=&gt;0}, "_seq_no"=&gt;25, "_primary_term"=&gt;1}

puts 'Deleting index'
response = client.indices.delete(index: index)
puts response
# Deleting index
# {"acknowledged"=&gt;true}<h2>RubyアプリをElasticsearchに移行する</h2><p>最初のステップは、Gemfile に<code>elasticsearch-ruby</code>を追加することです。<code>bundle install</code>を実行すると、Elasticsearch Ruby クライアント gem がインストールされます。完全に移行する前にコードをテストしたい場合は、最初は<code>opensearch-ruby</code> gem をそこに残しておくことができます。</p><p>次の重要なステップは、クライアントのインスタンス化です。これは、Elasticsearch をどのように実行しているかによって異なります。これらの例に対して同様のアプローチを維持するために、 <a href="https://www.elastic.co/downloads/elasticsearch">「Elasticsearch をダウンロードし</a>てローカルで実行する」の手順に従います。</p><p><code>bin/elasticsearch</code>を実行すると、Elasticsearch は自動的に構成されたセキュリティ機能で起動します。必ず elastic ユーザーのパスワードをコピーしてください (ただし、 <code>bin/elasticsearch-reset-password -u elastic</code>を実行してリセットできます)。この例に従う場合は、OpenSearch と Elasticsearch は同じポートで実行されるため、Elasticsearch を起動する前に必ず OpenSearch を停止してください。</p><p><code>example_code.rb</code>の始めで、OpenSearch クライアントのインスタンス化をコメント アウトし、Elasticsearch クライアントのインスタンス化を追加しました。</p># require 'opensearch'

# client = OpenSearch::Client.new(
#   host: 'https://localhost:9200',
#   user: 'admin',
#   password: ENV['OPENSEARCH_INITIAL_ADMIN_PASSWORD']
#   transport_options: { ssl: { verify: false } }
# )

require 'elasticsearch'

client = Elasticsearch::Client.new(
  host: 'https://localhost:9200',
  user: ENV['ELASTICSEARCH_USER'],
  password: ENV['ELASTICSEARCH_PASSWORD'],
  transport_options: { ssl: { verify: false } }
)<p>ご覧のとおり、このテスト シナリオではコードはほぼ同じです。これは、Elasticsearch のデプロイメントと、Elasticsearch との接続および認証の方法によって異なります。セキュリティに関しては OpenSearch と同じことが当てはまります。SSL を検証しないオプションはテスト目的のみであり、本番環境では使用しないでください。</p><p>クライアントがセットアップされたら、 <code>bundle exec ruby example_code.rb</code>を使用してコードを再度実行します。そして、すべてがうまく機能します!</p><h2>移行問題のデバッグ</h2><p>アプリケーションが使用している API によっては、OpenSearch の API が異なる場合、Elasticsearch に対してコードを実行するとエラーが発生する可能性があります。<a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/rest-apis.html">REST API ドキュメントは</a>、API の使用方法に関する詳細な情報を得るための重要なリファレンスです。使用している Elasticsearch のバージョンのドキュメントを必ず確認してください。<a href="https://rubydoc.info/gems/elasticsearch-api"><code>Elasticsearch::API</code></a>参照も参照できます。</p><p>Elasticsearch で発生する可能性のあるエラーには次のようなものがあります:</p><ul><li><p><code>ArgumentError: Required argument '&lt;ARGUMENT&gt;' missing</code> - これはクライアント エラーであり、リクエストに必要なパラメータがない場合に発生します。</p></li><li><p><code>Elastic::Transport::Transport::Errors::BadRequest: [400] {"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"request [/example/_doc] contains unrecognized parameter: [test]"}]...</code> このエラーは Elasticsearch から発生し、クライアント コードが、使用されている API に対して Elasticsearch が認識しないパラメータを使用していることを意味します。</p></li></ul><p>Elasticsearch クライアントは、サーバーから送信された詳細なエラー メッセージとともに、Elasticsearch からのエラーを発生させます。したがって、サポートされていないパラメータやエンドポイントの場合でも、エラーによって何が異なっているかが通知されるはずです。</p><h2>まとめ</h2><p>このサンプル コードで示したように、Ruby アプリを OpenSearch から Elasticsearch に移行することは、Ruby 側から見るとそれほど複雑ではありません。バージョン管理と、検索エンジン間で異なる可能性のある API に注意する必要があります。しかし、最も一般的なアクションでは、クライアントを移行する際の主な変更はインスタンス化にあります。その点ではどちらも似ていますが、ホストと資格情報の定義方法は、スタックの展開方法によって異なります。クライアントがセットアップされ、Elasticsearch に接続していることを確認したら、OpenSearch クライアントを Elasticsearch クライアントにシームレスに置き換えることができます。
</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/ruby-opensearch-elasticsearch-migration</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/ruby-opensearch-elasticsearch-migration</guid>
    <category><![CDATA[Ruby]]></category>
    <dc:creator><![CDATA[Fernando Briano]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7f2ce1fb5cbf7d70/6a17e1dd148009bc02b486af/47756f629737d47c4430860ea23366a8d24c90d9-1280x720.jpg" length="0" type="image/jpeg"/>
    <pubDate>Fri, 13 Dec 2024 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>