Que es Opensearch
OpenSearch es una suite de búsqueda y análisis de código abierto, con licencia Apache 2.0. Fue creado como fork de Elasticsearch + Kibana (versiones 7.10) en 2021 porque hubo un cambio de licencia hacia una menos permisiva y hubo preocupaciones en cuanto a restricciones de uso libre. Se organiza como un proyecto comunitario (OpenSearch Software Foundation) y está bajo el paraguas de la Linux Foundation. Una parte fundamental de este proyecto es que las corporaciones pueden tener el control total del código.
Permite inferir, buscar, visualizar y analizar datos para un gran número de casos de uso como análisis de logs u observabilidad, motor de búsqueda en sitios web, aplicaciones o catálogos, análisis de métricas y agregaciones (por ejemplo cómo se comportan KPIs con el tiempo). Otro caso de uso es detección de anomalías (ML básico) o incluso búsquedas vectoriales (KNN o vecinos más cercanos). En este artículo vamos a centrarnos en la indexación y en las búsquedas.
Indexar y buscar datos
Antes de nada, indexar significa almacenar un documento de forma estructurada y preparada para búsqueda rápida. El documento se convierte en un conjunto de campos y tokens, que son guardados en un indice invertido (estructura optimizada para responder rápido a búsquedas de texto) y al mismo tiempo el documento se guarda también para recuperarlo cuando hay coincidencias.
En este caso disponemos de un pequeño dataset de películas con el que haremos las pruebas.
Una herramienta muy util para ver como funciona nuestro indice es Opensearch Dashboard con el que tenemos un menú de Devtools para poder usar el indice y probar.
La primera búsqueda básica que podemos hacer es
GET /movies/_search
El resultado (o al menos parte de el) seria:
{
"took": 15,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 10,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "movies",
"_id": "xUp_55kBNlxXEfAmH62Z",
"_score": 1,
"_source": {
"title": "Inception",
"year": 2010,
"genre": [
"Sci-Fi",
"Thriller"
],
"rating": 8.8,
"director": "Christopher Nolan",
"duration_min": 148
}
},
De esta salida podemos sacar:
- Ha tardado 15 ms en hacer la consulta.
- Ha encontrado 10 valores y con coincidencia exacta.
- El max_score es 1. Esto significa que los documentos tendrán, como mucho, un 1 en su valor score.
- Como vemos, en el resultado mostrado, el _score es 1 y los resultados son devueltos dentro del array hits.
La estructura es la siguiente, tenemos primero la orden (GET), seguido del nombre del índice y la operación que vamos a realizar. Por ejemplo, podríamos obtener los mappings de Opensearch con:
GET /movies/_mapping

O incluso podríamos ver los índices que tenemos con:
GET /_cat/indices

Búsqueda de datos por coincidencia exacta
GET /movies/_search
{
"query": {
"match": {
"title": "Inception"
}
}
}
Búsqueda de datos por coincidencia parcial
GET /movies/_search
{
"query": {
"prefix": {
"title.keyword": "Incep"
}
}
}
Búsqueda de datos con fuzzy search
La fuzzy search nos permite busca registros incluso si hay algun error en la palabra clave usada para buscar. En este caso vamos a usar Indeption en vez de Inception para ver si la encuentra:
GET /movies/_search
{
"query": {
"match": {
"title": {
"query": "Indeption",
"fuzziness": "AUTO"
}
}
}
}
Con el campo fuzziness determinamos cuantos errores admitimos, podemos poner 1, 2 o los que necesitemos. Si ponemos AUTO es Opensearch quien se adapta a todos los posibles errores. Las busquedas fuzzy afectan al rendimiento asi que debemos usarlas solo en aquellos campos realmente necesarios.
Consultas más poderosas
Opensearch tiene la flexibilidad para que podamos customizar nuestras consultas de muchas maneras. Por ejemplo, tenemos condiciones de should, must, must_not o filter.
Por ejemplo queremos filtrar películas de acción, con una nota superior a 8 pero excluyendo las películas de Michael Bay y además queremos que todas sean del 2000 para adelante:
Consultas compuestas
GET movies/_search
{
"query": {
"bool": {
"must": [
{ "match": { "genre": "Action" } },
{ "range": { "rating": { "gte": 8 } } }
],
"must_not": [
{ "match": { "director": "Michael Bay" } }
],
"filter": [
{ "range": { "year": { "gte": 2000 } } }
]
}
}
}
Aggregations
Sirven para analizar datos, no solo buscarlos — tipo SQL GROUP BY, pero con superpoderes.
GET movies/_search
{
"size": 0,
"aggs": {
"by_genre": {
"terms": { "field": "genre.keyword" }
},
"avg_rating": {
"avg": { "field": "rating" }
},
"by_year": {
"histogram": {
"field": "year",
"interval": 10
}
}
}
}
Queries multi match
La query multi_match es perfecta para mostrar cómo OpenSearch puede buscar un mismo término en varios campos al mismo tiempo (por ejemplo, título, director o género).
GET movies/_search
{
"query": {
"multi_match": {
"query": "Nolan",
"fields": ["title", "director", "genre"]
}
}
}
Conclusión
A esta altura, ya vimos que OpenSearch no es solo un motor de búsqueda: es una plataforma completa para explorar, analizar y entender datos. Desde simples búsquedas textuales hasta consultas complejas y agregaciones, te permite construir experiencias de búsqueda potentes sin salir del ecosistema open source.
