<?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/es/search-labs/author/fernando-briano</link>
    </image>
    <link>https://www.elastic.co/es/search-labs/author/fernando-briano</link>
    <atom:link href="https://www.elastic.co/es/search-labs/rss/author/fernando-briano.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[es]]></language>
    <lastBuildDate>Mon, 28 Sep 2026 05:13:03 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Presentamos el ES|Generador de consultas QL para el cliente Ruby de Elasticsearch]]></title>
    <description><![CDATA[Aprende a usar el recientemente lanzado ES|Generador de consultas QL para el cliente Ruby de Elasticsearch. Una herramienta para construir ES|QL consulta más fácilmente con código Ruby.]]></description>
    <content:encoded><![CDATA[<p>Recientemente lanzamos <a href="https://github.com/elastic/esql-ruby/"><code>elastic-esql</code></a>, una joya Ruby publicada bajo la licencia Apache 2. Esta gema te permite construir el <a href="https://www.elastic.co/docs/explore-analyze/query-filter/languages/esql">ES| de ElasticConsultas QL</a> en Ruby idiomático, que luego puedes usar con el ES|API de consulta QL. ES|QL permite a los desarrolladores filtrar, transformar y analizar los datos almacenados en Elasticsearch mediante consultas. Emplea "tuberías" ( <code>|</code> ) para trabajar paso a paso con los datos. La gema emplea funciones Ruby en su lugar, que puedes encadenar al objeto original para crear consultas más complejas:</p><p><strong>ESQL:</strong></p><p><strong>Rubí:</strong></p>Elastic::ESQL.from('sample_data').limit(2).sort('@timestamp').descending<h2>Instalación</h2><p>La gema puede instalar desde RubyGems con:</p>gem install elastic-esql<p>O puede agregar al archivo de gemas de un proyecto:</p>gem 'elastic-esql'<h2>Uso</h2><p>Puedes construir una consulta completa de una vez o crear un objeto de consulta con un comando fuente como <code>from</code> o <code>row</code> y luego encadenar ES|QL métodos para construir sobre ella.</p>query = Elastic::ESQL.from('sample_data')
query.limit(2).sort('@timestamp')<p>La gema traduce el código a ES|QL en el método <code>to_s</code> , así que devuelve el ES|Consulta QL cuando se imprime o se convierte en una cadena:</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>Puedes instanciar un objeto de consulta y mutar su estado inicial usando los equivalentes <code>!</code> de cada función:</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>La herramienta ofrece formas cómodas de encadenar pasos extra a un ES|Función QL, como <code>enrich</code> y <code>sort</code>. Una vez que llamas <code>enrich</code> a un objeto <code>Elastic::ESQL</code> , puedes encadenar <code>on</code> y <code>with</code> a él:</p>esql.enrich!('policy').on('a').with({ name: 'language_name' })<p>También puedes encadenar <code>desc</code>, <code>asc</code>, <code>nulls_first</code> y <code>nulls_last</code> a tu consulta tras usar <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>También soporta cadenas personalizadas, por si quieres escribir el ES|Consulta QL tú mismo, o usa una función que aún no se agregó a la biblioteca. <code>custom</code> se unirán a las cadenas al final de la consulta. Los agregará a medida que se envían a la función, sin agregar ningún carácter de la tubería. Se combinarán con el resto de la consulta mediante un carácter espacio.</p>esql = Elastic::ESQL.from('sample_data')
esql.custom('| MY_VALUE = "test value"').to_s
# =&gt; 'FROM sample_data | MY_VALUE = "test value"'<p>También puedes encadenar <code>custom</code> funciones:</p>esql.custom('| MY_VALUE = "test value"').custom('| ANOTHER, VALUE')
'FROM sample_data | MY_VALUE = "test value" | ANOTHER, VALUE'<h2>Usando el ES|QL Query Builder con el cliente Ruby</h2><p>Puedes usar el constructor de consultas directamente con <a href="https://github.com/elastic/elasticsearch-ruby">elasticsearch-ruby</a> y la API <code>esql.query</code> enviando el objeto de consulta:</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>También puedes usarlo con el ES|QL Helper del cliente Ruby de Elasticsearch, <a href="https://www.elastic.co/search-labs/blog/esql-ruby-helper-elasticsearch">para saber más</a>:</p>require 'elasticsearch/helpers/esql_helper'

Elasticsearch::Helpers::ESQLHelper.query(client, query)<h2>Como herramienta independiente</h2><p>La gema está diseñada como una herramienta independiente para construir ES|QL consulta de forma idiomática. No tiene dependencias en tiempo de ejecución; puedes usarlo con el cliente oficial de Elasticsearch Ruby, o por separado.</p><p>La consulta generada puede usar con la API <a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-esql-query"><code>esql.query</code></a> de cualquier forma que una aplicación interactúe con la API de Elasticsearch (Ruby o no). Una vez que una consulta se construye con <code>elastic-esql</code>, la cadena generada puede enviar a la API como el parámetro <code>query</code> en el cuerpo de la solicitud. </p><p>Anteriormente escribí sobre <a href="https://www.elastic.co/search-labs/blog/elasticsearch-ruby-tools">el uso de Elasticsearch con las herramientas Ruby populares</a>. Esta gema puede usar con cualquiera de las herramientas Ruby populares para consultar Elasticsearch con ES|QL.</p><h2>Conclusión</h2><p>Esta biblioteca está en desarrollo activo y la API final aún no se completó. Actualmente está lanzado como un avance técnico. Si tienes algún comentario sobre la API actual o su uso general, no dudes en <a href="https://github.com/elastic/esql-ruby/issues">abrir un nuevo número</a>. Por favor, consulta <a href="https://github.com/elastic/esql-ruby/?tab=readme-ov-file#ruby-esql-query-builder">el README</a> para saber más sobre el Ruby ES|Constructor de consultas QL.</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[Cómo migrar tu aplicación Ruby de OpenSearch a Elasticsearch]]></title>
    <description><![CDATA[Una guía para migrar una base de código Ruby del cliente OpenSearch al cliente Elasticsearch.]]></description>
    <content:encoded><![CDATA[<p>El cliente Ruby de OpenSearch fue bifurcado desde el cliente Ruby de Elasticsearch en la versión <code>7.x</code>, por lo que las bases de código son relativamente similares. Esto significa que, al migrar una base de código Ruby de OpenSearch a Elasticsearch, el código de las respectivas bibliotecas cliente resultará muy familiar. En esta entrada del blog, voy a mostrar un ejemplo de aplicación Ruby que emplea OpenSearch y los pasos para migrar este código a Elasticsearch.</p><p>Ambos clientes están lanzados bajo la popular Apache License 2.0, por lo que son software de código abierto y libre. La licencia de Elasticsearch se actualizó recientemente y el núcleo de Elasticsearch y Kibana se publica bajo la licencia de código abierto aprobada por la OSI AGPL desde la versión 8.16.</p><h2>Considerando la versión de Elasticsearch al migrar la aplicación Ruby</h2><p>Una consideración al migrar es qué versión de Elasticsearch se va a emplear. Recomendamos usar la última versión estable, que en el momento de escribir esto es <code>8.17.0</code>. Las versiones menores del cliente Rubí de Elasticsearch siguen a las versiones menores de Elasticsearch. Así que para Elasticsearch <code>8.17.x</code>, puedes usar la versión <code>8.17.x</code> de la gema Rubí.</p><p>OpenSearch se bifurcó a partir de Elasticsearch 7.10.2. Así que las APIs pueden cambiar y se podrían usar diferentes funciones en cualquiera de las dos. Pero eso está fuera del alcance de esta publicación, y solo voy a analizar las operaciones más comunes en una aplicación de ejemplo.</p><p>Para Ruby on Rails, puedes usar el cliente oficial de Elasticsearch o las <a href="https://github.com/elastic/elasticsearch-rails/">bibliotecas de integración de Rails</a>. Recomendamos migrar a la última versión estable de Elasticsearch y del cliente, respectivamente. La versión <code>elasticsearch-rails</code> gema <code>8.0.0</code> soportar Rails <code>6.1</code>, <code>7.0</code> y <code>7.1</code> y Elasticsearch <code>8.x</code>.</p><h2>El código</h2><p>Para este ejemplo, seguí los pasos para <a href="https://opensearch.org/docs/latest/install-and-configure/install-opensearch/tar/">instalar OpenSearch desde un tarball</a>. Luego de descargar y extraer el tarball, necesitaba establecer una contraseña inicial de administrador que usaré más adelante para instanciar el cliente.</p><p>Creé un directorio con una <code>Gemfile</code> que se ve así:</p>source 'https://rubygems.org'

gem 'opensearch-ruby'<p>Luego de ejecutar <code>bundle install</code>, se instala la gema para mi proyecto. Esta versión de opensearch-ruby instalada <code>3.4.0</code> y la versión de OpenSearch que estoy usando es <code>2.18.0</code>. Escribí el código en un archivo <code>example_code.rb</code> en el mismo directorio. El código inicial en este archivo es la instancia de un cliente 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>La opción de transporte <code>ssl: { verify: false}</code> el parámetro se está pasando según la guía de usuario para facilitar las pruebas. En producción, esto debería configurar dependiendo del despliegue de OpenSearch.</p><p>Desde la versión 2.12.0 de OpenSearch, la variable de entorno <code>OPENSEARCH_INITIAL_ADMIN_PASSWORD</code> debe establecer con una contraseña fuerte al ejecutar el script de instalación. Siguiendo los pasos para instalar OpenSearch desde un tarball, exporté la variable en mi consola y ahora está disponible para mi script Ruby.</p><p>Una API sencilla para cerciorar de que el cliente se conecta a OpenSearch es usar la API <code>cluster.health</code> :</p>puts 'HEALTH:'
pp client.cluster.health<p>Y efectivamente funciona:</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>Probé algunos de los ejemplos comunes que tenemos en la documentación del cliente Ruby de Elasticsearch, y funcionan como se espera:</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>Migración de la aplicación Ruby a Elasticsearch</h2><p>El primer paso es agregar <code>elasticsearch-ruby</code> en el archivo gema. Tras ejecutar <code>bundle install</code>, se instalará la gema cliente Ruby de Elasticsearch. Si quieres probar tu código antes de migrar completamente, puedes dejar la gema <code>opensearch-ruby</code> ahí inicialmente.</p><p>El siguiente paso importante será la instanciación del cliente. Esto va a depender de cómo ejecutes Elasticsearch. Para mantener un enfoque similar en estos ejemplos, sigo los pasos de <a href="https://www.elastic.co/downloads/elasticsearch">Download Elasticsearch</a> y lo ejecuto localmente.</p><p>Al ejecutar <code>bin/elasticsearch</code>, Elasticsearch se iniciará con las funciones de seguridad configuradas automáticamente. Cerciórate de copiar la contraseña del usuario elástico (pero puedes restablecerla ejecutando <code>bin/elasticsearch-reset-password -u elastic</code>). Si sigues este ejemplo, cerciórate de detener OpenSearch antes de iniciar Elasticsearch, ya que se ejecutan en el mismo puerto.</p><p>Al principio de <code>example_code.rb</code>, comenté la instancia del cliente OpenSearch y agregué la instancia para un cliente 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>Como puedes ver, el código es casi idéntico en este escenario de pruebas. Variará según el despliegue de Elasticsearch y cómo decidas conectarte y autenticarte con él. Lo mismo aplica aquí que en OpenSearch en cuanto a seguridad, la opción de no verificar SSL es solo para fines de prueba y no debe usar en producción.</p><p>Una vez configurado el cliente, vuelvo a ejecutar el código con: <code>bundle exec ruby example_code.rb</code>. ¡Y todo simplemente funciona!</p><h2>Problemas de depuración de migración</h2><p>Dependiendo de las APIs que use tu aplicación, existe la posibilidad de que recibas un error al ejecutar tu código contra Elasticsearch si las APIs de OpenSearch divergen. La <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/rest-apis.html">documentación de las APIs REST</a> es una referencia esencial para obtener información detallada sobre cómo emplear las APIs. Cerciórate de consultar la documentación de la versión de Elasticsearch que estás usando. También puedes consultar la <a href="https://rubydoc.info/gems/elasticsearch-api"><code>Elasticsearch::API</code></a> referencia.</p><p>Algunos errores que puedes encontrar en Elasticsearch podrían ser:</p><ul><li><p><code>ArgumentError: Required argument '&lt;ARGUMENT&gt;' missing</code> - Esto es un error de cliente y se generará cuando una solicitud tenga un parámetro requerido.</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> Este error proviene de Elasticsearch y significa que el código del cliente está usando un parámetro que Elasticsearch no reconoce para la API que se está empleando.</p></li></ul><p>El cliente de Elasticsearch generará errores de Elasticsearch con el mensaje de error detallado enviado por el servidor. Así que, para parámetros o endpoints no soportados, el error debería informarte qué es diferente.</p><h2>Conclusión</h2><p>Como demostramos con este código de ejemplo, la migración de una aplicación Ruby de OpenSearch a Elasticsearch no es demasiado compleja desde el punto de vista de Ruby. Debes estar atento al versionado y a cualquier posible divergencia de APIs entre los motores de búsqueda. Pero para las acciones más comunes, el principal cambio al migrar clientes está en la instancia. Ambos son similares en ese aspecto, pero la forma en que se definen el host y las credenciales varía en función de cómo se despliega la pila. Una vez que el cliente está configurado y verifica que se conecta a Elasticsearch, puedes reemplazar el cliente OpenSearch sin problemas por el cliente 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>