<?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/fr/search-labs/author/fernando-briano</link>
    </image>
    <link>https://www.elastic.co/fr/search-labs/author/fernando-briano</link>
    <atom:link href="https://www.elastic.co/fr/search-labs/rss/author/fernando-briano.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[fr]]></language>
    <lastBuildDate>Mon, 28 Sep 2026 12:46:01 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Présentation du générateur de requêtes ES|QL pour le client Elasticsearch Ruby]]></title>
    <description><![CDATA[Apprenez à utiliser le constructeur de requêtes ES|QL récemment publié pour le client Elasticsearch Ruby. Un outil pour construire des requêtes ES|QL plus facilement avec du code Ruby.]]></description>
    <content:encoded><![CDATA[<p>Nous avons récemment publié <a href="https://github.com/elastic/esql-ruby/"><code>elastic-esql</code></a>, un outil Ruby publié sous licence Apache 2. Cette gemme vous permet de construire les requêtes <a href="https://www.elastic.co/docs/explore-analyze/query-filter/languages/esql">ES|QL</a> d'Elastic en Ruby idiomatique, que vous pouvez ensuite utiliser avec l'API de requête ES|QL. ES|QL permet aux développeurs de filtrer, de transformer et d'analyser les données stockées dans Elasticsearch au moyen de requêtes. Il utilise les tuyaux "" ( <code>|</code> ) pour travailler avec les données étape par étape. La gem utilise des fonctions Ruby à la place, que vous pouvez enchaîner à l'objet original pour construire des requêtes plus complexes :</p><p><strong>ESQL :</strong></p><p><strong>Rubis :</strong></p>Elastic::ESQL.from('sample_data').limit(2).sort('@timestamp').descending<h2>Installation</h2><p>La gemme peut être installée à partir de RubyGems avec :</p>gem install elastic-esql<p>Il peut également être ajouté au fichier Gemfile d'un projet :</p>gem 'elastic-esql'<h2>Utilisation</h2><p>Vous pouvez soit construire une requête complète en une seule fois, soit créer un objet de requête à l'aide d'une commande source telle que <code>from</code> ou <code>row</code>, puis enchaîner les méthodes ES|QL pour construire à partir de cet objet.</p>query = Elastic::ESQL.from('sample_data')
query.limit(2).sort('@timestamp')<p>La gemme traduit le code en ES|QL dans la méthode <code>to_s</code>, de sorte qu'elle renvoie la requête ES|QL lorsqu'elle est imprimée ou transformée en chaîne :</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>Vous pouvez instancier un objet de requête et modifier son état initial en utilisant les équivalents <code>!</code> de chaque fonction :</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>L'outil offre des moyens pratiques d'enchaîner des étapes supplémentaires à une fonction ES|QL, comme <code>enrich</code> et <code>sort</code>. Une fois que vous avez appelé <code>enrich</code> sur un objet <code>Elastic::ESQL</code>, vous pouvez enchaîner <code>on</code> et <code>with</code>:</p>esql.enrich!('policy').on('a').with({ name: 'language_name' })<p>Vous pouvez également enchaîner <code>desc</code>, <code>asc</code>, <code>nulls_first</code> et <code>nulls_last</code> à votre requête après avoir utilisé <code>sort</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>Elle prend également en charge les chaînes personnalisées, au cas où vous souhaiteriez écrire vous-même la requête ES|QL ou utiliser une fonctionnalité qui n'a pas encore été ajoutée à la bibliothèque. <code>custom</code> joindra les chaînes à la fin de la requête. Il les ajoutera au fur et à mesure qu'ils sont envoyés à la fonction, sans ajouter de caractères de liaison. Ils seront combinés au reste de la requête par un caractère d'espacement.</p>esql = Elastic::ESQL.from('sample_data')
esql.custom('| MY_VALUE = "test value"').to_s
# =&gt; 'FROM sample_data | MY_VALUE = "test value"'<p>Vous pouvez également enchaîner les fonctions de <code>custom</code>:</p>esql.custom('| MY_VALUE = "test value"').custom('| ANOTHER, VALUE')
'FROM sample_data | MY_VALUE = "test value" | ANOTHER, VALUE'<h2>Utilisation du générateur de requêtes ES|QL avec le client Ruby</h2><p>Vous pouvez utiliser le constructeur de requêtes directement avec <a href="https://github.com/elastic/elasticsearch-ruby">elasticsearch-ruby</a> et l'API <code>esql.query</code> en envoyant l'objet de requête :</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>Vous pouvez également l'utiliser avec l'ES|QL Helper du client Elasticsearch Ruby, pour en <a href="https://www.elastic.co/search-labs/blog/esql-ruby-helper-elasticsearch">savoir plus :</a></p>require 'elasticsearch/helpers/esql_helper'

Elasticsearch::Helpers::ESQLHelper.query(client, query)<h2>En tant qu'outil autonome</h2><p>La gemme est conçue comme un outil autonome pour construire des requêtes ES|QL de manière idiomatique. Il n'a aucune dépendance d'exécution ; vous pouvez l'utiliser avec le client Ruby officiel d'Elasticsearch, ou seul.</p><p>La requête générée peut être utilisée avec l'API <a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-esql-query"><code>esql.query</code></a> de toutes les façons dont une application interagit avec l'API Elasticsearch (Ruby ou non). Une fois qu'une requête est construite avec <code>elastic-esql</code>, la chaîne générée peut être envoyée à l'API en tant que paramètre <code>query</code> dans le corps de la requête. </p><p>J'ai déjà écrit sur l'<a href="https://www.elastic.co/search-labs/blog/elasticsearch-ruby-tools">utilisation d'Elasticsearch avec des outils Ruby populaires.</a> Cette gemme peut être utilisée avec n'importe quel outil Ruby populaire pour interroger Elasticsearch avec ES|QL.</p><h2>Conclusion</h2><p>Cette bibliothèque est en cours de développement et l'API finale n'a pas encore été finalisée. Il s'agit actuellement d'un aperçu technique. Si vous avez des commentaires sur l'API actuelle ou sur son utilisation générale, n'hésitez pas à <a href="https://github.com/elastic/esql-ruby/issues">ouvrir un nouveau dossier.</a> Veuillez vous référer au <a href="https://github.com/elastic/esql-ruby/?tab=readme-ov-file#ruby-esql-query-builder">README</a> pour en savoir plus sur Ruby ES|QL Query Builder.</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[Comment migrer votre application Ruby d'OpenSearch vers Elasticsearch ?]]></title>
    <description><![CDATA[Un guide pour migrer une base de code Ruby du client OpenSearch vers le client Elasticsearch.]]></description>
    <content:encoded><![CDATA[<p>Le client OpenSearch Ruby a été dérivé du client Elasticsearch Ruby dans la version <code>7.x</code>, les bases de code sont donc relativement similaires. Cela signifie que lors de la migration d'un code Ruby d'OpenSearch vers Elasticsearch, le code des bibliothèques clientes respectives sera très familier. Dans ce billet, je vais montrer un exemple d'application Ruby qui utilise OpenSearch et les étapes pour migrer ce code vers Elasticsearch.</p><p>Les deux clients sont publiés sous la célèbre licence Apache 2.0, ce qui en fait des logiciels libres et gratuits. La licence d'Elasticsearch a été récemment mise à jour et le cœur d'Elasticsearch et de Kibana est publié sous la licence Open Source AGPL approuvée par l'OSI depuis la version 8.16.</p><h2>Prise en compte de la version d'Elasticsearch lors de la migration d'une application Ruby</h2><p>Lors de la migration, il convient de prendre en compte la version d'Elasticsearch qui sera utilisée. Nous recommandons d'utiliser la dernière version stable, qui, au moment de la rédaction de ce document, est <code>8.17.0</code>. Les versions mineures du client Elasticsearch Ruby suivent les versions mineures d'Elasticsearch. Ainsi, pour Elasticsearch <code>8.17.x</code>, vous pouvez utiliser la version <code>8.17.x</code> de la gem Ruby.</p><p>OpenSearch a été dérivé d'Elasticsearch 7.10.2. Les API peuvent donc avoir changé et des fonctionnalités différentes peuvent être utilisées sur l'un ou l'autre. Mais cela n'entre pas dans le cadre de cet article, et je vais seulement examiner les opérations les plus courantes dans un exemple d'application.</p><p>Pour Ruby on Rails, vous pouvez utiliser le client Elasticsearch officiel ou les <a href="https://github.com/elastic/elasticsearch-rails/">bibliothèques d'intégration Rails</a>. Nous recommandons de migrer vers la dernière version stable d'Elasticsearch et du client respectivement. La version de la gem <code>elasticsearch-rails</code> <code>8.0.0</code> supporte Rails <code>6.1</code>, <code>7.0</code> et <code>7.1</code> et Elasticsearch <code>8.x</code>.</p><h2>Le code</h2><p>Pour cet exemple, j'ai suivi les étapes d'<a href="https://opensearch.org/docs/latest/install-and-configure/install-opensearch/tar/">installation d'OpenSearch à partir d'une archive.</a> Après avoir téléchargé et extrait l'archive, j'ai dû définir un mot de passe administrateur initial que j'utiliserai plus tard pour instancier le client.</p><p>J'ai créé un répertoire avec un <code>Gemfile</code> qui ressemble à ceci :</p>source 'https://rubygems.org'

gem 'opensearch-ruby'<p>Après avoir lancé <code>bundle install</code>, la gem est installée pour mon projet. Ceci a installé la version <code>3.4.0</code> de opensearch-ruby et la version d'OpenSearch que j'utilise est <code>2.18.0</code>. J'ai écrit le code dans un fichier <code>example_code.rb</code> dans le même répertoire. Le code initial de ce fichier est l'instanciation d'un client 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>Le paramètre de l'option de transport <code>ssl: { verify: false}</code> est transmis conformément au guide de l'utilisateur afin de faciliter les tests. En production, cela doit être configuré en fonction du déploiement d'OpenSearch.</p><p>Depuis la version 2.12.0 d'OpenSearch, la variable d'environnement <code>OPENSEARCH_INITIAL_ADMIN_PASSWORD</code> doit être définie avec un mot de passe fort lors de l'exécution du script d'installation. En suivant les étapes d'installation d'OpenSearch à partir d'une archive, j'ai exporté la variable dans ma console et elle est maintenant disponible pour mon script Ruby.</p><p>Une API simple pour s'assurer que le client se connecte à OpenSearch consiste à utiliser l'API <code>cluster.health</code>:</p>puts 'HEALTH:'
pp client.cluster.health<p>Et en effet, cela fonctionne :</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>J'ai testé certains des exemples courants que nous avons dans la documentation du client Elasticsearch Ruby, et ils fonctionnent comme prévu :</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>Migration d'une application Ruby vers Elasticsearch</h2><p>La première étape consiste à ajouter <code>elasticsearch-ruby</code> dans le fichier Gemfile. Après l'exécution de <code>bundle install</code>, le client Elasticsearch Ruby gem sera installé. Si vous souhaitez tester votre code avant de migrer complètement, vous pouvez initialement laisser la gem <code>opensearch-ruby</code> en place.</p><p>La prochaine étape importante sera l'instanciation du client. Cela va dépendre de la manière dont vous utilisez Elasticsearch. Afin de conserver une approche similaire pour ces exemples, je suivrai les étapes de la section <a href="https://www.elastic.co/downloads/elasticsearch">Télécharger Elasticsearch</a> et l'exécuter localement.</p><p>Lors de l'exécution de <code>bin/elasticsearch</code>, Elasticsearch démarre avec des fonctions de sécurité automatiquement configurées. Veillez à copier le mot de passe de l'utilisateur élastique (mais vous pouvez le réinitialiser en lançant <code>bin/elasticsearch-reset-password -u elastic</code>). Si vous suivez cet exemple, assurez-vous d'arrêter OpenSearch avant de démarrer Elasticsearch, car ils fonctionnent sur le même port.</p><p>Au début de <code>example_code.rb</code>, j'ai commenté l'instanciation du client OpenSearch et j'ai ajouté l'instanciation d'un client 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>Comme vous pouvez le constater, le code est presque identique dans ce scénario de test. Elle diffère en fonction du déploiement d'Elasticsearch et de la manière dont vous décidez de vous connecter et de vous authentifier. Il en va de même pour OpenSearch en ce qui concerne la sécurité, l'option de ne pas vérifier ssl ne sert qu'à des fins de test et ne doit pas être utilisée en production.</p><p>Une fois le client configuré, j'exécute à nouveau le code avec : <code>bundle exec ruby example_code.rb</code>. Et tout fonctionne !</p><h2>Déboguer les problèmes de migration</h2><p>En fonction des API que votre application utilise, il est possible que vous receviez une erreur lorsque vous exécutez votre code contre Elasticsearch si les API d'OpenSearch divergent. La <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/rest-apis.html">documentation sur les API REST</a> est une référence essentielle pour obtenir des informations détaillées sur l'utilisation des API. Veillez à consulter la documentation relative à la version d'Elasticsearch que vous utilisez. Vous pouvez également consulter la référence <a href="https://rubydoc.info/gems/elasticsearch-api"><code>Elasticsearch::API</code></a>.</p><p>Voici quelques exemples d'erreurs que vous pouvez rencontrer avec Elasticsearch :</p><ul><li><p><code>ArgumentError: Required argument '&lt;ARGUMENT&gt;' missing</code> - Il s'agit d'une erreur du client qui se produit lorsqu'il manque un paramètre requis dans une demande.</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> Cette erreur provient d'Elasticsearch et signifie que le code client utilise un paramètre qu'Elasticsearch ne reconnaît pas pour l'API utilisée.</p></li></ul><p>Le client Elasticsearch lèvera les erreurs d'Elasticsearch avec le message d'erreur détaillé envoyé par le serveur. Ainsi, pour les paramètres ou les points de terminaison non pris en charge, l'erreur devrait vous informer de ce qui est différent.</p><h2>Conclusion</h2><p>Comme nous l'avons démontré avec cet exemple de code, la migration d'une application Ruby d'OpenSearch vers Elasticsearch n'est pas trop complexe du côté de Ruby. Vous devez être conscient des versions et des éventuelles divergences entre les API des moteurs de recherche. Mais pour les actions les plus courantes, le principal changement lors de la migration des clients se situe au niveau de l'instanciation. Ils sont tous deux similaires à cet égard, mais la façon dont l'hôte et les informations d'identification sont définis varie en fonction de la manière dont la pile est déployée. Une fois que le client est configuré et que vous avez vérifié qu'il se connecte à Elasticsearch, vous pouvez remplacer le client OpenSearch par le client 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>