Blog

La búsqueda de vectores de Elasticsearch es hasta 8 veces más rápida que OpenSearch

Exploramos los puntos de referencia de búsqueda vectorial con filtrado entre OpenSearch y Elasticsearch, y por qué el rendimiento de la búsqueda vectorial es crucial para los sistemas diseñados en función del contexto.

¿Por qué es importante la velocidad de búsqueda para los agentes de IA y la ingeniería de contexto?

Nuestros benchmarks en un corpus de documentos de 20M muestran que Elasticsearch ofrece hasta 8 veces más rendimiento que OpenSearch para búsqueda vectorial filtrada, además de lograr mayores Recall@100 en las configuraciones que probamos. La ingeniería de contexto depende de más que la rápida recuperación de vectores. Los equipos también necesitan fuertes controles de relevancia, como búsqueda y filtrado híbridos, simplicidad operativa y rendimiento predecible, a medida que los flujos de trabajo se repiten. Pero como los agentes suelen ejecutar bucles de recuperación y razonamiento muchas veces por cada solicitud, la latencia de la recuperación se convierte en un factor multiplicador, por lo que las mejoras en este aspecto se traducen directamente en una mejor capacidad de respuesta de extremo a extremo y en un menor costo.

OpenSearch vs. Elasticsearch: prueba de rendimiento para la búsqueda vectorial filtrada

Grafo 1: Rendimiento.

En la ingeniería de contexto, la recuperación no es un paso único. Los agentes y las aplicaciones ejecutan bucles repetidamente, como recuperar → razonar → recuperar, para refinar consultas, verificar hechos, reunir contexto fundamentado y completar tareas. Este patrón es común en los flujos de trabajo agénticos y en la Retrieval-Augmented Generation (RAG) iterativa. Como la recuperación puede invocarse muchas veces por cada consulta del usuario, agrega demora a la respuesta o aumenta los costos de infraestructura.

La ingeniería de contexto convierte un gran grupo de contexto en una ventana de contexto limitada del LLM.

Figura 1: La ingeniería de contexto convierte un gran grupo de contexto (documentos, memoria, herramientas, historial de chat) en una ventana de contexto limitada de un modelo de lenguaje grande (LLM, por su sigla en inglés) mediante recuperación y curación repetidas.

La implementación óptima de la ingeniería de contexto es una técnica emergente. El número de iteraciones varía mucho según el flujo de trabajo. El concepto clave más fundamental para estos resultados de benchmark es que la ingeniería de contexto es direccional: la recuperación iterativa convierte la latencia en un multiplicador.

¿Por qué es crítico el rendimiento de la búsqueda de vectores?

Imagina un asistente de compras respondiendo la pregunta: "Necesito una mochila de equipaje de mano de menos de $60 que quepa una laptop de 15 pulgadas, sea resistente al agua y pueda llegar para el viernes".

En producción, el asistente rara vez emite una consulta vectorial y se detiene ahí. Ejecuta un ciclo de recuperación para crear el contexto correcto, y cada paso suele estar limitado por filtros, como disponibilidad, región, promesa de envío, reglas de marca y elegibilidad de políticas.

Paso 1: Interpretar la intención y traducirla a restricciones.

El agente convierte la solicitud en filtros estructurados y una consulta semántica, tales como:

  • Filtros: En stock, entregable al código postal del usuario, entrega antes del viernes, precio inferior a $60, listado válido

  • Consulta vectorial: "Mochila de equipaje de mano computadora portátil de 15 pulgadas resistente al agua"

Paso 2: Recuperar candidatos y luego refinar la selección.

A menudo repite la recuperación con variaciones para evitar perder buenas coincidencias:

  • "mochila de viaje de equipaje de mano con funda para computadora portátil"

  • "mochila de viaje resistente al agua de 15 pulgadas"

  • “mochila de cabina ligera”

Cada consulta utiliza los mismos filtros de elegibilidad, porque recuperar elementos irrelevantes o no disponibles es un desperdicio de contexto.

Paso 3: Expandir para confirmar detalles y reducir el riesgo.

A continuación, el agente vuelve a consultar para verificar los atributos clave que influyen en la respuesta final:

  • Palabras utilizadas para describir los materiales y la resistencia al agua

  • Dimensiones y ajuste del compartimento de la computadora portátil

  • Restricciones de la garantía o política de devolución

  • Opciones alternativas si hay poco inventario

Esto es ingeniería de contexto en múltiples pasos: recuperar, razonar, recuperar, ensamblar.

¿Por qué la latencia y la recuperación son importantes para la ingeniería de contexto?

Estas interacciones pueden implicar decenas de llamadas de recuperación filtradas por sesión de usuario. Eso hace que la latencia por llamada sea un multiplicador directo en el tiempo de respuesta de extremo a extremo, y la baja recuperación obliga a reintentos adicionales o hace que el agente pierda elementos elegibles, lo que degrada la calidad de la respuesta.

Conclusión: En sistemas diseñados con contexto, los vecinos más cercanos aproximados (ANN, por su sigla en inglés) filtrados no son una sola consulta. Es una operación repetida bajo restricciones, por lo que el rendimiento de la búsqueda vectorial se nota enseguida en la latencia, la capacidad de procesamiento y el costo, incluso cuando el modelo de lenguaje grande (LLM) es el componente más visible.

Evaluación comparativa

Resultados

En el grafo 2, cada punto representa una configuración de prueba. Los mejores resultados aparecen hacia la parte superior izquierda, lo que significa una mayor recuperación con menor latencia. Los resultados de Elasticsearch se sitúan sistemáticamente más cerca de la esquina superior izquierda que los de OpenSearch, lo que indica una mayor velocidad y precisión con los mismos ajustes de carga de trabajo.

 Grafo 2: Recuperación versus latencia promedio (recalificación 1).

Grafo 2: Recuperación versus latencia promedio, recalificación de 1.

Algunas ideas clave

  • s_n_r_value: La abreviatura de size_numCandidates_rescoreOversample (k y numCandidates iguales a numCandidates en estas pruebas), por ejemplo, 100_500_1 significa tamaño=100, numCandidates=500 y k=500, rescore oversample=1

  • Recuperación: Mide Recall@100 para esa configuración

  • Latencia promedio (ms): Latencia de extremo a extremo promedio por consulta

  • Rendimiento: Búsquedas por segundo

  • Recall %: Mejora relativa de recuperación de Elasticsearch frente a OpenSearch (Elasticsearch menos OpenSearch)/OpenSearch

  • Latencia Xs: Latencia promedio de OpenSearch dividida por la latencia media de Elasticsearch

  • Rendimiento Xs: rendimiento de Elasticsearch dividido por el rendimiento de OpenSearch

Motor

's_n_r_value'

Recuperación

Latencia promedio (ms)

Rendimiento

Porcentaje de recuperación

Latencia Xs

Rendimiento Xs

Elasticsearch

100_250_1

0.7704

25

534.75

9.70 %

2.28

1.91

OpenSearch

100_250_1

0.7023

57.08

279.58

Elasticsearch

100_500_1

0.8577

25.42

524.14

7.20 %

2.4

2

OpenSearch

100_500_1

0.8001

60.9

262.12

Elasticsearch

100_750_1

0.8947

29.67

528.09

5.72 %

2.25

2.21

OpenSearch

100_750_1

0.8463

66.76

239.11

Elasticsearch

100_1000_1

0.9156

29.65

534.5

4.66 %

2.46

2.44

OpenSearch

100_1000_1

0.8748

72.88

219.01

Elasticsearch

100_1500_1

0.9386

31.84

497.3

3.38 %

2.71

2.68

OpenSearch

100_1500_1

0.9079

86.16

185.4

Elasticsearch

100_2000_1

0,9507

34.69

457.2

2.57 %

2.98

2.96

OpenSearch

100_2000_1

0.9269

103.36

154.55

Elasticsearch

100_2500_1

0.9582

37.9

418.43

1.99 %

3.28

3.26

OpenSearch

100_2500_1

0.9395

124.29

128.53

Elasticsearch

100_3000_1

0.9636

41.86

379.4

1.62 %

3.46

3.44

OpenSearch

100_3000_1

0.9482

144.67

110.34

Elasticsearch

100_4000_1

0.9705

50.28

316.21

1,06%

3.87

3.85

OpenSearch

100_4000_1

0.9603

194.36

82.22

Elasticsearch

100_5000_1

0.9749

58.77

270.91

0.73 %

4.43

4.41

OpenSearch

100_5000_1

0.9678

260.33

61.38

Elasticsearch

100_6000_1

0.9781

66.75

238.59

0.52 %

4.91

4.89

OpenSearch

100_6000_1

0.973

327.44

48.81

Elasticsearch

100_7000_1

0.9804

74.64

213.49

0.38 %

5.28

5.27

OpenSearch

100_7000_1

0.9767

394.24

40.53

Elasticsearch

100_8000_1

0.9823

82.28

193.59

0.27 %

6.86

6.83

OpenSearch

100_8000_1

0.9797

564.14

28.33

Elasticsearch

100_9000_1

0.9837

90.08

176.96

0.16 %

7.63

7.61

OpenSearch

100_9000_1

0.9821

687.25

23.25

Elasticsearch

100_10000_1

0.9848

97.64

163.31

0.08 %

8.38

8.36

OpenSearch

100_10000_1

0.984

818.64

19.53

Por ejemplo, en 100_9000_1, OpenSearch tiene un promedio de 687 milisegundos por recuperación frente a 90 milisegundos en Elasticsearch, y en un bucle de recuperación de 10 pasos eso equivale a aproximadamente 10 × (687 - 90) = seis segundos de tiempo de espera adicional.

Consulta los resultados completos.

Metodología

Al usar Python para enviar las consultas y rastrear el tiempo de respuesta y otras estadísticas, enviamos las siguientes consultas a los motores. Ten en cuenta que el rendimiento de cualquier motor de búsqueda vectorial depende de cómo ajustes sus parámetros núcleo: cuántos candidatos considerar, cuán agresivamente volver a puntuar y cuánto contexto devolver. Estos ajustes afectan directamente tanto la exhaustividad (la probabilidad de encontrar la respuesta correcta) como la latencia (la rapidez con la que obtienes los resultados).

En nuestras pruebas comparativas, empleamos la misma configuración de candidatos, repuntuación y tamaño de resultados que normalmente ajustarías en un bucle de recuperación basado en agentes, y medimos el rendimiento de Elasticsearch bajo esa carga de trabajo. Luego ejecutamos OpenSearch con la misma configuración como referencia.

OpenSearch

GET <INDEX_NAME>/_search
{
  "query": {
    "knn": {
      "<DENSE_VECTOR_FIELD_NAME>": {
        "vector": [...],
        "k": <NUMBER_OF_CANDIDATES>,
        "method_parameters": {
          "ef_search": <NUMBER_OF_CANDIDATES>
        },
        "rescore": {
          "oversample_factor": <OVERSAMPLE>
        },
        "filter": {
          <SOME_FILTER>
        }
      }
    }
  },
  "size": <RESULT_SIZE>,
  "_source": {
    "excludes": [
      "<DENSE_VECTOR_FIELD_NAME>"
    ]
  }
}
  • "size": <RESULT_SIZE>: Número de resultados devueltos al cliente. En esta prueba de rendimiento, el tamaño del conjunto de datos es 100 para calcular el Recall@100.

  • "k": <NUMBER_OF_CANDIDATES>: El número de candidatos a vecinos más cercanos.

  • "ef_search": <NUMBER_OF_CANDIDATES>: El número de vectores a examinar.

  • "oversample_factor": <OVERSAMPLE>: ¿Cuántos vectores candidatos se recuperan antes de volver a calcular la puntuación?

Elasticsearch

GET <INDEX_NAME>/_search
{
  "query": {
    "knn": {
      "field": "<DENSE_VECTOR_FIELD_NAME>",
      "query_vector": [...],
      "k": <NUMBER_OF_CANDIDATES>,
      "num_candidates": <NUMBER_OF_CANDIDATES>,
      "rescore_vector": {
        "oversample": <OVERSAMPLE>
      },
      "filter": {
        <SOME_FILTER>
      }
    }
  },
  "size": <RESULT_SIZE>,
  "_source": {
    "excludes": [
      "<DENSE_VECTOR_FIELD_NAME>"
    ]
  }
}
  • "size": <RESULT_SIZE>: Número de resultados devueltos al cliente. En esta prueba de rendimiento, el tamaño del conjunto de datos es 100 para calcular el Recall@100.

  • "k": <NUMBER_OF_CANDIDATES>: Número de vecinos más cercanos que se debe devolver desde cada shard.

  • "num_candidates": <NUMBER_OF_CANDIDATES>: Número de candidatos de vecinos más cercanos a considerar por shard mientras se realiza la búsqueda de knn.

  • "oversample": <OVERSAMPLE>: ¿Cuántos vectores candidatos se recuperan antes de volver a calcular la puntuación?

Ejemplo

Knn la búsqueda, (100_500_1), sería de la siguiente manera:

OpenSearch

GET search_catalog_128/_search
{
  "query": {
    "knn": {
      "search_catalog_embedding": {
        "vector": [...],
        "k": 500,
        "method_parameters": {
          "ef_search": 500
        },
        "rescore": {
          "oversample_factor": 1
        },
        "filter": {
          "term": {
            "valid": true
          }
        }
      }
    }
  },
  "size": 100,
  "_source": {
    "excludes": [
      "search_catalog_embedding"
    ]
  }
}

Elasticsearch

GET search_catalog_128/_search
{
  "query": {
    "knn": {
      "field": "search_catalog_embedding",
      "query_vector": [...],
      "k": 500,
      "num_candidates": 500,
      "rescore_vector": {
        "oversample": 1
      },
      "filter": {
        "term": {
          "valid": true
        }
      }
    }
  },
  "size": 100,
  "_source": {
    "excludes": [
      "search_catalog_embedding"
    ]
  }
}

La configuración completa, junto con scripts de Terraform, manifiestos de Kubernetes y el código de benchmarking, está disponible en este repositorio en la carpeta es-9.3-vs-os-3.5-vector-search.

La configuración del cluster

Ejecutamos nuestras pruebas en seis servidores cloud e2-standard-16, cada uno con 16 vCPUs y 64 GB de RAM. En cada servidor, asignamos 15 vCPUs y 56 GB de RAM a cada pod de Kubernetes que ejecutaba el nodo del motor de búsqueda, con 28 GB reservados para el heap de JVM.

Los clústeres ejecutaban Elasticsearch 9.3.0 y OpenSearch 3.5.0 (Lucene 10.3.2). Dado que ambos sistemas emplean la misma versión de Lucene en esta prueba comparativa, las diferencias de rendimiento y latencia que observamos no pueden atribuirse únicamente a Lucene, sino que reflejan diferencias en la forma en que cada motor integra y ejecuta la recuperación y recalculación filtradas del algoritmo k-vecinos más cercanos (kNN). Usamos un único índice con tres shards primarios y una réplica (es decir, 6 shards en total, 1 por nodo).

También usamos un servidor independiente en la misma región para ejecutar el cliente de pruebas de rendimiento y recopilar estadísticas de tiempos.

Configuración del clúster para las pruebas de rendimiento de Elasticsearch y OpenSearch

Figura 2: Diagrama de la configuración de los clústeres.

El set de datos

Para este benchmark, empleamos un set de datos de incrustación de catálogos de tipo comercio electrónico a gran escala con 20 millones de documentos, diseñado para reflejar la recuperación vectorial filtrada a escala del mundo real.

Cada documento representa un artículo del catálogo e incluye:

  • Un vector denso incrustado de 128 dimensiones utilizado para la recuperación aproximada de kNN.

  • Campos estructurados de metadatos usados para filtrar (por ejemplo, validez y disponibilidad de artículos más otras restricciones del catálogo) que permiten el patrón común de producción de recuperar a los vecinos más cercanos, pero solo dentro de un subconjunto elegible.

Elegimos este set de datos porque captura el núcleo del desafío principal de rendimiento que vemos en sistemas agentes y de estilo RAG en producción: la similitud vectorial por sí sola no es suficiente, la recuperación está frecuentemente limitada por filtros y el sistema debe mantener una alta recuperación a la vez que mantiene baja la latencia bajo esas restricciones. En comparación con sets de datos más pequeños de estilo QA, un corpus de 20M de documentos también refleja mejor la escala y la presión de los candidatos que enfrentan los sistemas de ANN filtrados en la práctica.

Conclusión

En las arquitecturas de IA modernas, especialmente aquellas construidas alrededor de la ingeniería de contexto, la velocidad de búsqueda vectorial no es un detalle de implementación menor. Es un multiplicador. Cuando los agentes y los flujos de trabajo iteran a través de recuperar → razonar → recuperar, el rendimiento de la recuperación da forma directamente a la latencia de extremo a extremo, al rendimiento y a la calidad del contexto que se introduce en el modelo.

En nuestras pruebas de referencia, Elasticsearch ofreció consistentemente una mayor recuperación con menor latencia que OpenSearch en escenarios donde la corrección depende de recuperar el documento correcto, no solo de un vector similar. En un set de datos controlado, la diferencia es clara, y en producción esos avances se acumulan a lo largo de grandes volúmenes de llamadas de recuperación, lo que mejora la capacidad de respuesta, aumenta el margen de capacidad y reduce los costos de infraestructura.

Lecturas adicionales

  1. ¿Qué es la ingeniería de contexto?

  2. La evolución de la búsqueda híbrida y la ingeniería de contexto

  3. El impacto de la relevancia en la ingeniería de contexto para agentes de IA

Contenido relacionado

LINQ a Elasticsearch ES|QL: escribir en C#, buscar en Elasticsearch

Florian Bernd

Mejorando las capacidades de los chatbots con PLN y búsqueda vectorial en Elasticsearch

Priscilla Parodi

Elasticsearch vs. OpenSearch: Comparación del rendimiento de búsqueda vectorial

Ugo Sangiorgi

Plagio por IA: detección de plagio con Elasticsearch

Priscilla Parodi

Técnicas avanzadas de RAG parte 2: Consultas y pruebas

Han Xiang Choong

¿Estás listo para crear experiencias de búsqueda de última generación?

No se logra una búsqueda suficientemente avanzada con los esfuerzos de uno. Elasticsearch está impulsado por científicos de datos, operaciones de ML, ingenieros y muchos más que son tan apasionados por la búsqueda como tú. Conectemos y trabajemos juntos para crear la experiencia mágica de búsqueda que te dará los resultados que deseas.

Pruébalo tú mismo