<?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[Conceptos básicos - 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[Conceptos básicos - 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/blog/category/basics</link>
    </image>
    <link>https://www.elastic.co/es/search-labs/blog/category/basics</link>
    <atom:link href="https://www.elastic.co/es/search-labs/rss/category/basics.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[es]]></language>
    <lastBuildDate>Tue, 29 Sep 2026 04:13:37 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Cómo desplegar Elasticsearch en Azure AKS Automatic]]></title>
    <description><![CDATA[Aprende cómo desplegar Elasticsearch con Kibana en Azure usando AKS Automatic y ECK para una configuración parcialmente gestionada de Elasticsearch.]]></description>
    <content:encoded><![CDATA[<p>Este artículo forma parte de un serial en la que aprenderemos a instalar Elasticsearch usando diferentes infraestructuras.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt45071aec499098c0/6a17fe770b0beda3d1dd37f4/0a65ca8b62fd8a42d7751b8f4bf057e33d877304-940x458.png" alt="Esfuerzos de despliegue de Elasticsearch" /><p>ECK requiere mucho más esfuerzo que las soluciones Elastic Cloud basadas en el Marketplace, pero es más automatizado que desplegar VMs por tu cuenta, porque el operador Kubernetes se encargará de la orquestación del sistema y el escalado de nodos.</p><p>Esta vez, vamos a trabajar con el Azure Kubernetes Service (AKS), usando Automático. En los otros artículos aprenderás a usar <a href="https://www.elastic.co/search-labs/blog/azure-elasticsearch-vm-deployment">Azure VM</a> y <a href="https://www.elastic.co/search-labs/blog/deploy-elasticsearch-azure-marketplace">Azure Marketplace</a>.</p><h2>¿Qué es AKS Automático?</h2><p><a href="https://learn.microsoft.com/en-us/azure/aks/intro-aks-automatic">Azure Kubernetes Service (AKS) </a>gestiona automáticamente la configuración del clúster, asigna dinámicamente los recursos e integra las mejores prácticas de seguridad mientras preserva la flexibilidad de Kubernetes, permitiendo a los desarrolladores pasar de la imagen del contenedor a la aplicación desplegada en cuestión de minutos.</p><p>AKS Automatic elimina la mayor parte de la gestión del cluster y logra un buen equilibrio entre simplicidad y flexibilidad. La elección correcta depende de tu caso de uso, pero la decisión es más fácil si planeas:</p><ul><li><p><strong>Despliega un entorno de pruebas: </strong>El despliegue es rápido y sencillo, lo que lo hace ideal para experimentos rápidos o clústeres de corta duración.</p></li><li><p><strong>Trabajar sin requisitos estrictos de máquinas virtuales, almacenamiento o redes: </strong>AKS Automatic ofrece valores predeterminados, así que si esos se ajustan a tus necesidades, te ahorra más configuraciones.</p></li><li><p><strong>Empieza por Kubernetes por primera vez: </strong>Al gestionar gran parte de la configuración del clúster, AKS Automatic reduce la curva de aprendizaje y permite a los equipos centrar en sus aplicaciones.</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9e74556cda9b56bd/6a17fe791d1b830cdc93e681/2e4c09b8c5e0ce5e8ea9c369626a373b7030a5ba-854x489.png" alt=" Cómo crear un clúster automático de Azure Kubernetes Service (AKS)" /><p>Para Elasticsearch, vamos a usar <a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s">Elastic Cloud on Kubernetes </a>(ECK), que es el operador oficial de Elastic Kubernetes que simplifica la orquestación de despliegues de Kubernetes en Elastic Stack.</p><h2>Cómo configurar AKS Automatic</h2><p>1. Iniciar sesión en el <a href="https://azure.microsoft.com/">Portal Microsoft Azure</a>.</p><p>2. En <strong>la parte superior derecha, </strong>haz clicen el botón<strong> Cloud Shell</strong> para acceder a la consola y desplegar el clúster AKS desde allí. Alternativamente, puedes usar <a href="https://learn.microsoft.com/en-us/azure/cloud-shell/overview">Azure Cloud Shell</a>.</p><p><em><strong>Recuerda actualizar el ID del proyecto con el tuyo durante el tutorial.</strong></em></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt06acd165140f9ab5/6a17fe7ae9ea876604a9c849/0aa60605777c0a6e3aef8faa4e54388c2cb582c8-624x495.png" alt="" /><p><em>Abrir el AKS debería ver como en la captura de pantalla de arriba.</em></p><p>3. Instalar la extensión aks-preview de Azure CLI. Esta versión previa nos permitirá seleccionar <code>--sku automatic</code> en la creación del clúster, lo que habilita la función AKS Automática.</p>az extension add --name aks-preview<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt703add301bb94b89/6a17fe7c57726213da1bce20/2e05ab67fc554c5fb5208683c179fdeaeadd95db-624x56.png" alt="" /><p><em>Si ves este mensaje, significa que la extensión AKS se instaló correctamente.</em></p><p>4. Registrar<a href="https://learn.microsoft.com/en-us/azure/azure-app-configuration/concept-feature-management"> banderas de características</a> usando el comando <code>az feature register</code></p>az feature register --namespace Microsoft.ContainerService --name AutomaticSKUPreview<p><em>Veréis los detalles sobre la subscripción a la función que acabamos de crear:</em></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt024ca2930c3a02e3/6a17fe7ee9ea87e003a9c84d/3aca710c1f312ba91de461638e518386919ec722-801x138.png" alt="" /><p>Verifica el estado del registro hasta que cambie de "<em><strong>Registrado</strong></em>" a "<em><strong>Registrado</strong></em>". Puede tardar unos minutos en terminar el registro.</p>az feature show --namespace Microsoft.ContainerService --name AutomaticSKUPreview<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0b8d717b484bd461/6a17fe7f445de951aa4d0382/186486b08ab8e1c372efaff50f10cbddeaf4e0cd-844x177.png" alt="" /><p>Ejecuta <code>az provider register</code> para propagar los cambios.</p>az provider register --namespace Microsoft.ContainerService<p>5. Crear un grupo de recursos</p><p>Un grupo de recursos es un grupo lógico de recursos Azure que deben gestionar y desplegar.</p>az group create --name elastic-resource --location eastus<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbbf4b6e75c2dd560/6a17fe8163baff6114741e72/d1952269e97d94f914020754bd02702f9eafd037-770x212.png" alt="" /><p>6. Crear un clúster de Autopilot. Lo llamaremos <em><strong>myAKSAutomaticCluster </strong></em>y usaremos el grupo de recursos que acabamos de crear. Cerciórate de tener <em><strong>disponibles 16 vCPUs</strong></em> en cualquiera de los siguientes tamaños de VM: <a href="https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/dpsv5-series">Standard_D4pds_v5</a>, <a href="https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/dldsv5-series">Standard_D4lds_v5</a>, <a href="https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/dadsv5-series">Standard_D4ads_v5</a>, <a href="https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/ddsv5-series">Standard_D4ds_v5</a>, <a href="https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/ddv5-series">Standard_D4d_v5</a>, <a href="https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/ddv4-series">Standard_D4d_v4</a>, <a href="https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/dsv3-series">Standard_DS3_v2</a> <a href="https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/memory-optimized/dv2-dsv2-series-memory">Standard_DS12_v2</a> para que AKS asigne recursos.</p>az aks create \
    --resource-group elastic-resource \
    --name myAKSAutomaticCluster \
    --sku automatic \
    --generate-ssh-keys<p><em>* Si aparecen </em><em><code>MissingSubscriptionRegistration</code></em><em> errores, vuelve al paso 4 con las subscripciones que faltan. Por ejemplo, </em><em><code>The subscription is not registered to use namespace '</code></em><em><strong><code>microsoft.insights</code></strong></em><em><code>'</code></em><em> requiere correr </em><em><code>az provider register --namespace Microsoft.Insights.</code></em></p><p>Sigue el inicio de sesión interactivo:</p><p><em>Aparecerá un mensaje pidiendo ejecutar "az login". Tienes que ejecutar ese comando y luego esperar.</em></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc711a241388cf786/6a17fe83dbb4fff454fb5929/14c0238f755fe6347519e69d3cb28c0fa52ec044-775x203.png" alt="" /><p>7. Esperar a que esté listo. Tarda unos 10 minutos en crear.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc389eecd12e3b2c8/6a17fe8425daab0b2408a442/eb00c3ad18f884f47db6645b196808ebec07c1fc-797x177.png" alt="" /><p>8. Configurar el acceso en línea de comandos de kubectl.</p>az aks get-credentials --resource-group elastic-resource --name myAKSAutomaticCluster<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfdb13d3950950b06/6a17fe85b1e11319e179f4bd/5136d72a5d455345b0b6205bb232c4bdf7762998-793x52.png" alt="" /><p><em>Ten en cuenta que la extensión que instalamos está habilitando AKS Automatic.</em></p><p>9. Confirmar que los nodos se desplegaron.</p>kubectl get nodes<p>Verás un mensaje de error prohibido; copia el ID de usuario del error.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4b2bb8558e1a39f4/6a17fe87a292991ce3d02ea8/d6c021fa54f4db00d2d795f5ba9b5a93376d03cd-818x47.png" alt="" /><p>10. Agregar a tu usuario al control de acceso de AKS.</p><p>Consigue el ID AKS. Copia la salida del comando.</p>az aks show --resource-group elastic-resource  --name myAKSAutomaticCluster --query id --output tsv<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0ebc4fa29348d561/6a17fe896df7317a3b0a1166/22a1cdc538bd379812a752c6a368a0651000abb8-810x36.png" alt="" /><p>Crea una asignación de roles usando el ID AKS y el ID principal de tu usuario.</p>az role assignment create --role "Azure Kubernetes Service RBAC Cluster Admin" --assignee &lt;PRINCIPAL_ID&gt; --scope &lt;AKS_ID&gt;<p>11. Intenta confirmar que los nodos se desplegaron de nuevo.</p>kubectl get nodes<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltda416366f0e53d49/6a17fe8ab1e113f87c79f4c1/c9b3a5c1cc540ef732c3e7f60b0a973bdbd0b6fd-617x99.png" alt="" /><p>12. Instalar la Nube Elástica en el operador Kubernetes (ECK).</p># Install ECK Custom Resource Definitions
kubectl create -f https://download.elastic.co/downloads/eck/2.16.1/crds.yaml

# Install the ECK operator
kubectl apply -f https://download.elastic.co/downloads/eck/2.16.1/operator.yaml<p>13. Vamos a crear una instancia de Elasticsearch de un solo nodo con los valores predeterminados.</p>cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: quickstart
spec:
  version: 9.0.0
  nodeSets:
  - name: default
    count: 1
    config:
      node.store.allow_mmap: false
EOF<p>Desactivamos <code>nmap</code> porque la máquina AKS predeterminada tiene un valor de <code>vm.max_map_count</code> demasiado bajo. No se recomienda desactivarlo para la producción, pero sí aumentar el valor de <code>vm.max_map_count</code>. Puedes leer más sobre cómo hacerlo <a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s/virtual-memory">aquí</a>.</p><p>14. Desplieguemos también un clúster Kibana de un solo nodo. Para Kibana, agregaremos un balanceador de carga, que nos dará una IP externa que podremos usar para llegar a Kibana desde nuestro dispositivo.</p>cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
  name: quickstart
spec:
  version: 9.0.0
  http:
    service:
      spec:
        type: LoadBalancer
  count: 1
  elasticsearchRef:
    name: quickstart
EOF<p>Por defecto, AKS Automatic configurará el balanceador de carga como público; Puedes cambiar el comportamiento configurando la anotación de metadatos:</p><p><code>service.beta.kubernetes.io/azure-load-balancer-internal: "true"</code></p><p>15. Comprueba que tus cápsulas estén funcionando.</p>kubectl get pods<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltea98380109a7a0b1/6a17fe8c4b055dda6c43241e/213a897176c0af6cea19c7c777cfaf8734e3ee6e-616x84.png" alt="" /><p>16. También puedes ejecutar <code>kubectl get elasticsearch</code> y <code>kubectl get kibana</code> para estadísticas más específicas como la versión de Elasticsearch, nodos y salud.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt89119d59582673d9/6a17fe8d4b055d4257432422/c84988e725ef892eddd8fb7e5a03d58c35a8f9d6-470x62.png" alt="" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte714550df3504cd4/6a17fe8f7b54f982a28b3b19/452dd03d314cd00c8a3c19e19862b968592a0435-415x62.png" alt="" /><p>17. Accede a tus servicios.</p>kubectl get svc<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfc9c24dc9b78a354/6a17fe900b0beda9f8dd37f8/b2d3e8f368be22b89aa2ed4d4d514f97dd6cbabd-624x115.png" alt="" /><p>Esto te mostrará la <a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s/accessing-services">URL externa</a> de Kibana bajo EXTERNAL-IP. Puede que el balanceador de carga tarde unos minutos en provisionarse. <em><strong>Copia el valor de EXTERNAL-IP.</strong></em></p><p>18. Consigue la contraseña de Elasticsearch para el usuario 'elastic':</p>kubectl get secret quickstart-es-elastic-user -o=jsonpath='{.data.elastic}' | base64 --decode<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltec8ef3a4df60e7a8/6a17fe9263baff3381741e76/bd74537f8c35c4e027c518913fdb0a0524621d56-624x31.png" alt="" /><p>19. <strong>Accede a Kibana</strong> desde tu navegador:</p><p>a. URL: https://&lt;EXTERNAL_IP&gt;:5601</p><p>b. Nombre de usuario:elastic</p><p>c. Contraseña:c44A295CaEt44D6xIzN6Zs5m (del paso anterior)</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7e8fbd1593bae329/6a17fe937b54f91d7c8b3b1d/a601112527d80721b292328ed8da58386d2837eb-463x503.png" alt="" /><p>20. Al acceder a Elastic Cloud desde tu navegador, verás la pantalla de bienvenida.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9ad7cd3196eb7dbe/6a17fe95b1e11336a579f4c5/f91e71fa961d215a8d886601d1a9fc5c452ce329-1999x1256.png" alt="" /><p>Si quieres cambiar las especificaciones del clúster de Elasticsearch, como cambiar o redimensionar nodos, puedes volver a aplicar el manifiesto YML con la nueva configuración:</p>cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: quickstart
spec:
  version: 9.0.0
  nodeSets:
    - name: default
      count: 2
      config:
        node.store.allow_mmap: false
      podTemplate:
        spec:
          containers:
            - name: elasticsearch
              resources:
                requests:
                  memory: 1.5Gi
                  cpu: 2
                limits:
                  memory: 1.5Gi
                  cpu: 2
EOF<p>En este ejemplo, vamos a agregar un nodo más y modificar la RAM y la CPU. Como puedes ver, ahora <code>kubectl get elasticsearch</code> muestra 2 nodos:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdfe6ff383e03814e/6a17fe974b055dd514432426/4b139a476b50933d45d99e09479112817964f76a-624x60.png" alt="" /><p>Lo mismo ocurre con Kibana:</p>cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
  name: quickstart
spec:
  version: 9.0.0
  http:
    service:
      spec:
        type: LoadBalancer
  count: 1
  elasticsearchRef:
    name: quickstart
  podTemplate:
    spec:
      containers:
        - name: kibana
          env:
            - name: NODE_OPTIONS
              value: "--max-old-space-size=1024"
          resources:
            requests:
              memory: 0.5Gi
              cpu: 0.5
            limits:
              memory: 1Gi
              cpu: 1
EOF<p>Podemos ajustar la CPU/RAM del contenedor y también el <a href="https://nodejs.org/">uso de Node.js </a>memoria (<a href="https://nodejs.org/api/cli.html#--max-old-space-sizesize-in-mib">máximo-tamaño de espacio antiguo</a>)</p><p>Ten en cuenta que <a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s/volume-claim-templates">las reclamaciones de volumen existentes no pueden reducir</a>. Tras aplicar la actualización, el operador realizará los cambios con un tiempo de interrupción mínimo.</p><p>Recuerda eliminar el clúster cuando termines de hacer pruebas para evitar costos innecesarios.</p>az aks delete --name myAKSAutomaticCluster --resource-group elastic-resource<h2>Conclusión</h2><p>Emplear Azure AKS Automatic con ECK proporciona una solución equilibrada para desplegar Elasticsearch y Kibana: reduce la complejidad operativa, garantiza escalado y actualizaciones automatizadas, y aprovecha la flexibilidad de Kubernetes. Este enfoque es ideal para equipos que buscan un proceso de despliegue fiable, repetible y manteniendo sin gestionar manualmente cada detalle de la infraestructura, lo que lo convierte en una opción práctica tanto para entornos de pruebas como de producción.</p><h2>Pasos siguientes</h2><p>Si quieres leer más sobre Kubernetes, puedes consultar la documentación oficial aquí:</p><ul><li><p><a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s">Nube elástica en Kubernetes | Documentos elásticos</a></p></li><li><p><a href="https://learn.microsoft.com/en-us/azure/aks/intro-aks-automatic">Introduction to Azure Kubernetes Service (AKS) Automatic (preview)</a></p></li><li><p><a href="https://azure.github.io/AKS/2024/05/22/aks-automatic">AKS Automatic - Blog de ingeniería de AKS</a></p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-azure-aks-automatic-deployment</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-azure-aks-automatic-deployment</guid>
    <category><![CDATA[Conceptos básicos]]></category>
    <dc:creator><![CDATA[Eduard Martin]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt58d08dac9d3586db/6a17fe983e9e45002eba16e7/4d821659a606e04390b09215e9a0d32eb01f0d1b-854x489.png" length="0" type="image/png"/>
    <pubDate>Fri, 14 Nov 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Configuración del fragmento recursivo para documentos estructurados en Elasticsearch]]></title>
    <description><![CDATA[Aprende a configurar el chunking recursivo en Elasticsearch con tamaño de bloque, grupos de separadores y listas de separadores personalizadas para una indexación óptima de documentos estructurados.]]></description>
    <content:encoded><![CDATA[<p>Desde la versión 8.16, los usuarios pudieron configurar la estrategia de fragmentación empleada al ingirir documentos largos en campos de texto semánticos. A partir de 9.1 / 8.19, introdujimos una nueva estrategia configurable de fragmentación recursiva que emplea una lista de expresiones regulares para fragmentar el documento. El objetivo del chunking es dividir un documento largo en secciones que encapsulen contenido relacionado. Nuestras estrategias actuales dividirán el texto en un detalle de palabras/oraciones, pero los documentos escritos en formatos estructurados (por ejemplo, Markdown) a menudo contienen contenido relacionado dentro de secciones definidas por algunas cadenas de separación (por ejemplo, cabeceras). Para este tipo de documentos, introducimos la estrategia de fragmentación recursiva para aprovechar el formato de documentos estructurados y crear mejores fragmentos.</p><h2>¿Qué es el chunking recursivo?</h2><p>El fragmento recursivo iterará a través de una lista de secciones proporcionadas que separan patrones para dividir progresivamente un documento en segmentos más pequeños hasta alcanzar el tamaño máximo deseado del fragmento.</p><h3>¿Cómo configuro el chunking recursivo?</h3><p>A continuación se presentan los valores configurables proporcionados por el usuario para el fragmento recursivo:</p><ul><li><p>(requerido) <code>max_chunk_size</code>: El número máximo de palabras en un bloque.</p></li><li><p>Cualquiera de:</p><ul><li><p><code>separators</code>: Una lista de patrones de cadenas regex que se usarán para dividir el documento en bloques.</p></li><li><p><code>separator_group</code>: Una cadena que se mapea a una lista predeterminada de separadores definida por Elastic para usar en tipos específicos de documentos. Actualmente, hay <code>markdown</code> y <code>plaintext</code> disponibles.</p></li></ul></li></ul><h3>¿Cómo funciona el chunking recursivo?</h3><p>El proceso de fragmentación recursiva dado un documento de entrada, una <code>max_chunk_size</code> (medida en palabras) y una lista de cadenas de separadores es el siguiente:</p><ol><li><p>Si el documento de entrada ya está dentro del tamaño máximo del bloque, devuelva un solo bloque que cubra toda la entrada.</p></li><li><p>Divide el texto en posibles fragmentos según la aparición del separador. Para cada segmento potencial:</p><ol><li><p>Si el chunk potencial está dentro del tamaño máximo del chunk, agrégalo a la lista de chunks para devolverlos al usuario.</p></li><li><p>De lo contrario, repite desde el paso 2, usando solo el texto del posible fragmento y dividiendo usando el siguiente separador de la lista. Si ya no quedan separadores por probar, recurre a fragmentos basados en frases.</p></li></ol></li></ol><h2>Ejemplos de configuración del chunking recursivo</h2><p>Además del tamaño del bloque, la configuración principal para el fragmento recursivo es seleccionar qué separadores deben usar para dividir tus documentos. Si no sabes por dónde empezar, Elasticsearch ofrece algunos grupos de separadores por defecto que se pueden usar en casos de uso comunes.</p><h3>Utilización de grupos separadores</h3><p>Para emplear un grupo separador, simplemente indica el nombre del grupo que quieres usar al configurar la configuración de fragmentos. Por ejemplo:</p>"chunking_settings": {
    "strategy": "recursive",
    "max_chunk_size": 25,
    "separator_group": "plaintext"
}<p>Esto te dará una estrategia de fragmentación recursiva que emplea la lista de separadores <code>["(?&lt;!\\n)\\n\\n(?!\\n)", "(?&lt;!\\n)\\n(?!\\n)")]</code>. Esto funciona bien para aplicaciones genéricas de texto plano, dividiendo en 2 caracteres de nueva línea, seguidos de 1 carácter de nueva línea.</p><p>También ofrecemos un grupo de separadores <code>markdown</code> que empleará la lista de separadores:</p>[
"\n# ",
       "\n## ",
       "\n### ",
       "\n#### ",
       "\n##### ",
       "\n###### ",
       "\n^(?!\\s*$).*\\n-{1,}\\n",
       "\n^(?!\\s*$).*\\n={1,}\\n"
]<p>Esta lista de separadores funcionará bien para casos generales de reducción de categorías, dividiendo en cada uno de los 6 niveles de encabezado y en los caracteres que rompen secciones.</p><p>Al crear un recurso (extremo de inferencia/campo de texto semántico), la lista de separadores correspondiente al grupo de separadores en ese momento se almacenará en tus configuraciones. Si el grupo separador se actualiza más adelante, no cambiará el comportamiento de los recursos ya creados.</p><h3>Empleando una lista de separadores personalizada</h3><p>Si uno de los grupos de separadores predefinidos no funciona para tu caso de uso, puedes definir una lista personalizada de separadores que se adapte a tus necesidades. Ten en cuenta que las expresiones regulares pueden proporcionar dentro de la lista de separadores. A continuación se muestra un ejemplo de configuración de fragmentación configurada con separadores personalizados:</p>"chunking_settings": {
    "strategy": "recursive",
    "max_chunk_size": 25,
    "separators": ["\n\n", "\n", "&lt;my-custom-separator&gt;"]
}<p>La estrategia de fragmentación anterior se dividirá en 2 caracteres de nueva línea, seguidos de 1 carácter de nueva línea y, por último, en una cadena <code>“&lt;my-custom-separator&gt;”</code>.</p><h2>Un ejemplo de fragmentación recursiva en acción</h2><p>Veamos un ejemplo de fragmentación recursiva en acción. Para este ejemplo, usaremos los siguientes ajustes de fragmentación con una lista personalizada de separadores que dividen un documento markdown usando los dos niveles superiores de cabecera:</p>"chunking_settings": {
    "strategy": "recursive",
    "max_chunk_size": 25,
    "separators": ["\n# ", "\n## "]
}<p>Veamos un documento sencillo de Markdown sin fragmentos:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdb5f41d1bd43ba50/6a17e831e9ea87c1d8a9c5f3/3a5507f4a1288065097231548e5b18e240508785-1302x1446.png" alt="Un documento Markdown sin fragmentos" /><p>Ahora usemos los ajustes de fragmentación definidos arriba para fragmentar el documento:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfffda162c7b9c87a/6a17e83296142aefa8eb1b0b/a3313c4c40ff39b8dbcdd7c4878c723f088e6c1a-1600x1187.png" alt="Fragmentación de un documento en Elasticsearch" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt96f65346a8e09e3a/6a17e834445de9157b4d015e/79a2921943191ea631df94c9d465818ec8d3e738-1600x1206.png" alt="División en segundo separador: fragmentación de un documento en Elasticsearch" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt28381c8f85aedf07/6a17e836ec0f89801e5a6640/459e695cce7540267422396b9a62ff4ad35f61db-1600x1260.png" alt="Fragmentos finales en un documento luego del fragmento basado en oraciones en Elasticsearch" /><p>Nota: La nueva línea al final de cada bloque (excepto el Fragmento 3) no está resaltada, pero sí se incluye dentro de los límites reales del bloque.</p><h3>¡Empieza hoy mismo con el chunking recursivo!</h3><p>Para más información sobre cómo emplear esta función, consulta la documentación sobre cómo configurar la configuración de fragmentos.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/recursive-chunking-structured-documents-elasticsearch</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/recursive-chunking-structured-documents-elasticsearch</guid>
    <category><![CDATA[Conceptos básicos]]></category>
    <category><![CDATA[Dentro de Elastic]]></category>
    <category><![CDATA[AI]]></category>
    <dc:creator><![CDATA[Daniel Rubinstein]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf442dc4941f37be7/6a17e838505ac3eaf8ad8b3d/591872e31880768ca927507654a621addc0d124d-1600x960.png" length="0" type="image/png"/>
    <pubDate>Tue, 11 Nov 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Introducción de la interfaz de reglas de consulta Elasticsearch en Kibana]]></title>
    <description><![CDATA[Aprende a usar la interfaz de Reglas de Consulta de Elasticsearch para agregar o excluir documentos de consultas de búsqueda usando conjuntos de reglas personalizables en Kibana, sin afectar al ranking orgánico.]]></description>
    <content:encoded><![CDATA[<p>La función de un motor de búsqueda es devolver resultados relevantes. Sin embargo, hay necesidades empresariales que van más allá de eso, como destacar las ventas, priorizar productos de temporada o mostrar artículos patrocinados, y los desarrolladores no siempre pueden hacer esto en la consulta de búsqueda.</p><p>Además, estos casos de uso suelen ser sensibles al tiempo, y pasar por las etapas típicas de desarrollo (crear una rama de código y luego esperar una nueva versión) es un proceso que consume mucho tiempo.</p><p>Entonces, ¿y si pudiéramos hacer todo este proceso solo con una llamada a la API, o mejor aún, con solo unos clics en Kibana?</p><h2>Interfaz de Reglas de Consulta</h2><p>Elasticsearch 8.10 introdujo Reglas de <a href="https://www.elastic.co/blog/introducing-query-rules-elasticsearch-8-10"><strong>Consulta</strong></a> y <a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/retrievers/rule-retriever"><strong>Retriever de Reglas</strong></a>. Estas son herramientas diseñadas para inyectar <a href="https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-pinned-query"><em>resultados fijados</em></a> en las consultas sin afectar la clasificación de los resultados orgánicos según reglas. Solo agregan lógica de negocio encima de los resultados de forma declarativa y sencilla.</p><p>Algunos casos de uso comunes para las Reglas de Consulta son:</p><ul><li><p><strong>Destacar anuncios u ofertas promocionadas</strong>: Mostrar artículos en oferta o patrocinados en la parte superior.</p></li><li><p><strong>Excluyendo por contexto o geolocalización</strong>: ocultar ciertos objetos cuando la normativa local no permite mostrarlos.</p></li><li><p><strong>Priorizar los resultados clave</strong>: Cerciorar de que las búsquedas populares o fijas estén siempre en la cima, independientemente del ranking orgánico.</p></li></ul><p>Para acceder a la interfaz e interactuar con estas herramientas, necesitas hacer clic en el menú lateral de Kibana e ir a <strong>Reglas de consulta</strong>, en <strong>Relevancia:</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltac12541cddd58e36/6a170853a29299941cd00fc2/242e33e89d1a07ffa0e76009c46b3a9236722741-458x1010.png" alt="Acceso a las reglas de consulta en Elasticsearch bajo relevancia" /><p>Cuando aparezca el menú de reglas de consulta, haz clic <strong>en Crear tu primer conjunto de reglas:</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcc28329c0f3c3aa9/6a17085547d49c67e22d893b/30b3a91bbbf243d314cf38298e01ca5cff784430-1600x945.png" alt="Crear tu primer conjunto de reglas de consulta en Elasticsearch" /><p>A continuación, tienes que nombrar tu conjunto de normas.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb37d271297a4f148/6a170856a29299782cd00fc6/26c5462f88678867776f933b5655ca0df0d72a16-708x446.png" alt="Nombrar tu conjunto de reglas de consulta en Elasticsearch" /><p>La forma para definir cada regla tiene tres componentes clave:</p><ul><li><p><strong>Criterios</strong>: Las condiciones que deben cumplir para que la norma se aplique. Por ejemplo, "cuando el campo query_string contiene el valor <em>Christmas</em>" o "cuando el campo del país es <em>CO."</em></p></li><li><p><strong>Acción</strong>: Esto es lo que quieres que ocurra cuando se cumplan las condiciones. Puede fijar (fijar un documento a los resultados superiores) o excluir (ocultar un documento).</p></li><li><p><strong>Metadatos</strong>: Estos son los campos que acompañan la consulta cuando se ejecuta. Pueden incluir la información del usuario (como ubicación o idioma), así como datos de búsqueda (query_string). Estos son los valores que emplean los criterios para decidir si aplicar o no una regla.</p></li></ul><h2>Ejemplo: objetos populares</h2><p>Imaginemos que tenemos un sitio de comercio electrónico con diferentes artículos. Al analizar las métricas, observamos que uno de los artículos más vendidos en la categoría de consolas es el "DualShock 4 Wireless Controller", especialmente cuando los usuarios buscan las palabras clave "PS4" o "PlayStation 4". Así que decidimos poner este producto encima de los resultados cada vez que un usuario busque esas palabras clave.</p><p>Primero, indexemos los documentos de cada elemento usando una solicitud Bulk API:</p>POST _bulk
{ "index": { "_index": "products", "_id": "1" } }
{ "id": "1", "name": "PlayStation 4 Slim 1TB", "category": "console", "brand": "Sony", "price": 1200 }
{ "index": { "_index": "products", "_id": "2" } }
{ "id": "2", "name": "DualShock 4 Wireless Controller", "category": "accessory", "brand": "Sony", "price": 250 }
{ "index": { "_index": "products", "_id": "3" } }
{ "id": "3", "name": "PlayStation 4 Camera", "category": "accessory", "brand": "Sony", "price": 200 }
{ "index": { "_index": "products", "_id": "4" } }
{ "id": "4", "name": "PlayStation 4 VR Headset", "category": "accessory", "brand": "Sony", "price": 900 }
{ "index": { "_index": "products", "_id": "5" } }
{ "id": "5", "name": "Charging Station for DualShock 4", "category": "accessory", "brand": "Sony", "price": 80 }<p>Si no intervenimos en la consulta, el elemento suele aparecer en cuarto lugar. Aquí está la pregunta:</p>GET products/_search
{
 "query": {
   "match": {
     "name": "PlayStation 4"
   }
 }
}<p>Y aquí están los resultados</p>{
 "took": 1,
 "timed_out": false,
 "_shards": {
   "total": 1,
   "successful": 1,
   "skipped": 0,
   "failed": 0
 },
 "hits": {
   "total": {
     "value": 5,
     "relation": "eq"
   },
   "max_score": 0.6973252,
   "hits": [
     {
       "_index": "products",
       "_id": "3",
       "_score": 0.6973252,
       "_source": {
         "id": "3",
         "name": "PlayStation 4 Camera",
         "category": "accessory",
         "brand": "Sony",
         "price": 200
       }
     },
     {
       "_index": "products",
       "_id": "1",
       "_score": 0.6260078,
       "_source": {
         "id": "1",
         "name": "PlayStation 4 Slim 1TB",
         "category": "console",
         "brand": "Sony",
         "price": 1200
       }
     },
     {
       "_index": "products",
       "_id": "4",
       "_score": 0.6260078,
       "_source": {
         "id": "4",
         "name": "PlayStation 4 VR Headset",
         "category": "accessory",
         "brand": "Sony",
         "price": 900
       }
     },
     {
       "_index": "products",
       "_id": "2",
       "_score": 0.08701137,
       "_source": {
         "id": "2",
         "name": "DualShock 4 Wireless Controller",
         "category": "accessory",
         "brand": "Sony",
         "price": 250
       }
     },
     {
       "_index": "products",
       "_id": "5",
       "_score": 0.07893815,
       "_source": {
         "id": "5",
         "name": "Charging Station for DualShock 4",
         "category": "accessory",
         "brand": "Sony",
         "price": 80
       }
     }
   ]
 }
}<p>Vamos a crear una regla de consulta para cambiar esto. Primero, vamos a agregarlo al reglamento de esta manera:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1576d4f4a2e60548/6a170858cdacbfccb07d298d/fdc42646fb3e76a09bca7d19047a76efe343f7a2-1600x650.png" alt="Cómo editar un conjunto de reglas de consulta en Elasticsearch" /><p>O <a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-query-rules-put-ruleset">solicitud API</a> equivalente:</p>PUT _query_rules/my-rules
{
  "rules": [
    {
      "rule_id": "rule-1232",
      "type": "pinned",
      "criteria": [
        {
          "type": "exact",
          "metadata": "query_string",
          "values": [
            "PS4",
            "PlayStation 4"
          ]
        }
      ],
      "actions": {
        "docs": [
          {
            "_index": "products",
            "_id": "2"
          }
        ]
      }
    }
  ]
}<p>Para usar el <strong>conjunto de reglas </strong>en nuestra consulta, debemos usar un tipo de regla de consulta. Este tipo de consulta se compone de dos partes principales:</p>GET /products/_search
{
 "retriever": {
   "rule": {
     "retriever": {
       "standard": {
         "query": {
           "match": { "name": "PlayStation 4" }
         }
       }
     },
     "match_criteria": {
       "query_string": "PlayStation 4"
     },
     "ruleset_ids": ["my-rules"]
   }
 }
}<ul><li><p><strong>match_criteria</strong>: Estos son los metadatos que se emplean para comparar con la consulta del usuario. En este ejemplo, el conjunto de reglas se activa cuando el campo query_string tiene el valor "PlayStation 4."</p></li><li><p><strong>Consulta</strong>: La consulta real que se usará para buscar y obtener los resultados orgánicos.</p></li></ul><p>De este modo, primero ejecutas la consulta orgánica y luego Elasticsearch aplica las reglas de tu conjunto de reglas:</p>{
 "took": 17,
 "timed_out": false,
 "_shards": {
   "total": 1,
   "successful": 1,
   "skipped": 0,
   "failed": 0
 },
 "hits": {
   "total": {
     "value": 5,
     "relation": "eq"
   },
   "max_score": 1.7014122e+38,
   "hits": [
     {
       "_index": "products",
       "_id": "2",
       "_score": 1.7014122e+38,
       "_source": {
         "id": "2",
         "name": "DualShock 4 Wireless Controller",
         "category": "accessory",
         "brand": "Sony",
         "price": 250
       }
     },
     {
       "_index": "products",
       "_id": "3",
       "_score": 0.6973252,
       "_source": {
         "id": "3",
         "name": "PlayStation 4 Camera",
         "category": "accessory",
         "brand": "Sony",
         "price": 200
       }
     },
     {
       "_index": "products",
       "_id": "1",
       "_score": 0.6260078,
       "_source": {
         "id": "1",
         "name": "PlayStation 4 Slim 1TB",
         "category": "console",
         "brand": "Sony",
         "price": 1200
       }
     },
     {
       "_index": "products",
       "_id": "4",
       "_score": 0.6260078,
       "_source": {
         "id": "4",
         "name": "PlayStation 4 VR Headset",
         "category": "accessory",
         "brand": "Sony",
         "price": 900
       }
     },
     {
       "_index": "products",
       "_id": "5",
       "_score": 0.07893815,
       "_source": {
         "id": "5",
         "name": "Charging Station for DualShock 4",
         "category": "accessory",
         "brand": "Sony",
         "price": 80
       }
     }
   ]
 }
}<h2>Ejemplo: metadatos basados en el usuario</h2><p>Otra aplicación interesante de las Reglas de Consulta es usar metadatos para mostrar documentos específicos basar en información contextual del usuario o del sitio web.</p><p>Por ejemplo, imaginemos que queremos destacar artículos o ventas personalizadas basándonos en el nivel de fidelidad del usuario, representado como un valor numérico.</p><p>Podemos hacerlo ingiriendo estos metadatos directamente en la consulta para que las reglas se activen cuando dicho valor cumple ciertos criterios.</p><p>Primero, indexaremos un documento que solo los usuarios con un alto nivel de lealtad puedan ver:</p>POST _bulk
{ "index": { "_index": "products", "_id": "6" } }
{ "id": "6", "name": "PlayStation Plus Deluxe Card - 12 months", "category": "membership", "brand": "Sony", "price": 300 }<p>Ahora, creemos una nueva regla dentro del mismo conjunto de reglas para que cuando el loyalty_level sea igual o superior a 80, el elemento aparezca encima de los resultados.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt158578005df8c76d/6a17085aab7f086dc0db9de3/58de12dff93305440608f51465462fcc68653a08-1421x496.png" alt="Cómo editar un conjunto de reglas de consulta en Elasticsearch" /><p>Almacena la regla y el reglamento.</p><p>Aquí está la solicitud REST equivalente:</p>PUT _query_rules/my-rules
{
  "rules": [
    {
      "rule_id": "pin-premiun-user",
      "type": "pinned",
      "criteria": [
        {
          "type": "gte",
          "metadata": "loyalty_level",
          "values": [
            80
          ]
        }
      ],
      "actions": {
        "docs": [
          {
            "_index": "products",
            "_id": "6"
          }
        ]
      }
    }
  ]
}<p>Ahora, al ejecutar una consulta, necesitamos incluir el nuevo <strong>parámetro loyalty_level </strong>en los metadatos. Si se cumple la condición de la regla, el nuevo documento aparecerá encima de los resultados.</p><p>Por ejemplo, al enviar una consulta donde el loyalty_level es 80:</p>POST /products/_search
{
  "retriever": {
    "rule": {
      "retriever": {
        "standard": {
          "query": {
            "match": {
              "name": "PlayStation"
            }
          }
        }
      },
      "match_criteria": {
        "query_string": "PlayStation",
        "loyalty_level": 80
      },
      "ruleset_ids": ["my-rules"]
    }
  }
}<p>Veremos el documento de lealtad encima de los resultados:</p>{
  "took": 31,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 4,
      "relation": "eq"
    },
    "max_score": 1.7014122e+38,
    "hits": [
      {
        "_index": "products",
        "_id": "6",
        "_score": 1.7014122e+38,
        "_source": {
          "id": "6",
          "name": "PlayStation Plus Deluxe Card - 12 months",
          "category": "membership",
          "brand": "Sony",
          "price": 300
        }
      },
      {
        "_index": "products",
        "_id": "3",
        "_score": 0.5054567,
        "_source": {
          "id": "3",
          "name": "PlayStation 4 Camera",
          "category": "accessory",
          "brand": "Sony",
          "price": 200
        }
      },
      {
        "_index": "products",
        "_id": "1",
        "_score": 0.45618832,
        "_source": {
          "id": "1",
          "name": "PlayStation 4 Slim 1TB",
          "category": "console",
          "brand": "Sony",
          "price": 1200
        }
      },
      {
        "_index": "products",
        "_id": "4",
        "_score": 0.45618832,
        "_source": {
          "id": "4",
          "name": "PlayStation 4 VR Headset",
          "category": "accessory",
          "brand": "Sony",
          "price": 900
        }
      }
    ]
  }
}<p>En el caso siguiente, dado que el nivel de lealtad es 70, la regla no se cumple y el objeto no debería aparecer arriba:</p>POST /products/_search
{
  "retriever": {
    "rule": {
      "retriever": {
        "standard": {
          "query": {
            "match": {
              "name": "PlayStation"
            }
          }
        }
      },
      "match_criteria": {
        "query_string": "PlayStation",
        "loyalty_level": 70
      },
      "ruleset_ids": ["my-rules"]
    }
  }
}<p>Aquí están los resultados:</p>{
  "took": 7,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 4,
      "relation": "eq"
    },
    "max_score": 0.5054567,
    "hits": [
      {
        "_index": "products",
        "_id": "3",
        "_score": 0.5054567,
        "_source": {
          "id": "3",
          "name": "PlayStation 4 Camera",
          "category": "accessory",
          "brand": "Sony",
          "price": 200
        }
      },
      {
        "_index": "products",
        "_id": "1",
        "_score": 0.45618832,
        "_source": {
          "id": "1",
          "name": "PlayStation 4 Slim 1TB",
          "category": "console",
          "brand": "Sony",
          "price": 1200
        }
      },
      {
        "_index": "products",
        "_id": "4",
        "_score": 0.45618832,
        "_source": {
          "id": "4",
          "name": "PlayStation 4 VR Headset",
          "category": "accessory",
          "brand": "Sony",
          "price": 900
        }
      },
      {
        "_index": "products",
        "_id": "6",
        "_score": 0.3817649,
        "_source": {
          "id": "6",
          "name": "PlayStation Plus Deluxe Card - 12 months",
          "category": "membership",
          "brand": "Sony",
          "price": 300
        }
      }
    ]
  }
}<h2>Ejemplo: exclusión inmediata</h2><p>Supongamos que nuestro <strong>mando inalámbrico DualShock 4 (ID 2)</strong> está temporalmente indisponible y no puede vender. Así que, en lugar de eliminar manualmente el documento o esperar a que algún proceso de datos se active, el equipo de negocio decide eliminarlo de los resultados de búsqueda mientras tanto.</p><p>Usaremos un proceso similar al que acabamos de aplicar a los objetos populares, pero esta vez en lugar de seleccionar <em>Fijado</em>, elegiremos <em>Excluir</em>. Esta regla funciona como una especie de lista negra. Cambia los criterios a <strong>Siempre</strong> para que la exclusión funcione cada vez que se ejecute la consulta.</p><p>La regla debería ser así:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt38564c0b7f4a6ee2/6a17085c1949f78692e7a989/f10971e4f1bc9520105111adfa3a476581a27130-1600x623.png" alt="Ejemplo de un conjunto de reglas de exclusión inmediata en Elasticsearch" /><p>Almacena la regla y el conjunto de reglas para aplicar los cambios. Aquí está la solicitud REST equivalente:</p>PUT _query_rules/my-rules
{
  "rules": [
    {
      "rule_id": "rule-6358",
      "type": "pinned",
      "criteria": [
        {
          "type": "always"
        }
      ],
      "actions": {
        "docs": [
          {
            "_index": "products",
            "_id": "2"
          }
        ]
      }
    }
  ]
}<p>Ahora, cuando ejecutamos la consulta de nuevo, verás que el elemento ya no aparece en los resultados, aunque la regla anterior sea fijarlo. Esto se debe a <strong>que las exclusiones tienen prioridad sobre los resultados de fijación</strong>.</p>{
 "took": 6,
 "timed_out": false,
 "_shards": {
   "total": 1,
   "successful": 1,
   "skipped": 0,
   "failed": 0
 },
 "hits": {
   "total": {
     "value": 4,
     "relation": "eq"
   },
   "max_score": 2.205655,
   "hits": [
     {
       "_index": "products",
       "_id": "3",
       "_score": 2.205655,
       "_source": {
         "id": "3",
         "name": "PlayStation 4 Camera",
         "category": "accessory",
         "brand": "Sony",
         "price": 200
       }
     },
     {
       "_index": "products",
       "_id": "1",
       "_score": 1.9738505,
       "_source": {
         "id": "1",
         "name": "PlayStation 4 Slim 1TB",
         "category": "console",
         "brand": "Sony",
         "price": 1200
       }
     },
     {
       "_index": "products",
       "_id": "4",
       "_score": 1.9738505,
       "_source": {
         "id": "4",
         "name": "PlayStation 4 VR Headset",
         "category": "accessory",
         "brand": "Sony",
         "price": 900
       }
     },
     {
       "_index": "products",
       "_id": "5",
       "_score": 0.69247496,
       "_source": {
         "id": "5",
         "name": "Charging Station for DualShock 4",
         "category": "accessory",
         "brand": "Sony",
         "price": 80
       }
     }
   ]
 }
}<h2>Conclusión</h2><p><strong>Las Reglas de Consulta</strong> facilitan mucho ajustar la relevancia sin ningún cambio en el código. La nueva interfaz <strong>Kibana</strong> tepermite realizar estos cambios en cuestión de segundos, dándote a ti y a tu equipo empresarial más control sobre los resultados de búsqueda.</p><p>Más allá del comercio electrónico, las Reglas de Consulta pueden impulsar muchos otros escenarios: destacar guías de resolución de problemas en portales de soporte, mostrar documentos internos clave en bases de conocimiento, promover noticias de última hora en sitios de noticias o filtrar ofertas de empleo o contenido caducado. Incluso pueden hacer cumplir normas de cumplimiento, como ocultar material restringido por rol de usuario o región.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-query-rules-ui-introduction</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-query-rules-ui-introduction</guid>
    <category><![CDATA[Conceptos básicos]]></category>
    <category><![CDATA[Experiencia del desarrollador]]></category>
    <dc:creator><![CDATA[Jhon Guzmán]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt565ed0eb407e098d/6a17085d8b73cb363d189fb1/1fb10bd31c509cc9b9bb4f71f49970f140e6c36f-1600x945.png" length="0" type="image/png"/>
    <pubDate>Fri, 07 Nov 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Cómo desplegar Elasticsearch en AWS Marketplace]]></title>
    <description><![CDATA[Aprende a configurar y ejecutar Elasticsearch utilizando Elastic Cloud Service en AWS Marketplace con esta guía paso a paso.]]></description>
    <content:encoded><![CDATA[<p>En este artículo, vamos a aprender cómo desplegar Elasticsearch en AWS usando las ofertas del Marketplace.</p><p>Vamos a usar Elastic Cloud Service en AWS, que es el servicio oficial gestionado de Elasticsearch que simplifica el despliegue y la orquestación de todos los componentes de Elastic Stack a través de la infraestructura nativa de AWS.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6c1107b202d48147/6a16f67d92262a04071cc077/f15814051b53b50bec38f9a9f515a1e6dc08a56c-884x440.png" alt="" /><p>Si quieres aprender a instalar y configurar Elasticsearch en AWS EC2, echa un vistazo a <a href="https://www.elastic.co/search-labs/blog/elasticsearch-on-aws-ec2-deployment-guide">este blog</a>.
</p><h2>¿Qué es AWS Marketplace?</h2><p><a href="https://aws.amazon.com/marketplace"><strong>Elastic en AWS Marketplace</strong></a> ofrece una experiencia de búsqueda y análisis totalmente gestionada, en la que AWS se encarga de la provisión de infraestructura, seguridad y el escalado, mientras los desarrolladores se centran en crear aplicaciones de búsqueda. Esto permite a los equipos desplegar clústeres de Elasticsearch de nivel empresarial en cuestión de minutos con integraciones de AWS integradas.</p><h2>¿Cuándo usar Elastic en AWS Marketplace?</h2><p>Elastic en AWS Marketplace es más adecuado para organizaciones con una infraestructura AWS existente que buscan desplegar Elasticsearch con servicios gestionados, seguridad integrada e integraciones fluidas de AWS sin sobrecarga operativa.</p><h2>Cómo configurar Elastic Cloud en AWS Marketplace</h2><h3>Paso 1: Accede a AWS Marketplace</h3><p>1. Inicia sesión en <a href="https://console.aws.com/">AWS</a></p><ul><li><p>En la barra de búsqueda, busca AWS Marketplace</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd7b4a64a97929ca0/6a16f67e60084b1ee43c4333/fc9928f79482c2c01e33978c88d390a2bfa2a3bf-1600x340.png" alt="" /><p>2. En el panel de navegación izquierdo, haz clic en <strong>Descubrir productos</strong>, luego haz una búsqueda de Elasticsearch.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta3efc233beb103ab/6a16f680b0367d681572babd/ca4232271cb13ebfe33de406ecaec085033ec8a0-1454x760.png" alt="" /><p>3. Haz clic en <strong>Elastic Cloud (Elasticsearch Service)</strong>.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd7fe524f5d0cc84e/6a16f682cdacbfabdf7d27c4/e59aa276e55532f2ac3461d0ca983af4d41ad7a6-1600x611.png" alt="" /><h3>Paso 2: Suscríbete al servicio</h3><p>1. Selecciona <strong>opciones de compra</strong> o haz clic en <strong>Pruébalo gratis</strong></p><p>2. Revisa <strong>Detalles de precios</strong>, <strong>Términos y condiciones</strong> y <strong>Detalles de compra</strong></p><p>3. Haz clic en el botón <strong>Suscribirse</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt027c8adb6bfa2b73/6a16f683a292995855d00de4/1c30d12b6b1061e76771d518011e522285f939f1-1600x290.png" alt="" /><p>4. Ahora hay que configurar la cuenta de Elastic. Sigue los pasos de AWS</p><p>a. Haz clic en el botón Habilitar integración.</p><p>b. Haz clic en el botón Iniciar sesión o crear una cuenta de proveedor</p><p>c. Haz clic en el botón Lanzar plantilla</p><p>d. Haz clic en el botón Iniciar software</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4d290ceb4c00c3ca/6a16f685839dfa35f6dcfc9b/879d9f0f01406e1955e1b38a2f6f2192ef040344-852x722.png" alt="" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt20832a47a3a5ce7b/6a16f68767045b0c8b45bf92/fc59be78cf776aa12867f40810598419576cbd39-1600x1143.png" alt="" /><h3>Paso 3. Configura tu cuenta nueva en Elastic</h3><p>1. Crea tu cuenta de Elastic</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2a47e1e23a0be123/6a16f68875879e400ffe15c0/5efeaf0737062a55470b17b67651f220e12183f2-986x905.png" alt="" /><p>2. Valida tu dirección de correo electrónico</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltaad961a0644018b5/6a16f68a0811ae0734e9feb6/e0cfaac278614e317ce278935040bfa5a58edd13-853x894.png" alt="" /><p>3. Introduce tu nombre e información de la empresa</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt52f4a502993fa5d4/6a16f68b2b835fb4b9f4afc4/d5658fe66c3b1bcced73e822eae006846f0ddd9e-997x903.png" alt="" /><p>4. Completa una rápida encuesta de Elastic</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt375dca1904b2f0c1/6a16f68dcdacbf4f8d7d27c8/a3f53c00dadfd22f7d739a920c87d5f387182833-892x805.png" alt="" /><p>5. Selecciona la región en la que quieres hospedar Elastic Cloud. De forma predeterminada, se seleccionará tu región real de AWS</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0c23f8b8b63af517/6a16f68fb0367d6a6072bac1/c1dcdf3bf91c305821daaa25a60aa03be6454c1c-1207x1032.png" alt="" /><p>6. Espera a que Elastic se despliegue</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd88a26701fb26db5/6a16f69075879ef0d8fe15cc/50903e57ebea7cc47bdfabf4750b4ba2a7a91148-1370x1266.png" alt="" /><p>7. Tu despliegue está conectado a tu suscripción de AWS Marketplace</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt822e8acb553ffac4/6a16f69275879ed57ffe15d0/3bb731e2d5de5053ccecb77e45dbdbcdaf294dba-1600x1288.png" alt="" /><h2>Cancelar tu suscripción</h2><p>Para cancelar tu suscripción</p><p>1. Ve a la <a href="https://console.aws.com/">consola de AWS</a></p><p>Haz una búsqueda de AWS Marketplace en la barra de búsqueda. Haz clic en <strong>AWS Marketplace</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7a19e162d4cb818a/6a16f694839dfa21a6dcfc9f/aeed3d1e67b4cef91934de257a6fd6daa9737a12-1600x554.png" alt="" /><p>2. Haz clic en <strong>suscripción a Elastic Cloud</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta189d9ff9b518243/6a16f695a292991b60d00de8/04e6cc41850226df223dbe2d1b0e4b45265f6c39-1600x564.png" alt="" /><p>3. Haz clic en el botón <strong>Actions</strong>, luego haz clic en <strong>Cancelar suscripción</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt40fc41f3911b8b66/6a16f6971949f70896e7a7a9/e33d334ea6541c637a223de3ebd6209def75a6d3-1600x1039.png" alt="" /><p>4. Confirma la cancelación, luego haz clic en <strong>Sí </strong>y en el botón Cancelar<strong> suscripción</strong>.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3eb1839197854313/6a16f699ab7f08469fdb9c31/b73b3187168adc7aefdd46f95be33c1bce3da1e4-1103x698.png" alt="" /><p>5. Aparecerá un mensaje de confirmación en la parte superior de la página</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt513bdb916a3bff8e/6a16f69a1949f74c5de7a7ad/c5ba66a23d535e866a8b458e5aca82c5f0b93037-1600x639.png" alt="" /><h2>Pasos siguientes</h2><p>Comienza tu experiencia con Elastic Cloud con una prueba gratuita de 7 días que incluye un único despliegue y tres proyectos<a href="https://aws.amazon.com/marketplace/pp/prodview-voru33wi6xs7k"> Elastic Cloud (Elasticsearch Service)</a>. Simplemente inicia sesión en tu cuenta de AWS y haz clic en "Ver opciones de compra" para empezar a usar la Plataforma de búsqueda de IA de Elastic inmediatamente en Elastic<a href="https://aws.amazon.com/marketplace/pp/prodview-voru33wi6xs7k"> Cloud (Elasticsearch Service)</a>. La prueba proporciona acceso completo a soluciones de búsqueda, seguridad y observabilidad sin ninguna carga de gestión de infraestructura.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/aws-elasticsearch-service-set-up</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/aws-elasticsearch-service-set-up</guid>
    <category><![CDATA[Conceptos básicos]]></category>
    <dc:creator><![CDATA[Eduard Martin]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcbf8a044704b64d5/6a16f69ccf4f25d524b2cf3f/a80776d2ef85db26f850d932339fac2d26b90278-1086x620.png" length="0" type="image/png"/>
    <pubDate>Fri, 03 Oct 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Fragmentos y réplicas de Elasticsearch: Una guía práctica]]></title>
    <description><![CDATA[Domina los conceptos de fragmentos y réplicas de Elasticsearch y aprende a optimizarlos.]]></description>
    <content:encoded><![CDATA[<p>Elasticsearch potencia Lucene construyendo un sistema distribuido sobre él, que aborda los problemas de escalabilidad y tolerancia a fallos. También expone una API REST basada en JSON, lo que facilita mucho la interoperabilidad con otros sistemas.</p><p>Sistemas distribuidos como Elasticsearch pueden ser muy complejos, con muchos factores que pueden afectar su rendimiento y estabilidad. <strong>Los fragmentos</strong> son uno de los conceptos más fundamentales en Elasticsearch, y entender cómo funcionan te permitirá gestionar eficazmente un clúster de Elasticsearch.</p><p>Este artículo explica qué son los shards primarios y réplica, su impacto en un clúster de Elasticsearch y qué herramientas existen para ajustarlos a diferentes demandas.</p><h2>Entendiendo fragmentos</h2><p>Los datos en un índice de Elasticsearch pueden crecer a proporciones enormes. Para mantenerlo manejable, cada dato se almacena en un índice, y los índices son un índice <strong>dividido en varios fragmentos</strong>. Cada fragmento de Elasticsearch es un índice de Lucene Apache, donde cada índice individual de Lucene contiene un subconjunto de los documentos del índice de Elasticsearch. Dividir los índices de esta manera mantiene el uso de recursos bajo control. Un índice de Lucena apache tiene un límite de 2.147.483.519 (2³¹ - 129) documentos.</p><p>A veces, es necesario mover índices entre nodos para fines de reequilibrio. Dado que este proceso puede requerir tanto tiempo como recursos, los índices no deberían crecer demasiado, lo que ayuda a mantener el tiempo de recuperación manejable. Además, dado que los índices están compuestos por segmentos de Lucene que deben fusionar constantemente, es importante que los segmentos no se hagan demasiado grandes. Por estas razones, Elasticsearch divide los datos del índice en fragmentos más pequeños y manejables, <strong>llamados fragmentos primarios</strong>, que pueden distribuir más fácilmente entre varias máquinas. <strong>Los fragmentos réplica</strong> son simplemente una copia exacta de un fragmento primario correspondiente y repasaremos su función más adelante en este artículo.</p><p>Tener el número adecuado de fragmentos es importante para el rendimiento. Por tanto, es prudente planear con antelación. Cuando las consultas se ejecutan en diferentes fragmentos en paralelo, se ejecutan más rápido que un índice compuesto por un solo fragmento, pero solo si cada fragmento está ubicado en un nodo diferente y hay suficientes nodos en el clúster. Sin embargo, al mismo tiempo, los fragmentos consumen memoria y espacio en disco, tanto en términos de datos indexados como de metadatos de clúster. Tener demasiados fragmentos (también conocido como sobrefragmentación) puede ralentizar consultas, solicitudes de indexación y operaciones de gestión, por lo que mantener el equilibrio adecuado es fundamental.</p><p>El número de fragmentos primarios se define en el momento de la creación <strong>del índice para esa instancia específica del índice</strong>. Si necesitas un número diferente de fragmentos primarios más adelante, puedes usar las<strong> APIs de redimensionamiento</strong>: <a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-split">split</a> (más shards primarios), <a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-shrink">shrink</a> (menos shards primarios) o <a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-clone">clone</a> (el mismo número de shards primarios con nuevos ajustes para réplicas). Estas operaciones copian los segmentos de Lucene y <strong>evitan una reindexación completa de todos los documentos</strong>. Al crear un índice, puedes establecer el número de fragmentos primarios y réplica como ajustes del índice:</p>PUT /sensor
{
   "settings" : {
       "index" : {
           "number_of_shards" : 6,
           "number_of_replicas" : 2
       }
   }
}<p>(Si no especificas el número de fragmentos o réplicas, el valor por defecto de ambos es 1, según Elasticsearch 7.0). El número ideal de fragmentos debe determinar en función de la cantidad de datos en un índice. Generalmente, <a href="https://www.elastic.co/docs/deploy-manage/production-guidance/optimize-performance/size-shards">un shard óptimo debe contener entre 10 y 50GB de datos</a>, con menos de 200 millones de documentos por shard. Por ejemplo, si esperas acumular alrededor de 300GB de registros de aplicaciones en un día, tener alrededor de 10 fragmentos en ese índice sería razonable, siempre que tengas suficientes nodos para alojarlos.</p><p>Durante su vida, los fragmentos pueden pasar por varios estados, entre ellos:</p><ul><li><p><strong>Inicializar:</strong> Un estado inicial antes de que se pueda usar el fragmento.</p></li><li><p><strong>Comenzó:</strong> Un estado en el que el fragmento está activo y puede recibir solicitudes.</p></li><li><p><strong>Reubicación:</strong> Un estado que ocurre cuando los fragmentos están en proceso de mover a otro nodo. Esto puede ser necesario bajo ciertas condiciones, por ejemplo, cuando el nodo en el que están se está quedando sin espacio en disco.</p></li><li><p><strong>No asignado:</strong> El estado de un fragmento que no fue asignado. Se proporciona una razón cuando esto ocurre, por ejemplo, si el nodo que aloja el fragmento ya no está en el clúster <em>(NODE_LEFT)</em> o debido a la restauración en un índice cerrado <em>(EXISTING_INDEX_RESTORED).</em></p></li></ul><p>Para ver todos los fragmentos, sus estados y otros metadatos, puedes usar la siguiente solicitud:</p>GET _cat/shards<p>Para ver fragmentos de un índice específico, puedes agregar el nombre del índice a la URL, por ejemplo, sensor:</p>GET _cat/shards/sensor<p>Este comando produce una salida, como en el siguiente ejemplo. Por defecto, las columnas que aparecen incluyen el nombre del índice, el nombre (es decir, número) del fragmento, si es un fragmento principal o una réplica, su estado, el número de documentos, el tamaño en disco, así como la dirección IP y el ID del nodo donde se encuentra el fragmento.</p>sensor 5 p STARTED    0  283b 127.0.0.1 ziap
sensor 5 r UNASSIGNED                  
sensor 2 p STARTED    1 3.7kb 127.0.0.1 ziap
sensor 2 r UNASSIGNED                  
sensor 3 p STARTED    3 7.2kb 127.0.0.1 ziap
sensor 3 r UNASSIGNED                  
sensor 1 p STARTED    1 3.7kb 127.0.0.1 ziap
sensor 1 r UNASSIGNED                  
sensor 4 p STARTED    2 3.8kb 127.0.0.1 ziap
sensor 4 r UNASSIGNED                  
sensor 0 p STARTED    0  283b 127.0.0.1 ziap
sensor 0 r UNASSIGNED<h2>Comprensión de réplicas</h2><p>Aunque cada fragmento contiene una única copia de los datos, un índice puede contener varias copias del fragmento. Por tanto, existen dos tipos de fragmentos: el <strong>fragmento principal</strong> y una copia, o <strong>réplica</strong>. Cada réplica de un fragmento primario siempre se encuentra en un nodo diferente, lo que garantiza una alta disponibilidad de tus datos en caso de fallo de un nodo. Además de la redundancia y su papel en la prevención de la pérdida de datos y el tiempo de inactividad, las réplicas también pueden ayudar a mejorar el rendimiento de búsqueda al permitir que las consultas se procesen en paralelo con el shard primario y, por tanto, más rápido.</p><p>Existen diferencias importantes en el comportamiento de los fragmentos primarios y réplica. Aunque ambos son capaces de procesar consultas, las solicitudes de indexación (es decir, Agregar datos al índice) debe pasar primero por los fragmentos primarios antes de poder replicar en los fragmentos réplica. Como se indicó antes, si un fragmento primario deja de estar disponible—por ejemplo, debido a una desconexión de nodo o fallo de hardware—se promueve una réplica para asumir su función.</p><p>Aunque las réplicas pueden ayudar en caso de fallo de un nodo, es importante no tener demasiadas porque consumen memoria, espacio en disco y potencia de cálculo al indexar. Otra diferencia entre los fragmentos primarios y las réplicas es que, aunque el número de fragmentos primarios no puede cambiar una vez creado el índice, el número de réplicas puede modificar dinámicamente en cualquier momento actualizando la configuración del índice.</p><p>Otro factor a considerar con las réplicas es el número de nodos disponibles. Las réplicas siempre se colocan en nodos diferentes del fragmento primario, ya que dos copias de los mismos datos en el mismo nodo no ofrecerían protección si el nodo fallara. Como resultado, para que un sistema soporte <em>n</em> réplicas, debe haber al <em>menos n + 1</em> nodos en el clúster. Por ejemplo, si hay dos nodos en un clúster y un índice está configurado con seis réplicas, solo se asignará una réplica. Por otro lado, un sistema con siete nodos es perfectamente capaz de manejar un fragmento principal y seis réplicas.</p><h2>Optimización de fragmentos y réplicas</h2><p>Incluso después de que se creó un índice con el equilibrio adecuado entre fragmentos primarios y réplica, estos deben ser monitorizados, ya que la dinámica alrededor de un índice cambia con el tiempo. Por ejemplo, al tratar con datos de seriales temporales, los índices con datos recientes suelen estar más activos que los más antiguos. Sin ajustar estos índices, todos consumirían la misma cantidad de recursos, a pesar de sus requisitos muy diferentes.</p><p>La API de índices de rollover puede usar para separar índices más nuevos y antiguos. Se puede configurar para crear automáticamente un nuevo índice una vez alcanzado cierto umbral—el tamaño del índice en el disco, el número de documentos o la antigüedad. Esta API también es útil para mantener bajo control el tamaño de los fragmentos. Dado que el número de fragmentos no puede modificar fácilmente tras la creación del índice, los fragmentos seguirán acumulando datos si no se cumplen las condiciones de rollover. Para índices antiguos que solo requieren acceso poco frecuente, reducir y forzar la fusión de un índice son dos formas diferentes de reducir su huella de memoria y disco. La primera reduce el número de fragmentos en un índice, mientras que la segunda reduce el número de segmentos Lucene y libera espacio empleado por documentos que fueron eliminados.</p><h2>Fragmentos primarios y réplica como base de Elasticsearch</h2><p>Elasticsearch construyó una estable reputación como plataforma distribuida de almacenamiento, búsqueda y análisis para enormes volúmenes de datos. Sin embargo, al operar a tal escala, inevitablemente surgen desafíos. Por eso entender cómo funcionan los fragmentos primarios y réplica es tan importante y fundamental para Elasticsearch, ya que esto puede ayudar a optimizar la fiabilidad y el rendimiento de la plataforma.</p><p>Saber cómo funcionan y cómo optimizarlos es fundamental para lograr un clúster de Elasticsearch más robusto y eficiente. Si experimentas respuestas lentas o cortes de información con regularidad, este conocimiento puede ser la clave para superar estos obstáculos.</p><p>Sigue la documentación oficial de Elasticsearch para saber más sobre <a href="https://www.elastic.co/docs/deploy-manage/distributed-architecture/clusters-nodes-shards">clústeres, nodos y fragmentos</a>, <a href="https://www.elastic.co/docs/deploy-manage/production-guidance/optimize-performance/size-shards">cómo dimensionar tus fragmentos</a>, <a href="https://www.elastic.co/docs/deploy-manage/distributed-architecture/shard-allocation-relocation-recovery">asignación y recuperación de fragmentos</a>.</p><p>Este tema también está disponible como curso introductorio en el <a href="https://youtu.be/sAySPSyL2qE">canal de YouTube de Elastic Community.</a></p><p>Por último, pero no menos importante: si no quieres preocuparte por nodos, fragmentos o réplicas, puedes probar <a href="https://www.elastic.co/docs/deploy-manage/deploy/elastic-cloud/serverless">Elastic Cloud Serverless</a>. Esta oferta de Elastic Cloud está completamente gestionada por Elastic y automatizada para escalar con tu carga de trabajo. Una prueba gratis puede ayudarte a familiarizarte con otros beneficios del enfoque sin servidor.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-shards-and-replicas-guide</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-shards-and-replicas-guide</guid>
    <category><![CDATA[Conceptos básicos]]></category>
    <dc:creator><![CDATA[Piotr Przybyl]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt71dd92d939d383a2/6a17e9d53e03d769c44f2cc7/7775c44f01f2516c4ff4cce6d6bbe9e7b2c38908-720x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Thu, 14 Aug 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Revelando patrones únicos: Guía para la agregación de términos significativos en Elasticsearch]]></title>
    <description><![CDATA[Aprende a emplear la agregación de términos significativos para descubrir información en tus datos.]]></description>
    <content:encoded><![CDATA[<p>En Elasticsearch, una <a href="https://www.elastic.co/docs/reference/aggregations/search-aggregations-bucket-significantterms-aggregation">agregación significativa de términos</a> va más allá de los <a href="https://www.elastic.co/docs/reference/aggregations/search-aggregations-bucket-terms-aggregation">términos más comunes</a> para encontrar valores estadísticamente inusuales en un conjunto de datos. Esto nos permite descubrir ideas valiosas y patrones no evidentes. Una agregación significativa de términos proporciona una respuesta con dos parámetros útiles:</p><ul><li><p><strong>bg_count (recuento de fondo): </strong>Número de documentos encontrados en el conjunto de datos principal</p></li><li><p><strong>doc_count:</strong> Número de documentos encontrados en el conjunto de datos resultante</p></li></ul><p>Por ejemplo, en un conjunto de datos de ventas de teléfonos, podemos buscar términos significativos en las ventas del iPhone 16 como este:</p>GET phone_sales_analysis/_search
{
 "size": 0,
 "query": {
   "term": {
     "phone_model": {
       "value": "iPhone 16"
     }
   }
 },
 "aggs": {
   "significant_cities": {
     "significant_terms": {
       "field": "city_region",
       "size": 1
     }
   }
 }
}<p>Luego, la respuesta nos da:</p>{
 "aggregations": {
   "significant_cities": {
     "doc_count": 122,
     "bg_count": 424,
     "buckets": [
       {
         "key": "Houston",
         "doc_count": 12,
         "score": 0.1946481360617346,
         "bg_count": 14
       }

     ]
   }
 }
}<p>Houston no está entre las 10 principales ciudades de todo el conjunto de datos ni la ciudad principal para el iPhone 16. Sin embargo, la agregación significativa de términos mostró que el<em><strong> iPhone 16 se está comprando de forma desproporcionada en esta ciudad</strong></em> en comparación con el resto de datos. Vamos a profundizar en los números:</p><ul><li><p><strong>En el nivel superior:</strong></p><ul><li><p><strong>doc_count: 122 — </strong>La consulta coincidió con un total de 122 documentos</p></li><li><p><strong>bg_count: 424 — </strong>El conjunto de antecedentes (todos los documentos de ventas) contiene 424 documentos</p></li></ul></li><li><p><strong>En el grupo de Houston:</strong></p><ul><li><p><strong>doc_count: 12 — </strong>Houston aparece en 12 de los 122 resultados de consulta</p></li><li><p><strong>bg_count: 14 — </strong>Houston aparece en 14 de los 424 documentos totales del conjunto de datos de fondo</p></li></ul></li></ul><p>Esto nos indica que, de un total de 424 compras, solo 14 ocurrieron en Houston; Eso supone el 3,3% de todas las compras. Sin embargo, si solo miramos las ventas del iPhone 16, vemos que 12 de 122 ocurrieron en Houston, lo que supone un 9,8%, tres veces más que en todo el conjunto de datos; ¡Eso es significativo!</p><p>Así es como se ve eso en una visualización: ventas totales por city_region.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blted1af6606708267e/6a17f5d614800960e1b488d5/f31335b0b7793650025f941820f238dd35bfb09f-1486x1066.png" alt="" /><p>Podemos ver que hay 14 ventas en Houston, lo que la convierte en la 14ª ciudad con más ventas en el conjunto de datos.</p><p>Ahora, si aplicamos un filtro para mirar solo las ventas del iPhone 16, tenemos 12 ventas en Houston, lo que la convierte en la segunda ciudad con más ventas para este modelo específico:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd2882d5e87d02406/6a17f5d71d1b83851e93e5b2/6516040db77e6c62af5541a74c723b18008ad3c6-1472x1038.png" alt="" /><h2>Comprensión de la agregación de términos significativos</h2><p>Según la documentación de Elastic, los <a href="https://www.elastic.co/docs/reference/aggregations/search-aggregations-bucket-significantterms-aggregation">términos significativos agregación</a>:</p><p><em>"(Encuentra) términos que experimentaron un cambio significativo de popularidad medido entre un conjunto de primer plano y un de fondo."</em></p><p>Esto significa que emplea métricas estadísticas para comparar la frecuencia de un término en un subconjunto de datos (el conjunto de primer plano) con la frecuencia del mismo término en el conjunto padre de datos (el conjunto de fondo). De este modo, el puntaje refleja la significación estadística en lugar de la frecuencia con la que aparece un término en los datos.</p><p>Las principales diferencias entre una agregación de términos significativos y una agregación de términos normales son:</p><ul><li><p>Los términos significativos comparan un subconjunto de los datos, mientras que la agregación de términos solo funciona sobre el conjunto de datos resultante de la consulta.</p></li><li><p>Los resultados de una agregación de términos son los más comunes en el conjunto de datos, mientras que los resultados de términos significativos ignoran los términos comunes para encontrar qué hace único el conjunto de datos.</p></li><li><p>Los términos significativos pueden tener un mayor impacto en el rendimiento, dado que necesitan obtener datos del disco en lugar de de la memoria, como ocurre con los términos agregación.</p></li></ul><h2>Aplicación práctica (análisis del comportamiento del consumidor)</h2><h3>Preparación de datos para el análisis</h3><p>Para este análisis, generamos un conjunto de datos de ventas de teléfonos sintéticos que incluye precio, especificaciones del teléfono, demografía del comprador y opiniones. También generamos incrustaciones a partir de la retroalimentación del usuario para poder ejecutar una consulta semántica más adelante. Usamos el <a href="https://huggingface.co/intfloat/multilingual-e5-small">modelo pequeño multilingüe e5</a>, disponible de fábrica en Elasticsearch.</p><p></p><p>Para usar este conjunto de datos en Elasticsearch:</p><ol><li><p>Sube el archivo CSV (descargable <a href="https://github.com/Alex1795/significant_terms_blog_dataset/blob/main/phone_sales_analysis_dataset.csv">desde aquí</a>) usando la función <a href="https://www.elastic.co/docs/manage-data/ingest/upload-data-files">de Upload de archivos de datos</a> de Kibana.</p></li><li><p>Configura un campo semántico, como se muestra en <a href="https://www.elastic.co/search-labs/blog/chat-with-pdf-elastic-playground#upload-pdfs-to-kibana">este blog,</a> llamado "embedding", que emplea el <code>multilingual-e5-small model</code></p></li><li><p>Termina la importación con los valores predeterminados del tipo de campo (palabra clave para todos los campos excepto <code>purchase_date</code> y <code>user_feedback)</code>. Cerciórate de agregar el nombre del índice <code>phone_sales_analysis</code> para poder ejecutar las consultas que se presentan aquí tal cual.</p></li></ol><p>El objetivo principal de este análisis es <em><strong>descubrir "¿Qué diferencia a los compradores del iPhone 16 frente a otros segmentos de la población?"</strong></em> y segmentar a los compradores con fines de marketing. </p><p>Este es un documento de ejemplo del conjunto de datos:</p>{
         "customer_type": "Returning",
         "user_feedback": "I have to say, quality is great for the price. The battery life is really good.",
         "upgrade_frequency": "2 years",
         "storage_capacity": "256GB",
         "occupation": "Technology &amp; Data",
         "color": "Phantom Black",
         "gender": "Male",
         "price_paid": 899,
         "previous_brand_loyalty": "Mixed",
         "location_type": "Urban",
         "phone_model": "Samsung Galaxy S24",
         "city_region": "San Francisco Bay Area",
         "@timestamp": "2024-03-15T00:00:00.000-05:00",
         "income_bracket": "75000-100000",
         "purchase_channel": "Online",
         "feedback_sentiment": "positive",
         "education_level": "Bachelor",
         "embedding": "I have to say, quality is great for the price. The battery life is really good.",
         "customer_id": "C001",
         "purchase_date": "2024-03-15",
         "age": 34,
         "trade_in_model": "iPhone 13"
}<h3>Comprensión de los patrones demográficos</h3><p>Aquí, vamos a hacer un análisis sobre la población general y compararlo con hallazgos interesantes de las agregaciones significativas de términos para usuarios de iPhone 16.</p><h4>Patrones normales</h4><p>Para entender los patrones normales de compra, podemos agregar datos de todos los documentos de diferentes campos. Para simplificar, nos centraremos en explorar las ocupaciones de las personas que compraron un teléfono. Podemos hacer esto con una solicitud a Elasticsearch.</p>GET phone_sales_analysis/_search
{
 "aggs": {
   "occupation_distribution": {
     "terms": {
       "size": 5,
       "field": "occupation"
     }
   }
 },
 "size": 0
}<p>Esto nos indica que las principales ocupaciones en el conjunto de datos (por número de registros) son:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltec11e3ae5b9cb3c0/6a17f5d9505ac3f28aad8cba/99136ddddd7abad5d74481158a04501b6915441b-1518x480.png" alt="" /><h4>Patrones de los usuarios del iPhone 16</h4><p>Para entender qué diferencia la gente que compró un iPhone 16, hagamos una agregación de términos en el mismo campo con un filtro para encontrar a las personas de la consulta, así:</p>GET phone_sales_analysis/_search
{
  "query": {
    "term": {
      "phone_model": "iPhone 16"
    }
  },
  "aggs": {
    "occupation_distribution": {
      "terms": {
        "size": 5,
        "field": "occupation"
      }
    }
  },
  "size": 0
}<p>Así que, para los usuarios del iPhone 16, las principales ocupaciones son:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt26a5415e2f30d164/6a17f5da445de9637a4d028a/36ce86475beb03810c6ad81d7c776d1eec736654-1500x484.png" alt="" /><p>Podemos ver que los usuarios del iPhone 16 tienen patrones de ocupación diferentes en comparación con los de otros modelos de teléfono. Usemos Kibana para visualizar fácilmente los resultados:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4e0ddb09fe58e454/6a17f5dce317912cfa2d596b/b70ab05bc962a274e1617b6caf20575c489a62d8-1448x1128.png" alt="" /><p></p><p>En este gráfico, podemos ver que la tendencia del iPhone 16 es diferente a la de toda la población.</p><p>Podemos saltarnos todo este análisis para ver qué diferencia a los usuarios del iPhone 16 de la población general mediante una agregación significativa de términos:</p>GET phone_sales_analysis/_search
{
  "query": {
    "term": {
      "phone_model": "iPhone 16"
    }
  },
  "aggs": {
    "occupation_distribution": {
      "significant_terms": {
        "size": 5,
        "field": "occupation"
      }
    }
  },
  "size": 0
}<p>En resumen, obtenemos esta respuesta:</p><p>Valores de las ocupaciones para el iPhone 16</p><p>doc_count</p><p>bg_count</p><p>occupation_distribution (nivel superior)</p><p>122</p><p>424</p><p>Sector Médico y Sanitario</p><p>45</p><p>57</p><p>La respuesta sugiere claramente que los usuarios del iPhone 16 tienen un caso poco común (¡leer, significativo!) número de personas en el ámbito médico y sanitario en comparación con la población general. Veamos qué significan los números de la respuesta:</p><ul><li><p><strong>En el nivel superior:</strong></p><ul><li><p><strong>doc_count: 122 — </strong>La consulta coincidió con un total de 122 documentos</p></li><li><p><strong>bg_count: 424 — </strong>El conjunto de antecedentes (todos los documentos de ventas) contiene 424 documentos</p></li></ul></li><li><p><strong>En el ámbito Médico y Sanitario:</strong></p><ul><li><p><strong>doc_count: 45 — </strong>"Medical &amp; Healthcare" aparece en 45 de los 122 resultados de consulta</p></li><li><p><strong>bg_count: 57 — </strong>"Médico y Salud" aparece en 57 de los 424 documentos totales del conjunto de datos de antecedentes</p></li></ul></li></ul><p>De 424 compradores, 57 trabajan en el ámbito médico y sanitario — o el 13,44%. Pero cuando miramos a los compradores del iPhone 16, 45 de 122 trabajan en el ámbito médico y sanitario — eso supone el 36,88%. ¡Esto significa que tenemos el doble de probabilidades de encontrar a alguien trabajando en el ámbito médico y sanitario entre los usuarios del iPhone 16!</p><p>Podemos aplicar este mismo análisis a otros campos (edad, ubicación, rango de ingresos, etc.) para encontrar más información sobre qué hace único a los usuarios del iPhone 16. </p><h3>Segmentación del consumidor</h3><p>Podemos emplear los términos agregación significativa para extraer información sobre las relaciones entre productos, categorías y segmentos de clientes. Para ello, construimos una agregación madre para la categoría que nos interesa explorar. También usamos términos significativos y una subagregación de términos normales para encontrar ideas interesantes sobre esa categoría y compararlas con lo que la mayoría de las personas en esa ocupación usan.</p><p>Por ejemplo, veamos qué prefieren las personas en algunos campos laborales:</p><ol><li><p>Para aclarar el análisis, limitemos nuestra búsqueda a 3 campos de trabajo: ["Administrativo y Soporte", "Tecnología y Datos", "Médico y Sanidad"]</p></li><li><p>En el lado de las agregaciones, comenzamos con una agregación por ocupación</p></li><li><p>Agrega una subagregación: términos por modelo de teléfono—para descubrir qué modelos están comprando los usuarios que trabajan en cada campo</p></li><li><p>Agregar una segunda subagregación: términos significativos por modelos de teléfono, para encontrar qué modelos son especiales en cada campo de trabajo</p></li></ol>GET phone_sales_analysis/_search
{
 "query": {
   "terms": {
     "occupation": [
       "Administrative &amp; Support",
       "Technology &amp; Data",
       "Medical &amp; Healthcare"
     ]
   }
 },
 "aggs": {
   "occupations": {
     "terms": {
       "size": 15,
       "field": "occupation"
     },
     "aggs": {
       "general_models": {
         "terms": {
           "field": "phone_model"
         }
       },
       "significant_models": {
         "significant_terms": {
           "field": "phone_model"
         }
       }
     }
   }
 },
 "size": 0
}<p>Desglosemos los resultados de la agregación:</p><p><strong>Ocupación</strong>: Administrativa y de Apoyo</p><p><strong>Agregación de términos</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3a325cde37b40504/6a17f5dd4b055dbb68432372/a4ad519c9013867a3f4cee032160eadd8a47804a-1506x398.png" alt="" /><p><strong>Agregación de términos significativa</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltef514b8bbb7f429c/6a17f5df3e9e456488ba1612/e5604fa8036667bdfe733576a5e7c6153760dd3a-306x220.png" alt="" /><p>De esta tabla, podemos inferir que no hay diferencias significativas entre la tendencia de esta ocupación y la tendencia de toda la población</p><p><strong>Ocupación</strong>: Tecnología y Datos</p><p><strong>Agregación de términos</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt94189446d8f3100e/6a17f5e142022983b029f76e/13b09039bb7d183276451007d2d69dc190b1d3c0-1508x836.png" alt="" /><p></p><p><strong>Agregación de términos significativa</strong></p><p>Total de documentos: 424</p><p>Documentos de esta ocupación: 71</p><p>Modelo de teléfono</p><p>doc_count (este modelo en esta ocupación)</p><p>bg_count (este modelo en todos los documentos)</p><p>% en todos los documentos</p><p>% en esta ocupación</p><p>Google Pixel 8</p><p>12</p><p>22</p><p>5.19%</p><p>16.90%</p><p>OnePlus 11</p><p>9</p><p>14</p><p>3.30 %</p><p>12.68%</p><p>OnePlus 12 Pro</p><p>3</p><p>3</p><p>0.71 %</p><p>4.23%</p><p>Google Pixel 8 Pro</p><p>9</p><p>21</p><p>4.95%</p><p>12.68%</p><p>Nothing Phone 2</p><p>5</p><p>8</p><p>1.89%</p><p>7.04%</p><p>Samsung Galaxy Z Fold5</p><p>4</p><p>6</p><p>1.42%</p><p>5.63%</p><p>OnePlus 12</p><p>8</p><p>20</p><p>4.72%</p><p>11.27 %</p><p><strong>Ocupación</strong>: Medicina y Sanidad</p><p><strong>Agregación de términos</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt270b0a861a16488a/6a17f5e23e03d76a934f2df0/b008e996742fc0bb48dc6bacff17cfbc56cf0d73-1492x398.png" alt="" /><p><strong>Agregación de términos significativa</strong></p><p>Total de documentos: 424</p><p>Documentos en esta ocupación: 57</p><p>Modelo de teléfono</p><p>doc_count (este modelo en esta ocupación)</p><p>bg_count (este modelo en todos los documentos)</p><p>% en todos los documentos</p><p>% en esta ocupación</p><p>iPhone 16</p><p>45</p><p>122</p><p>28.77%</p><p>78.95%</p><p>iPhone 15 Pro Max</p><p>3</p><p>13</p><p>3.07 %</p><p>5.26%</p><p>iPhone 15</p><p>7</p><p>40</p><p>9.43%</p><p>12.28%</p><p>Veamos qué historia nos cuentan estos datos:</p><ul><li><p>Los profesionales sanitarios prefieren el iPhone 16 y suelen estar muy inclinados a usar teléfonos Apple en general.</p></li><li><p>Los profesionales de tecnología y datos prefieren teléfonos Android de gama alta, pero no necesariamente usan la marca Samsung. También hay una tendencia considerable para los iPhones en esta categoría.</p></li><li><p>Los profesionales administrativos y de soporte prefieren los teléfonos Samsung y Google, pero no tienen una tendencia fuerte y única.</p></li></ul><h3>Agregación de términos significativos y búsqueda híbrida</h3><p>La búsqueda híbrida combina la búsqueda por texto y resultados semánticos para ofrecer una experiencia de búsqueda mejorada. En este contexto, una agregación significativa de términos puede aportar información sobre los resultados de una búsqueda consciente del contexto al responder a la pregunta: <strong>¿Qué tiene de especial este conjunto de datos en comparación con todos los documentos?</strong>Para demostrar esta característica, veamos qué modelos están sobrerrepresentados cuando los usuarios hablan de buen rendimiento: </p><ul><li><p>Vamos a construir una consulta semántica donde encontramos la mejor retroalimentación de los usuarios más cerca de la entrada de "buen rendimiento" en comparación con la incrustación de campos</p></li><li><p>También usaremos una búsqueda de texto con los mismos términos sobre el campo de texto user_feedback</p></li><li><p>También agregaremos una consulta significativa de términos para encontrar modelos telefónicos que se encuentren con más frecuencia entre estos resultados que en el conjunto de datos completo
</p></li></ul>GET phone_sales_analysis/_search
{
 "retriever": {
   "rrf": {
     "retrievers": [
       {
         "standard": {
           "query": {
             "bool": {
               "must": [
                 {
                   "match": {
                     "user_feedback": {
                       "query": "good performance",
                       "operator": "and"
                     }
                   }
                 }
               ]
             }
           }
         }
       },
       {
         "standard": {
           "query": {
             "semantic": {
               "field": "embedding",
               "query": "good performance"
             }
           }
         }
       }
     ],
    "rank_window_size": 20
   }
 },
 "aggs": {
   "Models": {
     "significant_terms": {
       "field": "phone_model"
     }
   }
 }
}<p>Veamos un ejemplo de los documentos que coinciden:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1c3dc221896c8832/6a17f5e4445de91eac4d028e/4cb488097a382f0c28c21540db4f593d23633473-1600x162.png" alt="" /><p>Esta es la respuesta que recibimos:</p>{
  "took": 388,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 20,
      "relation": "eq"
    },
    "max_score": 0.016393442,
    "hits": [...]
  },
  "aggregations": {
    "Models": {
      "doc_count": 20,
      "bg_count": 424,
      "buckets": [
        {
          "key": "iPhone 15",
          "doc_count": 5,
          "score": 0.4125,
          "bg_count": 40
        }
      ]
    }
  }
}<p></p><p>Esto nos indica que, aunque un iPhone 15 se encuentra 40 veces de un total de 424 documentos (el 9,4% de los documentos), puede encontrar 5 veces en los 20 documentos que coinciden con la búsqueda semántica de "buen rendimiento" (el 25% de los documentos). Por tanto, podemos sacar una conclusión: un iPhone 15 tiene 2,7 veces más probabilidades de encontrar cuando se habla de buen rendimiento que por casualidad.</p><h2>Conclusión</h2><p>Los términos significativos agregación pueden descubrir detalles únicos de un conjunto de datos comparándolo con el universo de documentos. Esto puede revelar relaciones inesperadas en nuestros datos, que van más allá del conteo de ocurrencias. Podemos aplicar términos significativos en diversos casos de uso que permiten características muy interesantes, por ejemplo:</p><ul><li><p><a href="https://www.elastic.co/blog/significant-terms-aggregation#credit">Encuentra patrones al trabajar en </a>la detección de fraude — identifica transacciones comunes de tarjetas de crédito robadas.</p></li><li><p>Información sobre la calidad de la marca a partir de opiniones de usuarios — detecta una marca con un número desproporcionado de malas valoraciones.</p></li><li><p><a href="https://www.elastic.co/docs/reference/aggregations/search-aggregations-bucket-significantterms-aggregation#_use_on_free_text_fields">Documentos mal clasificados </a>— documentos puntuales que pertenecen a una categoría (filtro de términos) que usan palabras poco comunes para la categoría en una descripción (agregación significativa de términos).</p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/significant-terms-aggregation-elasticsearch</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/significant-terms-aggregation-elasticsearch</guid>
    <category><![CDATA[Conceptos básicos]]></category>
    <category><![CDATA[Búsqueda en DSL]]></category>
    <dc:creator><![CDATA[Alexander Dávila]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta4d95b6134c2a110/6a17f5e6505ac3fd3cad8cbf/13adbc901837835bb56abf15e377127b017cfac8-1536x1024.png" length="0" type="image/png"/>
    <pubDate>Mon, 07 Jul 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Cómo desplegar Elasticsearch en GCP GKE Autopilot]]></title>
    <description><![CDATA[Aprende cómo desplegar un clúster de Elasticsearch en GCP usando GKE Autopilot y ECK para una configuración parcialmente gestionada de Elasticsearch.]]></description>
    <content:encoded><![CDATA[<p>En este artículo, vamos a aprender cómo desplegar Elasticsearch en Google Cloud Kubernetes (GKE) usando Autopilot.</p><p>Para Elasticsearch, vamos a emplear <a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s">Elastic Cloud on Kubernetes </a>(ECK), que es el operador oficial de Elasticsearch Kubernetes que simplifica la orquestación de despliegues de Kubernetes de todos los componentes de Elastic Stack.</p><p>Para obtener más información sobre cómo desplegar clústeres de Elasticsearch en diferentes infraestructuras de GCP, puedes leer nuestros artículos de introducción sobre <a href="https://www.elastic.co/search-labs/blog/elasticsearch-gpc-google-compute-engine">Google Cloud Compute</a> y <a href="https://www.elastic.co/search-labs/blog/deploy-elastic-gcp-marketplace">Google Cloud Marketplace</a>.</p><h2>Esfuerzo de despliegue de Elasticsearch</h2><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt61969357430c94f8/6a17f6d125daab024708a3ae/56b54d718dcff9af9050873c41fdf738074851da-1428x582.png" alt="Esfuerzo de despliegue de Elasticsearch ECK." /><h3>¿Qué es GKE Autopilot?</h3><p><a href="https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-overview?hl=es-419"><strong>Google Kubernetes Engine (GKE) Autopilot</strong></a> ofrece una experiencia Kubernetes totalmente gestionada donde Google se encarga de la configuración del clúster, la gestión de nodos, la seguridad y el escalado, mientras los desarrolladores se centran en desplegar aplicaciones, lo que les permite a los equipos pasar del código a la producción en minutos con las mejores prácticas integradas.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt91e10f44290aeac4/6a17f6d33e9e451f67ba1638/bbf6de63fa0a199326352f521cb22654818799f6-1600x958.png" alt="Contenedores de GKE Autopilot." /><h2>¿Cuándo usar el ECK en Google Cloud?</h2><p>Elastic Cloud on Kubernetes (ECK) es el más adecuado para organizaciones con infraestructura existente de Kubernetes que buscan desplegar Elasticsearch con características avanzadas como roles de nodo dedicados, alta disponibilidad y automatización.</p><h2>¿Cómo configurar ECK en Google Cloud?</h2><p>1. Inicia sesión en <a href="https://console.cloud.google.com">Google Cloud Console</a>.</p><p>2. En la <strong>parte superior derecha </strong>haz clicen el botón <strong>Cloud Shell</strong> para acceder a la consola y desplegar el clúster de GKE desde allí. Alternativamente, puedes usar la <a href="https://cloud.google.com/cli">CLI de gcloud</a>.</p><p><em><strong>Recuerda actualizar el identificador del proyecto con el tuyo durante el tutorial.</strong></em></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc69e47bf97e4be31/6a17f6d5505ac3bbe6ad8cdb/999b03861d4fe44f360ab4c7e2616e1dc10cf182-1558x1248.png" alt="¿Cómo configurar Elasticsearch en GCP GKE Autopilot?" /><p>3. Habilita la <a href="https://console.cloud.google.com/flows/enableapi?apiid=container.googleapis.com">API de Google Kubernetes Engine</a>.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1a4d95465f563ece/6a17f6d7e8fbced6393a1af3/03827d3dc0e987c019e7747d33e7c01920047beb-911x246.png" alt="Habilitar la API de Google Kubernetes Engine." /><p>Haz <em><strong>clic en Siguiente.</strong></em></p><p>Ahora, la API de Kubernetes Engine debería mostrarse habilitada al buscar la API de Kubernetes Engine.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6ba41b82d995347f/6a17f6d8505ac3036bad8cdf/d5cd46f0333086bcb31b80cf9c08a469b449ec0f-640x250.png" alt="La API de Kubernetes Engine." /><p>4. En Cloud Shell, crea un clúster de Autopilot. Lo llamaremos autopilot-cluster-1, y también reemplazaremos autopilot-test por el id de tu proyecto.</p>gcloud beta container --project "autopilot-test-457216" clusters create-auto "autopilot-cluster-1" --region "us-central1" --release-channel "regular" --tier "standard" --enable-ip-access --no-enable-google-cloud-access --network "projects/autopilot-test-457216/global/networks/default" --subnetwork "projects/autopilot-test-457216/regions/us-central1/subnetworks/default" --cluster-ipv4-cidr "/17" --binauthz-evaluation-mode=DISABLED<p>5. Espera hasta que esté listo. Tarda unos 10 minutos en crearse.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4e821e77d5db5d71/6a17f6da148009381cb48900/81fbc45ba56d0f16ba42724cb8ae45e60b327dbc-1581x258.png" alt="Imagen de una configuración de cluster de Autopilot." /><p>Aparecerá un mensaje de confirmación después de configurar correctamente el clúster.</p><p>6. Configura el acceso a la línea de comandos de kubectl.</p>gcloud container clusters get-credentials autopilot-cluster-1 --region us-central1 --project autopilot-test-457216<p>Deberías ver:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf1c828e5059c8ec8/6a17f6dcabe0f215e5dfebb7/b0beba1ee00ce9029f586ee32693fc2aa58c7f65-3442x142.png" alt="" /><p><em>Entrada de kubeconfig generada para autopilot-cluster-1.</em></p><p>7. Instala el operador <a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s">Elastic Cloud on Kubernetes</a> (ECK).</p># Install ECK Custom Resource Definitions
kubectl create -f https://download.elastic.co/downloads/eck/2.16.1/crds.yaml

# Install the ECK operator
kubectl apply -f https://download.elastic.co/downloads/eck/2.16.1/operator.yaml<p>8. Creemos una instancia de Elasticsearch de un solo nodo con los valores por defecto.</p><p>Si deseas consultar algunas recetas para diferentes configuraciones, puedes visitar <a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s/recipes">este enlace</a>.</p><p>Ten en cuenta que si no especificas un <code>storageClass</code>, ECK usará el que se configura por defecto, que para GKE es <code>standard-rwo</code> y usa el <a href="https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/gce-pd-csi-driver?cloudshell=true">controlador CSI de disco persistente de Compute Engine</a>, y creará un volumen de 1GB con él.</p>cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: quickstart
spec:
  version: 9.0.0
  nodeSets:
  - name: default
    count: 1
    config:
      node.store.allow_mmap: false
EOF<p>Deshabilitamos <code>nmap</code> porque la máquina GKE predeterminada tiene un valor <code>vm.max_map_count</code> demasiado bajo. No se recomienda desactivarlo para la producción, pero sí aumentar el valor de <code>vm.max_map_count</code>. Puedes leer más sobre cómo hacerlo <a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s/virtual-memory">aquí</a>.</p><p>9. También despleguemos un clúster de un solo nodo Kibana. Para Kibana, agregaremos un LoadBalancer que nos dará una IP externa que podemos usar para acceder a Kibana desde nuestro dispositivo.</p>cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
  name: quickstart
spec:
  version: 9.0.0
  http:
    service:
      metadata:
        annotations:
          cloud.google.com/l4-rbs: "enabled"
      spec:
        type: LoadBalancer
  count: 1
  elasticsearchRef:
    name: quickstart
EOF<p>Nota la anotación: </p><p><code>cloud.google.com/l4-rbs: "enabled"</code></p><p><em><strong>Es muy importante porque le indica a Autopilot que proporcione un LoadBalancer orientado al público. Si no se configura, el LoadBalancer será interno.</strong></em></p><p>10. Verifica que tus pods estén en ejecución</p>kubectl get pods<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt627dd8f482340bc2/6a17f6de3e03d779a44f2e16/99da1270581a137683770efdb9c6e1577ec9fc01-3150x442.png" alt="" /><p>11. También puedes <code>run kubectl get elasticsearch</code> y <code>kubectl get kibana</code> para obtener estadísticas más específicas como la versión de Elasticsearch, nodos y salud.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt32d179d1c4f785b3/6a17f6e04b055db05a432392/86234f307970fd5f78b8acd41496e8cc89ff82d3-3414x326.png" alt="" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt75b60dc0e4ad9636/6a17f6e296142a27eaeb1ca6/29160286ccc88928734c8ea11b1923db8e85d49d-3142x318.png" alt="" /><p>12. Accede a tus servicios.</p>kubectl get svc<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3806ad91791373a2/6a17f6e46df731bc800a10ab/ed1a07314b84a99b4aa1fec3db4b9badeb9587ee-3446x610.png" alt="" /><p>Esto te mostrará la URL externa de Kibana bajo EXTERNAL-IP. Puede que el LoadBalancer tarde unos minutos en provisionar. <em><strong>Copia el valor de EXTERNAL-IP.</strong></em></p><p>13 Obtén la contraseña de Elasticsearch para el usuario ‘elastic’:</p>kubectl get secret quickstart-es-elastic-user -o=jsonpath='{.data.elastic}' | base64 --decode<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5ab53ce5a685491b/6a17f6e63e03d74fcc4f2e1a/ab5054219216ebc15fc0d96e27605aaf13b720c6-3448x210.png" alt="" /><p>14. <strong>Accede a Kibana</strong> desde tu navegador:</p><ul><li><p>URL:&lt;EXTERNAL_IP&gt; https://:5601</p></li><li><p>Nombre de usuario: elastic</p></li><li><p>Contraseña: 28Pao50lr2GpyguX470L2uj5 (del paso anterior)</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd86d22f797132c21/6a17f6e7e8fbce62b43a1afb/47cbe88dc14db64db3a256f3f7504cc86a843475-463x503.png" alt="Pantalla de bienvenida de Elastic." /><p>15. Al acceder desde tu navegador, verás la pantalla de bienvenida.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6f44dc23e6f1f625/6a17f6e9be6086ea71004948/a75c151c0144b7efe2b730698c0ed0156fa9b16a-1600x1005.png" alt="Página de inicio de Elasticsearch." /><p>Si quieres cambiar las especificaciones del clúster de Elasticsearch, como cambiar o redimensionar nodos, puedes volver a aplicar el manifesto yml con los nuevos ajustes:</p>cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: quickstart
spec:
  version: 9.0.0
  nodeSets:
    - name: default
      count: 2
      config:
        node.store.allow_mmap: false
      podTemplate:
        spec:
          containers:
            - name: elasticsearch
              resources:
                requests:
                  memory: 1.5Gi
                  cpu: 2
                limits:
                  memory: 1.5Gi
                  cpu: 2
EOF<p>En este ejemplo, vamos a agregar un nodo más y modificar la RAM y la CPU. Como puedes ver, ahora <code>kubectl get elasticsearch</code> muestra 2 nodos:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt33a7ba0be483195a/6a17f6ebe8fbcea7da3a1aff/48b475622cc48890bff8105d151f2cbde28d7021-3418x298.png" alt="" /><p>Lo mismo aplica para Kibana:</p>cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
  name: quickstart
spec:
  version: 9.0.0
  http:
    service:
      metadata:
        annotations:
          cloud.google.com/l4-rbs: "enabled"
      spec:
        type: LoadBalancer
  count: 1
  elasticsearchRef:
    name: quickstart
  podTemplate:
    spec:
      containers:
        - name: kibana
          env:
            - name: NODE_OPTIONS
              value: "--max-old-space-size=1024"
          resources:
            requests:
              memory: 0.5Gi
              cpu: 0.5
            limits:
              memory: 1Gi
              cpu: 1
EOF<p>Podemos ajustar la CPU/RAM del contenedor y también el uso de memoria <a href="https://nodejs.org/">de Node.js </a>(<a href="https://nodejs.org/api/cli.html#--max-old-space-sizesize-in-mib">max-old-space-size</a>).</p><p>Ten en cuenta que <a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s/volume-claim-templates">las solicitudes de volumen existentes no pueden reducirse</a>. Después de aplicar la actualización, el operador realizará los cambios con el mínimo tiempo de interrupción.</p><p>Recuerda eliminar el clúster cuando termines de probar para evitar costos innecesarios.</p>gcloud container clusters delete autopilot-cluster-1<h2>Pasos siguientes</h2><p>Si quieres saber más sobre Kubernetes y el motor de Google Kubernetes, consulta estos artículos:</p><ul><li><p><a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s">Elastic Cloud en Kubernetes | Elastic Docs</a></p></li><li><p><a href="https://cloud.google.com/blog/products/containers-kubernetes/introducing-gke-autopilot">Presentamos GKE Autopilot | Blog de Google Cloud</a></p></li><li><p><a href="https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-overview">Visión general del piloto automático | Google Kubernetes Engine (GKE)</a></p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/eck-gke-autopilot</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/eck-gke-autopilot</guid>
    <category><![CDATA[Conceptos básicos]]></category>
    <dc:creator><![CDATA[Eduard Martin]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltea045d2d12606d11/6a17f6edb1e113c86179f3e7/d9c462fe63011356671479ccfedd435eec1ede52-1200x628.png" length="0" type="image/png"/>
    <pubDate>Thu, 19 Jun 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elasticsearch en JavaScript de la manera correcta, parte II]]></title>
    <description><![CDATA[Aprende sobre las mejores prácticas de producción y cómo ejecutar el cliente de Node.js de Elasticsearch en entornos sin servidor para reducir errores de código. ]]></description>
    <content:encoded><![CDATA[<p>Esta es la segunda parte de nuestro serial Elasticsearch en JavaScript. En la<a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i"> primera parte,</a> aprendimos a configurar correctamente nuestro entorno, configurar el cliente Node.js, indexar datos y buscar. En esta segunda parte, aprenderemos a implementar las mejores prácticas de producción y a ejecutar el cliente <a href="http://node.js">de Node.js</a> Elasticsearch en entornos sin servidor.</p><p>Revisaremos:</p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-ii#production-best-practices">Mejores prácticas de producción</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-ii#error-handling">Manejo de errores</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-ii#testing">Pruebas</a></p></li></ul></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-ii#serverless-environments">Entornos sin servidor</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-ii#running-the-client-on-elastic-serverless">Ejecutando el cliente en Elastic Serverless</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-ii#running-the-client-on-function-as-a-service-environment">Ejecutando el cliente en un entorno de función como servicio</a></p></li></ul></li></ul><p><em>Puedes consultar el código fuente con los ejemplos </em><a href="https://github.com/Delacrobix/JS-client-best-practices_article"><em><strong>aquí</strong></em></a><em><strong>.</strong></em></p><h2>Mejores prácticas de producción</h2><h3>Manejo de errores en Elasticsearch</h3><p>Una característica útil del cliente Elasticsearch en Node.js es que expone objetos para los posibles errores en Elasticsearch, de modo que puedes validarlos y manejarlos de diferentes maneras.</p><p>Para <a href="https://www.elastic.co/docs/reference/elasticsearch/clients/javascript/connecting#client-error-handling">verlos todos</a>, pon esto: </p>const { errors } = require('@elastic/elasticsearch')
console.log(errors)<p>Volvamos al ejemplo de búsqueda y tratemos algunos de los posibles errores:</p>app.get("/search/lexic", async (req, res) =&gt; {
 ....
  } catch (error) {
    if (error instanceof errors.ResponseError) {
      let errorMessage =
        "Response error!, query malformed or server down, contact the administrator!";

      if (error.body.error.type === "parsing_exception") {
        errorMessage = "Query malformed, make sure mappings are set correctly";
      }

      res.status(error.meta.statusCode).json({
        erroStatus: error.meta.statusCode,
        success: false,
        results: null,
        error: errorMessage,
      });
    }

    res.status(500).json({
      success: false,
      results: null,
      error: error.message,
    });
  }
});<p><code>ResponseError</code> en individuo, ocurrirá cuando la respuesta sea <code>4xx</code> o <code>5xx</code>, lo que significa que la solicitud es incorrecta o el servidor no está disponible.</p><p>Podemos probar este tipo de error generando consultas erróneas, como intentar <strong>hacer una consulta de términos en un campo de tipo texto:</strong></p><p>Error por defecto:</p> {
    "success": false,
    "results": null,
    "error": "parsing_exception\n\tRoot causes:\n\t\tparsing_exception: [terms] query does not support [visit_details]"
}<p>Error personalizado: </p>{
    "erroStatus": 400,
    "success": false,
    "results": null,
    "error": "Response error!, query malformed or server down; contact the administrator!"
}<p>También podemos capturar y manejar cada tipo de error de una manera determinada. Por ejemplo, podemos agregar lógica de reintentos en un <code>TimeoutError</code>.</p>app.get("/search/semantic", async (req, res) =&gt; {
    try {
  ...
  } catch (error) {
    if (error instanceof errors.TimeoutError) {


     // Retry logic...

      res.status(error.meta.statusCode).json({
        erroStatus: error.meta.statusCode,
        success: false,
        results: null,
        error:
          "The request took more than 10s after 3 retries. Try again later.",
      });
    }
  }
});<h3>Pruebas</h3><p>Las pruebas son clave para garantizar la estabilidad de la aplicación. Para probar el código de forma aislada de Elasticsearch, podemos usar la biblioteca <a href="https://github.com/elastic/elasticsearch-js-mock">elasticsearch-js-mock</a> al crear nuestro clúster.</p><p>Esta biblioteca nos permite instanciar un cliente muy similar al real, pero que responderá a nuestra configuración reemplazando solo la capa HTTP del cliente por una mock, manteniendo el resto igual que el original.</p><p>Instalaremos la biblioteca de simulacros y <a href="https://github.com/avajs/ava">AVA</a> para los exámenes automatizados.</p><p><code>npm install @elastic/elasticsearch-mock</code></p><p><code>npm install --save-dev ava</code></p><p>Configuraremos el archivo <code>package.json</code> para ejecutar las pruebas. Cerciórate de que se vea así:</p>"type": "module",
	"scripts": {
		"test": "ava"
	},
	"devDependencies": {
		"ava": "^5.0.0"
	}<p>Ahora creemos un archivo <code>test.js</code> e instalemos nuestro cliente simulado:</p>const { Client } = require('@elastic/elasticsearch')
const Mock = require('@elastic/elasticsearch-mock')

const mock = new Mock()
const client = new Client({
  node: 'http://localhost:9200',
  Connection: mock.getConnection()
})<p>Ahora, agrega un simulacro para la búsqueda semántica:</p>function createSemanticSearchMock(query, indexName) {
  mock.add(
    {
      method: "POST",
      path: `/${indexName}/_search`,
      body: {
        query: {
          semantic: {
            field: "semantic_field",
            query: query,
          },
        },
      },
    },
    () =&gt; {
      return {
        hits: {
          total: { value: 2, relation: "eq" },
          hits: [
            {
              _id: "1",
              _score: 0.9,
              _source: {
                owner_name: "Alice Johnson",
                pet_name: "Buddy",
                species: "Dog",
                breed: "Golden Retriever",
                vaccination_history: ["Rabies", "Parvovirus", "Distemper"],
                visit_details:
                  "Annual check-up and nail trimming. Healthy and active.",
              },
            },
            {
              _id: "2",
              _score: 0.7,
              _source: {
                owner_name: "Daniel Kim",
                pet_name: "Mochi",
                species: "Rabbit",
                breed: "Mixed",
                vaccination_history: [],
                visit_details:
                  "Nail trimming and general health check. No issues.",
              },
            },
          ],
        },
      };
    }
  );
}<p>Ahora podemos crear una prueba para nuestro código, cerciorándonos de que la parte de Elasticsearch siempre devolverá los mismos resultados:</p>import test from 'ava';

test("performSemanticSearch must return formatted results correctly", async (t) =&gt; {
  const indexName = "vet-visits";
  const query = "Which pets had nail trimming?";

  createSemanticSearchMock(query, indexName);

  async function performSemanticSearch(esClient, q, indexName = "vet-visits") {
    try {
      const result = await esClient.search({
        index: indexName,
        body: {
          query: {
            semantic: {
              field: "semantic_field",
              query: q,
            },
          },
        },
      });

      return {
        success: true,
        results: result.hits.hits,
      };
    } catch (error) {
      if (error instanceof errors.TimeoutError) {
        return {
          success: false,
          results: null,
          error: error.body.error.reason,
        };
      }

      return {
        success: false,
        results: null,
        error: error.message,
      };
    }
  }

  const result = await performSemanticSearch(esClient, query, indexName);

  t.true(result.success, "The search must be successful");
  t.true(Array.isArray(result.results), "The results must be an array");

  if (result.results.length &gt; 0) {
    t.true(
      "_source" in result.results[0],
      "Each result must have a _source property"
    );
    t.true(
      "pet_name" in result.results[0]._source,
      "Results must include the pet_name field"
    );
    t.true(
      "visit_details" in result.results[0]._source,
      "Results must include the visit_details field"
    );
  }
});<p>Hagamos las pruebas.</p><p><code>npm run test</code></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt36304e286146f362/6a170559d7c02237b2de638f/42feae845ae8eae03c37ad7ad114e8db35984812-1186x302.png" alt="" /><p>¡Hecho! A partir de ahora, podemos probar nuestra app centrándonos al 100% en el código y no en factores externos.</p><h2>Entornos sin servidor</h2><h3>Cómo ejecutar el cliente en Elastic Serverless</h3><p>Cubrimos la ejecución de Elasticsearch en la nube o local; sin embargo, el cliente Node.js también soporta conexiones a <a href="https://www.elastic.co/guide/en/serverless/current/intro.html">Elastic Cloud Serverless</a>.</p><p>Elastic Cloud Serverless te permite crear un proyecto donde no tienes que preocuparte por la infraestructura, ya que Elastic se encarga de eso internamente, y solo tienes que preocuparte por los datos que quieres indexar y cuánto tiempo quieres tener acceso a ellos.</p><p>Desde la perspectiva del uso, los servidores sin servidor desacoplan el cálculo del almacenamiento, proporcionando funciones de escalado automático tanto para <a href="https://www.elastic.co/search-labs/blog/elasticsearch-serverless-tier-autoscaling">búsqueda</a> como <a href="https://www.elastic.co/search-labs/blog/elasticsearch-ingest-autoscaling">para indexación</a>. Esto te permite solo hacer crecer los recursos que realmente necesitas.</p><p>El cliente realiza las siguientes adaptaciones para conectarse a Serverless:</p><ul><li><p>Apaga el olfateo e ignora cualquier opción relacionada con el olfateo</p></li><li><p>Ignora todos los nodos que pasan en la configuración excepto el primero, e ignora cualquier filtrado de nodos y seleccionando opciones</p></li><li><p>Activa la compresión y el 'TLSv1_2_method' (igual que cuando se configura para Elastic Cloud)</p></li><li><p>Agrega un encabezado HTTP 'elastic-api-version' a todas las solicitudes</p></li><li><p>Emplea 'CloudConnectionPool' por defecto en lugar de 'WeightedConnectionPool'</p></li><li><p>Desactiva los encabezados 'content-type' y 'accept' que venden en favor de los tipos MIME estándar</p></li></ul><p>Para conectar tu proyecto serverless, necesitas usar el parámetro serverMode: serverless.</p>const { Client } = require('@elastic/elasticsearch')
const client = new Client({
  node: 'ELASTICSEARCH_ENDPOINT',
  auth: { apiKey: 'ELASTICSEARCH_API_KEY' },
  serverMode: "serverless",
});<h3>Cómo ejecutar el cliente en un entorno de función como servicio</h3><p>En el ejemplo, usamos un servidor Node.js, pero también puedes conectarte usando un entorno de función como servicio con funciones como AWS Lambda, GCP Run, etc.</p>'use strict'

const { Client } = require('@elastic/elasticsearch')

const client = new Client({
  // client initialisation
})

exports.handler = async function (event, context) {
  // use the client
}<p>Otro ejemplo es conectarse a servicios como Vercel, que también es sin servidor. Puedes consultar este <a href="https://github.com/elastic/elasticsearch-js/blob/main/docs/examples/proxy/README.md">ejemplo completo</a> de cómo hacerlo, pero la parte más relevante del <a href="https://github.com/elastic/elasticsearch-js/blob/main/docs/examples/proxy/api/search.js">endpoint de búsqueda</a> es la siguiente:</p>const response = await client.search(
  {
    index: INDEX,
    // You could directly send from the browser
    // the Elasticsearch's query DSL, but it will
    // expose you to the risk that a malicious user
    // could overload your cluster by crafting
    // expensive queries.
    query: {
      match: { field: req.body.text },
    },
  },
  {
    headers: {
      Authorization: `ApiKey ${token}`,
    },
  }
);<p>Este endpoint reside en la carpeta /api y se ejecuta desde el lado del servidor, de modo que el cliente solo tiene control sobre el parámetro "texto" que corresponde al término de búsqueda.</p><p>La participación de usar función como servicio es que, a diferencia de un servidor que funciona 24/7, las funciones solo activan la máquina que ejecuta la función y, una vez terminada, la máquina entra en modo reposo para consumir menos recursos.</p><p>Esta configuración puede ser conveniente si la aplicación no recibe demasiadas solicitudes; De lo contrario, los costos pueden ser elevados. También tienes que considerar el <a href="https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtime-environment.html">ciclo de vida de las funciones</a> y los tiempos de ejecución (que en algunos casos pueden ser solo segundos).</p><h2>Conclusión</h2><p>En este artículo, aprendimos a manejar errores, algo crucial en entornos de producción. También cubrimos pruebas de nuestra aplicación simulando el servicio Elasticsearch, que proporciona pruebas fiables independientemente del estado del clúster y nos permite centrarnos en nuestro código.</p><p>Finalmente, demostramos cómo crear una pila totalmente serverless aprovisionando tanto Elastic Cloud Serverless como una aplicación Vercel.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-ii</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-ii</guid>
    <category><![CDATA[Javascript]]></category>
    <category><![CDATA[Conceptos básicos]]></category>
    <dc:creator><![CDATA[Jeffrey Rengifo]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc58be329ffebcd60/6a17043e47d49c0bc62d88ab/70fb0ff949f6db9ac9b8a28ecb4329ab915ebf46-720x420.png" length="0" type="image/png"/>
    <pubDate>Mon, 19 May 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Cómo optimizar el espacio en disco y el uso de Elasticsearch]]></title>
    <description><![CDATA[Aprende a prevenir y manejar los casos en los que el disco de Elasticsearch está demasiado lleno (sobreutilización) y cuando la capacidad del disco está infrautilizada para optimizar los costos del clúster.]]></description>
    <content:encoded><![CDATA[<p>La gestión de discos es importante en cualquier base de datos, y Elasticsearch no es una excepción. Si no tienes suficiente espacio en disco disponible, Elasticsearch dejará de asignar fragmentos al nodo. Esto acabará impidiéndote poder escribir datos en el clúster, con el riesgo potencial de pérdida de datos en tu aplicación. Por otro lado, si tienes demasiado espacio en disco, entonces estás pagando por más recursos de los que necesitas.</p><h2>Antecedentes sobre las marcas de agua</h2><p>Hay varios umbrales de "marca de agua" en tu clúster de Elasticsearch que te ayudan a rastrear el espacio disponible en disco. A medida que el disco se llena en un nodo, el primer umbral que se cruzará será la "marca de agua de disco bajo". El segundo umbral será entonces el "umbral alto de marca de agua en disco". Finalmente, se alcanzará la "fase de inundación de disco". Una vez superado este umbral, el clúster bloqueará la escritura en TODOS los índices que tengan un fragmento (primario o réplica) en el nodo que pasó la marca de agua. Las lecturas (búsquedas) seguirán siendo posibles.</p><h2>Cómo prevenir y manejar casos cuando el disco está demasiado lleno (sobreutilización)</h2><p>Existen varios métodos para gestionar casos cuando tu disco de Elasticsearch está demasiado lleno:</p><ol><li><p><strong>Eliminar</strong> <strong>datos antiguos:</strong> Normalmente, los datos no deben conservar indefinidamente. Una forma de evitar y solucionar que el disco esté demasiado lleno es cerciorar de que, cuando los datos alcancen cierta edad, se archiven y eliminen de forma fiable. Una forma de hacerlo es usando <a href="https://www.elastic.co/docs/manage-data/lifecycle/index-lifecycle-management">ILM</a>.</p></li><li><p><strong>Agregar capacidad de almacenamiento:</strong> Si no puedes eliminar los datos, quizá quieras agregar más nodos de datos o aumentar el tamaño de los discos para conservar todos los datos sin afectar negativamente al rendimiento. Si necesitas agregar capacidad de almacenamiento al clúster, deberías considerar si necesitas agregar solo capacidad de almacenamiento, o tanto capacidad de almacenamiento como RAM y recursos de CPU en proporción (ver la sección sobre <a href="https://www.elastic.co/search-labs/blog/optimize-elasticsearch-disk-space-and-usage#the-relationship-between-disk-size,-ram-and-cpu">la proporción entre tamaño de disco, RAM y CPU</a> más abajo).</p></li></ol><h2>Cómo agregar capacidad de almacenamiento a tu clúster de Elasticsearch</h2><ol><li><p><strong>Aumentar el número de nodos de datos: </strong>Recuerda que los nuevos nodos deben tener el mismo tamaño que los nodos existentes y la misma versión de Elasticsearch.</p></li><li><p><strong>Aumentar el tamaño de los nodos existentes: </strong>En entornos basados en la nube, suele ser fácil aumentar el tamaño del disco y la RAM/CPU en los nodos existentes.</p></li><li><p><strong>Aumenta solo el tamaño del disco: </strong>En entornos basados en la nube, a menudo es relativamente fácil aumentar el tamaño del disco.</p></li><li><p><a href="https://www.elastic.co/docs/deploy-manage/tools/snapshot-and-restore"><strong>Instantánea</strong></a><a href="https://www.elastic.co/docs/deploy-manage/tools/snapshot-and-restore"> </a><a href="https://www.elastic.co/docs/deploy-manage/tools/snapshot-and-restore"><strong>y</strong></a><a href="https://www.elastic.co/docs/deploy-manage/tools/snapshot-and-restore"> </a><a href="https://www.elastic.co/docs/deploy-manage/tools/snapshot-and-restore"><strong>restauración</strong></a><strong>:</strong> Si estás dispuesto a permitir que se recuperen datos antiguos a petición en un proceso automatizado desde copias de seguridad, puedes hacer instantáneas de índices antiguos, eliminarlos y restaurar datos temporalmente a petición de las instantáneas. </p></li><li><p><strong>Reducir réplicas por fragmento:</strong> Otra opción para reducir los datos es reducir el número de réplicas de cada fragmento. Para alta disponibilidad, te gustaría tener una réplica por fragmento, pero cuando los datos envejecen, podrías trabajar sin réplicas. Esto normalmente podría funcionar si los datos son persistentes o si tienes una copia de seguridad que restaurar si es necesario.</p></li><li><p><strong>Crea alertas:</strong> Para evitar que los discos se llenen en el futuro y actuar de forma proactiva, deberías crear alertas basadas en el uso del disco que te avisen cuando el disco empiece a llenar. </p></li></ol><h2>Cómo prevenir y gestionar casos en los que la capacidad del disco está infrautilizada</h2><p>Si la capacidad de tu disco está infrautilizada, existen varias opciones para reducir el volumen de almacenamiento en tu clúster.</p><h3>Cómo reducir el volumen de almacenamiento en un clúster de Elasticsearch</h3><p>Existen varios métodos para reducir el volumen de almacenamiento de un clúster.</p><p><strong>1. Reducir el número de nodos de datos</strong></p><p>Si quieres reducir el almacenamiento de datos y también reducir los recursos de RAM y CPU en la misma proporción, esta es la estrategia más sencilla. Desmantelar nodos innecesarios probablemente suponga el mayor ahorro de costos.</p><p>Antes de desactivar el nodo, deberías:</p><ul><li><p>Cerciorar de que el nodo a desmantelar no sea necesario como nodo MAESTRO. Siempre deberías tener al menos tres nodos con el rol de nodo MAESTRO.</p></li><li><p>Migra los fragmentos de datos fuera del nodo para ser desmantelados.</p></li></ul><p><strong>2. Sustituir nodos existentes por nodos más pequeños</strong></p><p>Si no puedes reducir aún más el número de nodos (normalmente 3 sería una configuración mínima), entonces quizá quieras reducir el tamaño de los nodos existentes. Recuerda que es recomendable cerciorar de que todos los nodos de datos tengan la misma memoria RAM y tamaño de disco, ya que los fragmentos se equilibran en función del número de fragmentos por nodo.</p><p>El proceso sería:</p><ul><li><p>Agregar nuevos nodos más pequeños al clúster</p></li><li><p>Migra los fragmentos lejos de los nodos para ser desmantelados</p></li><li><p>Apaga los nodos antiguos</p></li></ul><p><strong>3. Reducir el tamaño del disco en los nodos</strong></p><p>Si SOLO quieres reducir el tamaño del disco en los nodos sin cambiar la RAM o la CPU total del clúster, entonces puedes reducir el tamaño del disco para cada nodo. Reducir el tamaño del disco en un nodo Elasticsearch no es un proceso trivial.</p><p>La forma más sencilla de hacerlo suele ser:</p><ul><li><p>Migrar fragmentos desde el nodo</p></li><li><p>Detener el nodo</p></li><li><p>Montar un nuevo volumen de datos en el nodo con el tamaño adecuado</p></li><li><p>Copiar todos los datos del volumen de disco antiguo al volumen nuevo</p></li><li><p>Desacoplar el antiguo volumen A</p></li><li><p>Nodo inicial y migra fragmentos de vuelta a nodo</p></li></ul><p>Esto requiere que tengas suficiente capacidad en los otros nodos para almacenar temporalmente los fragmentos extra del nodo durante este proceso. En muchos casos, el costo de gestionar este proceso puede superar los posibles ahorros en el uso del disco. Por esta razón, puede ser más sencillo reemplazar el nodo por completo por uno nuevo con el tamaño de disco deseado (ver "Sustituir nodos existentes por nodos más pequeños" arriba).</p><p>Al pagar por recursos innecesarios, el costo obviamente puede reducir optimizando la utilización de los recursos.</p><h2>La relación entre el tamaño del disco, la RAM y la CPU</h2><p>La proporción ideal de capacidad de disco respecto a RAM en tu clúster dependerá de tu caso de uso particular. Por esta razón, al considerar cambios en tu capacidad de almacenamiento, también deberías considerar si las relaciones actuales de disco/RAM/CPU están adecuadamente equilibradas y si, como consecuencia, necesitas agregar o reducir RAM y CPU en la misma proporción.</p><p>Los requisitos de RAM y CPU dependen del volumen de actividad <a href="https://opster.com/guides/elasticsearch/glossary/elasticsearch-indexing/">de indexación</a> , el número y tipo de consultas, y también de la cantidad de datos que se están buscando y agregando. Esto suele ser proporcional a la cantidad de datos almacenados en el clúster y, por tanto, también debe estar relacionado con el tamaño del disco.</p><p>La proporción entre la capacidad del disco y la RAM puede cambiar según el caso de uso. Consulta algunos ejemplos aquí:</p><p></p><p>Actividad en el índice</p><p>Retención</p><p>Actividad de búsqueda</p><p>Capacidad del disco</p><p>CARNERO</p><p>Aplicación de búsqueda empresarial</p><p>Ingestión moderada de logarítmic</p><p>Largo</p><p>Luz</p><p>2TB</p><p>32GB</p><p>Monitorización de aplicaciones</p><p>Ingesta intensiva de troncos</p><p>Corto</p><p>Luz</p><p>1TB</p><p>32GB</p><p>Comercio electrónico</p><p>Indexación de datos de luz</p><p>Indefinido</p><p>Pesado</p><p>500GB</p><p>32GB</p><p><em>Recuerda que modificar la configuración de las máquinas de nodos debe hacer con cuidado, ya que puede implicar tiempo de inactividad de nodos y debes cerciorarte de que los fragmentos no empiecen a migrar a otros nodos ya sobreextendidos.</em></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/optimize-elasticsearch-disk-space-and-usage</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/optimize-elasticsearch-disk-space-and-usage</guid>
    <category><![CDATA[Conceptos básicos]]></category>
    <dc:creator><![CDATA[Kofi Bartlett]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt087c3d95b6cb59c5/6a17dbda445de986f54cffd9/5d41a078dd03e4480a0ff4e9591c8618b9bab4d0-720x420.png" length="0" type="image/png"/>
    <pubDate>Fri, 16 May 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elasticsearch en JavaScript de la manera correcta, parte I]]></title>
    <description><![CDATA[Explicando cómo crear un backend de Elasticsearch listo para producción en JavaScript.  

Explora cómo usar Elasticsearch con JavaScript para crear un servidor con diferentes endpoints de búsqueda para consultar documentos de Elasticsearch siguiendo las mejores prácticas de cliente/servidor.]]></description>
    <content:encoded><![CDATA[<p>Este es el primer artículo de un serial que explica cómo usar Elasticsearch con JavaScript. En este serial, aprenderás lo básico sobre cómo usar Elasticsearch en un entorno JavaScript y revisarás las características y mejores prácticas más relevantes para crear una aplicación de búsqueda. Al final, sabrás todo lo necesario para ejecutar Elasticsearch usando JavaScript.</p><p>En esta primera parte, repasaremos:</p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#environment">Medio ambiente</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#frontend,-backend,-or-serverless?">¿Frontend, backend o serverless?</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#connecting-the-client">Conexión del cliente</a></p></li></ul></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#indexing-documents">Indexación de documentos</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#elasticsearch-client">Cliente Elasticsearch</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#semantic-mappings">Aplicaciones semánticas</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#bulk-helper">Ayudante a granel</a></p></li></ul></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#searching-data">Búsqueda de datos</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#lexical-query-(/search/lexic?q=%3Cquery-term%3E)">Consulta léxica</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#semantic-query-(/search/semantic?q=%3Cquery-term%3E)">Consulta semántica</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#hybrid-query-(/search/hybrid?q=%3Cquery-term%3E)">Consulta híbrida</a></p></li></ul></li></ul><p><em>Puedes consultar el código fuente con los ejemplos </em><a href="https://github.com/Delacrobix/JS-client-best-practices_article"><em><strong>aquí</strong></em></a><em><strong>.</strong></em></p><h3>¿Qué es el cliente de Node.js Elasticsearch?</h3><p>El <a href="https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/index.html">cliente Elasticsearch Node.js</a> es una biblioteca de JavaScript que introduce las llamadas HTTP REST de la API Elasticsearch a JavaScript. Esto facilita la gestión y cuenta con ayudas que simplifican tareas como indexar documentos en lotes.</p><h2>Medio ambiente</h2><h3>¿Frontend, backend o serverless?</h3><p>Para crear nuestra aplicación de búsqueda usando el cliente JavaScript, necesitamos al menos dos componentes: un clúster Elasticsearch y un entorno de ejecución en JavaScript para ejecutar el cliente.</p><p>El cliente JavaScript soporta todas las soluciones Elasticsearch (Cloud, local y Serverless), y no hay diferencias importantes entre ellas ya que el cliente gestiona todas las variaciones internamente, así que no tienes que preocuparte por cuál usar.</p><p>Sin embargo, el tiempo de ejecución de JavaScript debe ejecutar desde el <strong>servidor</strong> y <strong>no directamente desde el navegador.</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd3ec469c83e3a71a/6a17e3d5445de91da44d00b6/92ce6cfd923c8008fa44f617a58193642d9d5879-661x410.png" alt="Elasticsearch en el entorno JavaScript." /><p>Esto se debe a que, al llamar a Elasticsearch desde el navegador, el usuario puede obtener información sensible como la clave de la API del clúster, el host o la propia consulta. Elasticsearch recomienda <strong>no exponer nunca el clúster directamente a Internet </strong>y usar una capa intermedia que abstraiga toda esta información para que el usuario solo pueda ver los parámetros. Puedes leer más sobre <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/es-security-principles.html#security-protect-cluster-traffic">este tema aquí</a>.</p><p>Sugerimos usar un esquema como este:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4d7f215f2e70230a/6a17e3d6fbc5f83de6491a13/a08769f08ec73fe57bf2e961cfdfbb1cdd57919d-972x429.png" alt="Configuración del cliente de Elasticsearch Node.js." /><p>En este caso, el cliente solo envía los términos de búsqueda y una clave de autenticación para tu servidor mientras este tiene el control total de la consulta y la comunicación con Elasticsearch.</p><h3>Conexión del cliente</h3><p>Empieza creando una clave API siguiendo <a href="https://www.elastic.co/search-labs/tutorials/install-elasticsearch/elastic-cloud">estos pasos</a>.</p><p>Siguiendo el ejemplo anterior, crearemos un servidor Express sencillo y nos conectaremos a él usando un cliente de un servidor Node.JS.</p><p>Inicializaremos el proyecto con NPM e instalaremos el cliente Elasticsearch y <a href="https://expressjs.com/">Express.</a> Esta última es una biblioteca para abrir servidores en Node.js. Usando Express, podemos interactuar con nuestro backend vía HTTP.</p><p>Inicialemos el proyecto:</p><p><code>npm init -y</code></p><p>Dependencias de instalación:</p><p><code>npm install @elastic/elasticsearch express split2 dotenv</code></p><p>Déjame explicártelo:</p><ul><li><p><a href="https://www.npmjs.com/package/@elastic/elasticsearch"><em><strong>@elastic/elasticsearch</strong></em></a>: Es el cliente oficial de Node.js</p></li><li><p><a href="https://www.npmjs.com/package/express"><em><strong>express</strong></em></a>: Nos permitirá montar un servidor nodejs ligero para exponer Elasticsearch</p></li><li><p><a href="https://www.npmjs.com/package/split2"><em><strong>split2</strong></em></a>: Divide líneas de texto en un flujo. Útil para procesar nuestros archivos de ndjson línea a línea</p></li><li><p><a href="https://www.npmjs.com/package/dotenv"><em><strong>dotenv</strong></em></a>: Permítenos gestionar variables de entorno usando un .env archivo</p></li></ul><p>Crea un .env archiva en la raíz del proyecto y agrega las siguientes líneas:</p>ELASTICSEARCH_ENDPOINT="Your Elasticsearch endpoint"
ELASTICSEARCH_API_KEY="Your Elasticssearch API"<p>De esta manera, podemos importar esas variables usando el paquete <code>dotenv</code> .</p><p>Crea un archivo <code>server.js</code> :</p>const express = require("express");
const bodyParser = require("body-parser");
const { Client } = require("@elastic/elasticsearch");
 
require("dotenv").config(); //environment variables setup

const ELASTICSEARCH_ENDPOINT = process.env.ELASTICSEARCH_ENDPOINT;
const ELASTICSEARCH_API_KEY = process.env.ELASTICSEARCH_API_KEY;
const PORT = 3000;


const app = express();

app.listen(PORT, () =&gt; {
  console.log("Server running on port", PORT);
});
app.use(bodyParser.json());


let esClient = new Client({
  node: ELASTICSEARCH_ENDPOINT,
  auth: { apiKey: ELASTICSEARCH_API_KEY },  
});

app.get("/ping", async (req, res) =&gt; {
  try {
    const result = await esClient.info();

    res.status(200).json({
      success: true,
      clusterInfo: result,
    });
  } catch (error) {
    console.error("Error getting Elasticsearch info:", error);

    res.status(500).json({
      success: false,
      clusterInfo: null,
      error: error.message,
    });
  }
});<p>Este código configura un servidor de Express.js básico que escucha en el puerto 3000 y se conecta a un clúster Elasticsearch usando una clave API para autenticación. Incluye un punto final /ping que, al acceder mediante una solicitud GET, consulta al clúster de Elasticsearch información básica empleando el método <code>.info()</code> del cliente Elasticsearch. </p><p>Si la consulta tiene éxito, devuelve la información del clúster en formato JSON; de lo contrario, devuelve un mensaje de error. El servidor también emplea middleware de parser corporal para gestionar los cuerpos de las solicitudes JSON.</p><p>Ejecuta el archivo para abrir el servidor:</p><p><code>node server.js</code></p><p>La respuesta debería ser la siguiente:</p>Server running on port 3000<p>Y ahora, consultemos el <code>/ping</code> endpoint para comprobar el estado de nuestro clúster de Elasticsearch.</p>curl http://localhost:3000/ping
{
    "success": true,
    "clusterInfo": {
        "name": "instance-0000000000",
        "cluster_name": "61b7e19eec204d59855f5e019acd2689",
        "cluster_uuid": "BIfvfLM0RJWRK_bDCY5ldg",
        "version": {
            "number": "9.0.0",
            "build_flavor": "default",
            "build_type": "docker",
            "build_hash": "112859b85d50de2a7e63f73c8fc70b99eea24291",
            "build_date": "2025-04-08T15:13:46.049795831Z",
            "build_snapshot": false,
            "lucene_version": "10.1.0",
            "minimum_wire_compatibility_version": "8.18.0",
            "minimum_index_compatibility_version": "8.0.0"
        },
        "tagline": "You Know, for Search"
    }
}<h2>Indexación de documentos</h2><p>Una vez conectados, podemos indexar documentos usando mapeos como <a href="https://www.elastic.co/search-labs/blog/semantic-search-simplified-semantic-text">semantic_text</a> para búsqueda semántica y texto para consultas de texto completo. Con estos dos tipos de campos, también podemos hacer <a href="https://www.elastic.co/what-is/hybrid-search">búsqueda híbrida</a>.</p><p>Crearemos un nuevo archivo <code>load.js</code> para generar los mapeos y subir los documentos.</p><h3>Cliente Elasticsearch</h3><p>Primero necesitamos instanciar y autenticar al cliente:</p>const { Client } = require("@elastic/elasticsearch");

const ELASTICSEARCH_ENDPOINT = "cluster/project_endpoint";
const ELASTICSEARCH_API_KEY = "apiKey";

const esClient = new Client({
  node: ELASTICSEARCH_ENDPOINT,
  auth: { apiKey: ELASTICSEARCH_API_KEY },
});<h3>Aplicaciones semánticas</h3><p>Crearemos un índice con datos sobre un hospital veterinario. Almacenaremos la información del dueño, la mascota y los detalles de la visita.</p><p>Los datos sobre los que queremos realizar la búsqueda en texto completo, como nombres y descripciones, se almacenarán como texto. Los datos de categorías, como la especie o raza del animal, se almacenarán como palabras clave.</p><p>Además, copiaremos los valores de todos los campos en un campo semantic_text para poder ejecutar una búsqueda semántica también con esa información.</p>const INDEX_NAME = "vet-visits";

const createMappings = async (indexName, mapping) =&gt; {
  try {
    const body = await esClient.indices.create({
      index: indexName,
      body: {
        mappings: mapping,
      },
    });

    console.log("Index created successfully:", body);
  } catch (error) {
    console.error("Error creating mapping:", error);
  }
};

await createMappings(INDEX_NAME, {
  properties: {
    owner_name: {
      type: "text",
      copy_to: "semantic_field",
    },
    pet_name: {
      type: "text",
      copy_to: "semantic_field",
    },
    species: {
      type: "keyword",
      copy_to: "semantic_field",
    },
    breed: {
      type: "keyword",
      copy_to: "semantic_field",
    },
    vaccination_history: {
      type: "keyword",
      copy_to: "semantic_field",
    },
    visit_details: {
      type: "text",
      copy_to: "semantic_field",
    },
    semantic_field: {
      type: "semantic_text",
    },
  },
});<h3>Ayudante a granel</h3><p>Otro beneficio del cliente es que podemos usar el <a href="https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/client-helpers.html#bulk-helper">helper de mayor</a> volumen para indexar en lotes. El helper en bulk nos permite gestionar fácilmente cosas como la concurrencia, los intentos y qué hacer con cada documento que pasa por la función y que tiene éxito o fracasa.</p><p>Una característica atractiva de este asistente es que puedes trabajar con streams. Esta función te permite enviar un archivo línea por línea en lugar de almacenar el archivo completo en la memoria y enviarlo a Elasticsearch de una sola vez.</p><p>Para subir los datos a Elasticsearch, crea un archivo llamado data.ndjson en la raíz del proyecto y agrega la información que aparece a continuación (alternativamente, puedes descargar el archivo con el conjunto de datos <a href="https://github.com/Delacrobix/JS-client-best-practices_article/blob/main/data.ndjson">desde aquí</a>):</p>{"owner_name":"Alice Johnson","pet_name":"Buddy","species":"Dog","breed":"Golden Retriever","vaccination_history":["Rabies","Parvovirus","Distemper"],"visit_details":"Annual check-up and nail trimming. Healthy and active."}
{"owner_name":"Marco Rivera","pet_name":"Milo","species":"Cat","breed":"Siamese","vaccination_history":["Rabies","Feline Leukemia"],"visit_details":"Slight eye irritation, prescribed eye drops."}
{"owner_name":"Sandra Lee","pet_name":"Pickles","species":"Guinea Pig","breed":"Mixed","vaccination_history":[],"visit_details":"Loss of appetite, recommended dietary changes."}
{"owner_name":"Jake Thompson","pet_name":"Luna","species":"Dog","breed":"Labrador Mix","vaccination_history":["Rabies","Bordetella"],"visit_details":"Mild ear infection, cleaning and antibiotics given."}
{"owner_name":"Emily Chen","pet_name":"Ziggy","species":"Cat","breed":"Mixed","vaccination_history":["Rabies","Feline Calicivirus"],"visit_details":"Vaccination update and routine physical."}
{"owner_name":"Tomás Herrera","pet_name":"Rex","species":"Dog","breed":"German Shepherd","vaccination_history":["Rabies","Parvovirus","Leptospirosis"],"visit_details":"Follow-up for previous leg strain, improving well."}
{"owner_name":"Nina Park","pet_name":"Coco","species":"Ferret","breed":"Mixed","vaccination_history":["Rabies"],"visit_details":"Slight weight loss; advised new diet."}
{"owner_name":"Leo Martínez","pet_name":"Simba","species":"Cat","breed":"Maine Coon","vaccination_history":["Rabies","Feline Panleukopenia"],"visit_details":"Dental cleaning. Minor tartar buildup removed."}
{"owner_name":"Rachel Green","pet_name":"Rocky","species":"Dog","breed":"Bulldog Mix","vaccination_history":["Rabies","Parvovirus"],"visit_details":"Skin rash, antihistamines prescribed."}
{"owner_name":"Daniel Kim","pet_name":"Mochi","species":"Rabbit","breed":"Mixed","vaccination_history":[],"visit_details":"Nail trimming and general health check. No issues."}<p>Usamos split2 para transmitir las líneas de archivo mientras el asistente masivo las envía a Elasticsearch.</p>const { createReadStream } = require("fs");
const split = require("split2");
 
const indexData = async (filePath, indexName) =&gt; {
  try {
    console.log(`Indexing data from ${filePath} into ${indexName}...`);

    const result = await esClient.helpers.bulk({
      datasource: createReadStream(filePath).pipe(split()),

      onDocument: () =&gt; {
        return {
          index: { _index: indexName },
        };
      },
      onDrop(doc) {
        console.error("Error processing document:", doc);
      },
    });

    console.log("Bulk indexing successful elements:", result.items.length);
  } catch (error) {
    console.error("Error indexing data:", error);
    throw error;
  }
};

await indexData("./data.ndjson", INDEX_NAME);<p>El código anterior dice un .ndjson archivo línea por línea y en volumen indexa cada objeto JSON en un índice Elasticsearch especificado usando el método <code>helpers.bulk</code> . Transmite el archivo usando <code>createReadStream</code> y <code>split2</code>, establece metadatos de indexación para cada documento y registra cualquier documento que no se procese. Una vez completado, registra el número de elementos indexados con éxito.</p><p>Alternativamente a la función <code>indexData</code> , puedes subir el archivo directamente a través de la interfaz usando Kibana y usar la <a href="https://www.elastic.co/docs/manage-data/ingest/upload-data-files">interfaz de archivos de datos de subida.</a></p><p>Ejecutamos el archivo para subir los documentos a nuestro clúster de Elasticsearch.</p><p><code>node load.js</code></p>Creating mappings for index vet-visits...
Index created successfully: { acknowledged: true, shards_acknowledged: true, index: 'vet-visits' }
Indexing data from ./data.ndjson into vet-visits...
Bulk indexing completed. Total documents: 10, Failed: 0<h2>Búsqueda de datos en Elasticsearch</h2><p>Volviendo a nuestro archivo <code>server.js</code> , crearemos diferentes endpoints para realizar búsquedas léxicas, semánticas o híbridas.</p><p>En resumen, este tipo de búsquedas no son mutuamente excluyentes, sino que dependerán del tipo de pregunta que necesites responder.</p><p>Tipo de consulta</p><p>Caso de uso</p><p>Pregunta de ejemplo</p><p>Consulta léxica</p><p>Las palabras o raíces de palabras en la pregunta probablemente aparecerán en los documentos del índice. Similitud de token entre la pregunta y los documentos.</p><p>Busco una camiseta deportiva azul.</p><p>Consulta semántica</p><p>Las palabras de la pregunta probablemente no aparecerán en los documentos. Similitud conceptual entre la pregunta y los documentos.</p><p>Busco ropa para el frío.</p><p>Búsqueda híbrida</p><p>La pregunta contiene componentes léxicos y/o semánticos. Similitud de tokens y semántica entre la pregunta y los documentos.</p><p>Estoy buscando un vestido talla S para una boda en la playa.</p><p>Las partes <em><strong>léxicas </strong></em>de la pregunta probablemente formarán parte de títulos y descripciones, o nombres de categorías, mientras que las partes <em><strong>semánticas </strong></em>son conceptos relacionados con esos campos. <em><strong>El azul</strong></em> probablemente será un nombre de categoría o parte de una descripción, y <em><strong>la boda en la playa</strong></em> probablemente no lo sea, pero puede estar semánticamente relacionada con la ropa de lino.</p><h3>Consulta léxica (/search/lexic?q=&lt;query_term&gt;)</h3><p>La búsqueda léxica, también llamada búsqueda de texto completo, significa búsqueda basada en la similitud de los tokens; es decir, tras un análisis, se devolverán los documentos que incluyan los tokens en la búsqueda.</p><p>Puedes consultar nuestro tutorial práctico de búsqueda <a href="https://www.elastic.co/demo-gallery/lexical-search">léxica aquí</a>.</p>app.get("/search/lexic", async (req, res) =&gt; {
  const { q } = req.query;

  const INDEX_NAME = "vet-visits";

  try {
    const result = await esClient.search({
      index: INDEX_NAME,
      size: 5,
      body: {
        query: {
          multi_match: {
            query: q,
            fields: ["owner_name", "pet_name", "visit_details"],
          },
        },
      },
    });

    res.status(200).json({
      success: true,
      results: result.hits.hits
    });
  } catch (error) {
    console.error("Error performing search:", error);

    res.status(500).json({
      success: false,
      results: null,
      error: error.message,
    });
  }
});<p>Probamos con: <em><strong>corte de uñas</strong></em></p>curl http://localhost:3000/search/lexic?q=nail%20trimming<p>Respuesta:</p>{
    "success": true,
    "results": [
        {
            "_index": "vet-visits",
            "_id": "-RY6RJYBLe2GoFQ6-9n9",
            "_score": 2.7075968,
            "_source": {
                "pet_name": "Mochi",
                "owner_name": "Daniel Kim",
                "species": "Rabbit",
                "visit_details": "Nail trimming and general health check. No issues.",
                "breed": "Mixed",
                "vaccination_history": []
            }
        },
        {
            "_index": "vet-visits",
            "_id": "8BY6RJYBLe2GoFQ6-9n9",
            "_score": 2.560356,
            "_source": {
                "pet_name": "Buddy",
                "owner_name": "Alice Johnson",
                "species": "Dog",
                "visit_details": "Annual check-up and nail trimming. Healthy and active.",
                "breed": "Golden Retriever",
                "vaccination_history": [
                    "Rabies",
                    "Parvovirus",
                    "Distemper"
                ]
            }
        }
    ]
}<h3>Consulta semántica (/search/semantic?q=&lt;query_term&gt;)</h3><p>La búsqueda semántica, a diferencia de la búsqueda léxica, encuentra resultados similares al significado de los términos de búsqueda mediante la búsqueda vectorial.</p><p>Puedes consultar nuestro tutorial práctico de búsqueda <a href="https://www.elastic.co/demo-gallery/semantic-search">semántica aquí</a>.</p>app.get("/search/semantic", async (req, res) =&gt; {
  const { q } = req.query;

  const INDEX_NAME = "vet-visits";

  try {
    const result = await esClient.search({
      index: INDEX_NAME,
      size: 5,
      body: {
        query: {
          semantic: {
            field: "semantic_field",
            query: q
          },
        },
      },
    });

    res.status(200).json({
      success: true,
      results: result.hits.hits,
    });
  } catch (error) {
    console.error("Error performing search:", error);

    res.status(500).json({
      success: false,
      results: null,
      error: error.message,
    });
  }
});<p>Hacemos la prueba con: <em><strong>¿Quién se hizo una pedicura?</strong></em></p>curl http://localhost:3000/search/semantic?q=Who%20got%20a%20pedicure?<p>Respuesta:</p>{
    "success": true,
    "results": [
        {
            "_index": "vet-visits",
            "_id": "-RY6RJYBLe2GoFQ6-9n9",
            "_score": 4.861466,
            "_source": {
                "owner_name": "Daniel Kim",
                "pet_name": "Mochi",
                "species": "Rabbit",
                "breed": "Mixed",
                "vaccination_history": [],
                "visit_details": "Nail trimming and general health check. No issues."
            }
        },
        {
            "_index": "vet-visits",
            "_id": "8BY6RJYBLe2GoFQ6-9n9",
            "_score": 4.7152824,
            "_source": {
                "pet_name": "Buddy",
                "owner_name": "Alice Johnson",
                "species": "Dog",
                "visit_details": "Annual check-up and nail trimming. Healthy and active.",
                "breed": "Golden Retriever",
                "vaccination_history": [
                    "Rabies",
                    "Parvovirus",
                    "Distemper"
                ]
            }
        },
        {
            "_index": "vet-visits",
            "_id": "9RY6RJYBLe2GoFQ6-9n9",
            "_score": 1.6717153,
            "_source": {
                "pet_name": "Rex",
                "owner_name": "Tomás Herrera",
                "species": "Dog",
                "visit_details": "Follow-up for previous leg strain, improving well.",
                "breed": "German Shepherd",
                "vaccination_history": [
                    "Rabies",
                    "Parvovirus",
                    "Leptospirosis"
                ]
            }
        },
        {
            "_index": "vet-visits",
            "_id": "9xY6RJYBLe2GoFQ6-9n9",
            "_score": 1.5600781,
            "_source": {
                "pet_name": "Simba",
                "owner_name": "Leo Martínez",
                "species": "Cat",
                "visit_details": "Dental cleaning. Minor tartar buildup removed.",
                "breed": "Maine Coon",
                "vaccination_history": [
                    "Rabies",
                    "Feline Panleukopenia"
                ]
            }
        },
        {
            "_index": "vet-visits",
            "_id": "-BY6RJYBLe2GoFQ6-9n9",
            "_score": 1.2696637,
            "_source": {
                "pet_name": "Rocky",
                "owner_name": "Rachel Green",
                "species": "Dog",
                "visit_details": "Skin rash, antihistamines prescribed.",
                "breed": "Bulldog Mix",
                "vaccination_history": [
                    "Rabies",
                    "Parvovirus"
                ]
            }
        }
    ]
}<h3>Consulta híbrida (/search/hybrid?q=&lt;query_term&gt;)</h3><p>La búsqueda híbrida nos permite combinar la búsqueda semántica y léxica, obteniendo así lo mejor de ambos mundos: se obtiene la precisión de buscar por token, junto con la proximidad de significado de la búsqueda semántica.</p>app.get("/search/hybrid", async (req, res) =&gt; {
  const { q } = req.query;

  const INDEX_NAME = "vet-visits";

  try {
    const result = await esClient.search({
      index: INDEX_NAME,
      body: {
        retriever: {
          rrf: {
            retrievers: [
              {
                standard: {
                  query: {
                    bool: {
                      must: {
                         multi_match: {
             query: q,
            fields: ["owner_name", "pet_name", "visit_details"],
          },
                      },
                    },
                  },
                },
              },
              {
                standard: {
                  query: {
                    bool: {
                      must: {
                        semantic: {
                          field: "semantic_field",
                          query: q,
                        },
                      },
                    },
                  },
                },
              },
            ],
          },
        },
        size: 5,
      },
    });

    res.status(200).json({
      success: true,
      results: result.hits.hits,
    });
  } catch (error) {
    console.error("Error performing search:", error);

    res.status(500).json({
      success: false,
      results: null,
      error: error.message,
    });
  }
});<p>Hacemos pruebas con "<em><strong>¿Quién se hizo pedicura o tratamiento dental?"</strong></em></p>curl http://localhost:3000/search/hybrid?q=who%20got%20a%20pedicure%20or%20dental%20treatment<p>Respuesta:</p>{
    "success": true,
    "results": [
        {
            "_index": "vet-visits",
            "_id": "9xY6RJYBLe2GoFQ6-9n9",
            "_score": 0.032522473,
            "_source": {
                "pet_name": "Simba",
                "owner_name": "Leo Martínez",
                "species": "Cat",
                "visit_details": "Dental cleaning. Minor tartar buildup removed.",
                "breed": "Maine Coon",
                "vaccination_history": [
                    "Rabies",
                    "Feline Panleukopenia"
                ]
            }
        },
        {
            "_index": "vet-visits",
            "_id": "-RY6RJYBLe2GoFQ6-9n9",
            "_score": 0.016393442,
            "_source": {
                "pet_name": "Mochi",
                "owner_name": "Daniel Kim",
                "species": "Rabbit",
                "visit_details": "Nail trimming and general health check. No issues.",
                "breed": "Mixed",
                "vaccination_history": []
            }
        },
        {
            "_index": "vet-visits",
            "_id": "8BY6RJYBLe2GoFQ6-9n9",
            "_score": 0.015873017,
            "_source": {
                "pet_name": "Buddy",
                "owner_name": "Alice Johnson",
                "species": "Dog",
                "visit_details": "Annual check-up and nail trimming. Healthy and active.",
                "breed": "Golden Retriever",
                "vaccination_history": [
                    "Rabies",
                    "Parvovirus",
                    "Distemper"
                ]
            }
        },
        {
            "_index": "vet-visits",
            "_id": "9RY6RJYBLe2GoFQ6-9n9",
            "_score": 0.015625,
            "_source": {
                "pet_name": "Rex",
                "owner_name": "Tomás Herrera",
                "species": "Dog",
                "visit_details": "Follow-up for previous leg strain, improving well.",
                "breed": "German Shepherd",
                "vaccination_history": [
                    "Rabies",
                    "Parvovirus",
                    "Leptospirosis"
                ]
            }
        },
        {
            "_index": "vet-visits",
            "_id": "8xY6RJYBLe2GoFQ6-9n9",
            "_score": 0.015384615,
            "_source": {
                "pet_name": "Luna",
                "owner_name": "Jake Thompson",
                "species": "Dog",
                "visit_details": "Mild ear infection, cleaning and antibiotics given.",
                "breed": "Labrador Mix",
                "vaccination_history": [
                    "Rabies",
                    "Bordetella"
                ]
            }
        }
    ]
}<h2>Conclusión</h2><p>En esta primera parte de nuestro serial, explicamos cómo configurar nuestro entorno y crear un servidor con diferentes endpoints de búsqueda para consultar los documentos de Elasticsearch siguiendo las mejores prácticas cliente/servidor. Consulta <a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i">la segunda parte</a> de nuestro serial, en la que aprenderás las mejores prácticas de producción y cómo ejecutar el cliente de Node.js Elasticsearch en entornos serverless.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i</guid>
    <category><![CDATA[Javascript]]></category>
    <category><![CDATA[Conceptos básicos]]></category>
    <dc:creator><![CDATA[Jeffrey Rengifo]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt16d00c8a548b32e8/6a17e3d8fbc5f8c740491a19/72200540ed258779d87e53a72ea189f8a138540c-1600x901.png" length="0" type="image/png"/>
    <pubDate>Thu, 15 May 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Cómo configurar el número de réplicas en un índice de Elasticsearch]]></title>
    <description><![CDATA[Aprende a configurar el parámetro number_of_replicas en un índice de Elasticsearch para mejorar el rendimiento en las búsquedas y ofrecer resistencia ante fallos de nodos. 
]]></description>
    <content:encoded><![CDATA[<p>Elasticsearch está diseñado para ser un sistema distribuido que puede manejar una gran cantidad de datos y ofrecer una alta disponibilidad. Una de las características clave que permite esto es el concepto de replicación de índice, que está regulado por la configuración <code>number_of_replicas</code> . Este artículo profundizará en los detalles de este escenario, sus participaciones y cómo configurarlo correctamente.</p><h2>El papel de las réplicas en Elasticsearch</h2><p>En Elasticsearch, un índice es una colección de documentos que se dividen en múltiples fragmentos primarios. Cada fragmento primario es un índice Apache Lucene autosuficiente, y los documentos dentro de un índice se distribuyen entre todos los fragmentos primarios. Para garantizar una alta disponibilidad y redundancia de datos, Elasticsearch permite que cada fragmento tenga una o más copias, conocidas como réplicas.

La configuración <code>number_of_replicas</code> controla el número de fragmentos réplica (copias) que Elasticsearch crea para cada fragmento principal en un índice. Por defecto, Elasticsearch crea una réplica para cada shard primario, pero esto puede cambiar según los requisitos de tu sistema.</p><h2>Configuración de la number_of_replicas</h2><p>La configuración de <code>number_of_replicas</code> puede configurar en el momento de la creación del índice o actualizar más adelante. Así es como puedes configurarlo durante la creación del índice:</p>PUT /my_index
{
  "settings": {
    "number_of_replicas": 2
  }
}<p>En este ejemplo, Elasticsearch creará dos réplicas para cada fragmento primario en el índice de <code>my_index</code> .</p><p>Para actualizar la configuración de <code>number_of_replicas</code> de un índice existente, puedes usar la API <code>_settings</code> :</p>PUT /my_index/_settings
{
  "number_of_replicas": 3
}<p>Este comando actualizará el índice de <code>my_index</code> para tener tres réplicas por cada fragmento primario.</p><h2>Participaciones del entorno number_of_replicas</h2><p>La configuración <code>number_of_replicas</code> tiene un impacto significativo en el rendimiento y la resiliencia de tu <a href="https://opster.com/guides/elasticsearch/glossary/elasticsearch-cluster/">clúster</a> de Elasticsearch. Aquí tienes algunos puntos clave a tener en cuenta:</p><ol><li><p><strong>Redundancia y disponibilidad de datos:</strong> Aumentar la <code>number_of_replicas</code> mejora la disponibilidad de tus datos creando más copias de cada fragmento. Si un nodo falla, Elasticsearch aún puede servir datos de los fragmentos réplica en los <a href="https://opster.com/guides/elasticsearch/glossary/elasticsearch-node/">nodos</a> restantes.</p></li><li><p><strong>Rendimiento en la búsqueda:</strong> Los fragmentos réplica pueden atender solicitudes de lectura, por lo que tener más réplicas puede mejorar el rendimiento de búsqueda al distribuir la carga entre más fragmentos.</p></li><li><p><strong>Escribe la interpretación:</strong> Sin embargo, cada operación de escritura debe realizar en cada copia de un fragmento. Por lo tanto, un <code>number_of_replicas</code> mayor puede ralentizar el rendimiento <a href="https://opster.com/guides/elasticsearch/glossary/elasticsearch-indexing/">de la indexación</a> , ya que aumenta el número de operaciones que deben realizar por cada escritura.</p></li><li><p><strong>Requisitos de almacenamiento:</strong> Más réplicas significan más espacio de almacenamiento. Debes cerciorarte de que tu clúster tenga suficiente capacidad para almacenar las réplicas adicionales.</p></li><li><p><strong>Resiliencia ante el fallo de nodos:</strong> El <code>number_of_replicas</code> debería establecer teniendo en cuenta el número de nodos en tu clúster. Si el <code>number_of_replicas</code> es igual o mayor que el número de nodos, tu clúster puede tolerar el fallo de varios nodos sin pérdida de datos.</p></li></ol><h2>Mejores prácticas para establecer number_of_replicas</h2><p>La configuración óptima de <code>number_of_replicas</code> depende de los requisitos específicos de tu sistema. Sin embargo, aquí tienes algunas buenas prácticas generales:</p><ul><li><p>Para un clúster de un solo nodo, <code>number_of_replicas</code> debe estar en 0, ya que no hay otros nodos que almacenen réplicas.</p></li><li><p>Para un clúster multinodo, <code>number_of_replicas</code> debe estar configurado al menos en 1 para garantizar redundancia de datos y alta disponibilidad.</p></li><li><p>Si el rendimiento en las búsquedas es una prioridad, considera aumentar la <code>number_of_replicas</code>. Sin embargo, ten en cuenta el equilibrio entre el rendimiento de escritura y los requisitos de almacenamiento.</p></li><li><p>Cerciórate siempre de que tu clúster tenga suficiente capacidad para almacenar las réplicas adicionales.</p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-index-number-of_replicas</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-index-number-of_replicas</guid>
    <category><![CDATA[Conceptos básicos]]></category>
    <dc:creator><![CDATA[Kofi Bartlett]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd041e871a8935448/6a17de320b0bedf404dd34ab/23b96aaa1a38b1f4747b4a87695d816f24c0cf70-720x421.jpg" length="0" type="image/jpeg"/>
    <pubDate>Wed, 14 May 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Eliminar un campo de un documento en Elasticsearch]]></title>
    <description><![CDATA[Aprende a eliminar campos de los documentos de Elasticsearch mediante la API de actualización, scripts o reindexación para eliminaciones individuales y masivas.]]></description>
    <content:encoded><![CDATA[<p>En Elasticsearch, es un requisito común eliminar un campo de un documento. Esto puede ser útil cuando quieres eliminar información innecesaria o desactualizada de tu índice. En este artículo, discutiremos diferentes métodos para eliminar un campo de un documento en Elasticsearch, junto con ejemplos e instrucciones paso a paso. </p><h2>Método 1: Uso de la API de actualización</h2><p>La <a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/update-document">API de actualización</a> te permite actualizar un documento mediante un script que modifica el código fuente del documento. Puedes usar esta API para eliminar un campo de un documento al configurarlo como nulo. Aquí tienes una guía paso a paso sobre cómo hacerlo:</p><p>1. Identifica el índice, el tipo de documento (si se emplea Elasticsearch 6.x o anterior) y el ID del documento que se desea actualizar.</p><p>2. Usar la API Update con un script que ponga el campo en null, o mejor aún, que lo elimine del documento fuente. El siguiente ejemplo demuestra cómo eliminar el campo "field_to_delete" de un documento con ID "1" en el índice "my_index":</p>POST /my_index/_update/1
{
  "script": "ctx._source.remove('field_to_delete')"
}<p>3. Ejecutar la solicitud. Si tiene éxito, Elasticsearch devolverá una respuesta indicando que el documento fue actualizado.</p><p>Nota: Este método solo elimina el campo del documento especificado. El campo seguirá existiendo en el mapeo y en otros documentos del índice.</p><h2>Método 2: Reindexación con una fuente modificada</h2><p>Si deseas eliminar un campo de todos los documentos de una indexación, puedes usar la <a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-reindex">API de reindexación</a> para crear una indexación nueva con la fuente modificada. Aquí te explicamos cómo hacerlo:</p><p>1. Crear un nuevo índice con los mismos ajustes y asignaciones que el índice original. Puedes usar la API Get Index para recuperar la configuración y mapeo del índice original.</p><p>2. Emplear la API Reindex para copiar documentos del índice original al nuevo índice, eliminando el campo del código fuente. El siguiente ejemplo demuestra cómo eliminar el campo "field_to_delete" de todos los documentos en el índice "my_index":</p>POST /_reindex
{
  "source": {
    "index": "my_index"
  },
  "dest": {
    "index": "new_index"
  },
  "script": {
    "source": "ctx._source.remove('field_to_delete')"
  }
}<p>
3. Verificar que el nuevo índice contiene los documentos correctos con el campo eliminado.</p><p>4. Si todo parece bien, puedes eliminar el índice original y, si es necesario, agregar un alias al nuevo índice con el nombre del índice original.</p><h2>Método 3: Actualización del mapping y la reindexación</h2><p>Si quieres eliminar un campo del mapeo y todos los documentos de un índice, puedes actualizar el mapeo y luego volver a indexar los documentos. Así es como se hace:</p><p>1. Crear un nuevo índice con la misma configuración que el índice original.</p><p>2. Recuperar los mapeos del índice original usando la API Get Mapping.</p><p>3. Modifica los mapeos eliminando el campo que quieres eliminar.</p><p>4. Aplicar los mapeos modificados al nuevo índice usando la API de Put Maping.</p><p>5. Emplear la API Reindex para copiar documentos del índice original al nuevo índice, como se describe en el Método 2.</p><p>6. Verificar que el nuevo índice contiene los documentos correctos sin eliminar el campo y que el campo no esté presente en el mapeo.</p><p>7. Si todo se ve bien, puedes eliminar la indexación original y, si es necesario, agregar un alias a la indexación nueva con el nombre de la original.</p><h2>Conclusión</h2><p>En este artículo, discutimos tres métodos para eliminar un campo de un documento en Elasticsearch: usar la API Update, reindexar con un código fuente modificado y actualizar el mapeo y el reindexado. Cada método tiene sus propios casos de uso y compromisos, así que elige el que mejor se adapte a tus necesidades. Recuerda siempre probar tus cambios y verificar los resultados antes de aplicarlos a entornos de producción.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-delete-field-from-document</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-delete-field-from-document</guid>
    <category><![CDATA[Conceptos básicos]]></category>
    <dc:creator><![CDATA[Kofi Bartlett]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8deb617c89943b69/6a17e26c4b055d209e43212f/89278eb7309b7f3018c61be2b514d1fd25b9564d-720x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Fri, 09 May 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Cómo unir dos índices en Elasticsearch]]></title>
    <description><![CDATA[Explicando cómo usar los términos query, Logstash elasticsearch filter, el procesador enrich y ES|QL para unir dos índices en Elasticsearch.]]></description>
    <content:encoded><![CDATA[<p>En Elasticsearch, unir dos índices no es tan sencillo como en las bases de datos relacionales SQL tradicionales. Sin embargo, es posible lograr resultados similares empleando ciertas técnicas y características proporcionadas por Elasticsearch.</p><p>Históricamente, muchas personas usaban el<a href="https://www.elastic.co/es/docs/reference/elasticsearch/mapping-reference/nested"> tipo de campo</a> <a href="https://www.elastic.co/es/docs/reference/elasticsearch/mapping-reference/nested"><code>nested</code></a>como un mecanismo para unir diferentes índices. Sin embargo, fue limitado debido a consultas costosas y soporte incompleto en Kibana, específicamente visualizaciones de Lens.</p><p>Este artículo profundizará en el proceso de unir dos índices en Elasticsearch, centrar en los siguientes enfoques: </p><ol><li><p>Uso de la consulta <code>terms</code></p></li><li><p>Uso del procesador <code>enrich</code> en canalizaciones de ingesta</p></li><li><p>Complemento de filtro <code>elasticsearch</code> Logstash</p></li><li><p>ES|QL <code>ENRICH</code></p></li><li><p>ES|QL <code>LOOKUP JOIN</code></p></li></ol><h2>Uso de la consulta de términos</h2><p>La <a href="https://www.elastic.co/es/docs/reference/query-languages/query-dsl/query-dsl-terms-query">consulta de términos</a> es una de las formas más efectivas de unir dos índices en Elasticsearch. Esta consulta se emplea para recuperar documentos que contienen uno o más términos exactos en un campo específico. Aquí discutimos cómo usarlo para unir dos índices.</p><p>En primer lugar, debe recuperar los datos necesarios del primer índice. Esto se puede hacer usando una simple solicitud GET y extrayendo los valores del atributo <code>_source</code> .</p># Simple GET request
GET first_index/_search<p>Una vez que tenga los datos del primer índice, puede usarlos para consultar el segundo índice. Esto se hace mediante la consulta <code>terms</code> , donde se especifica el campo y los valores que desea que coincidan.</p><p>Aquí hay un ejemplo:</p>GET second_index/_search
{
  "query": {
    "terms": {
      "field_in_second_index": ["value1_from_first_index", "value2_from_first_index"]
    }
  }
}<p>
En este ejemplo, <code>field_in_second_index</code> es el campo del segundo índice que desea hacer coincidir con los valores del primer índice. <code>value1_from_first_index</code> y <code>value2_from_first_index</code> son los valores del primer índice que desea que coincidan en el segundo índice.</p><p>La consulta de términos también proporciona soporte para realizar los dos pasos anteriores de una sola vez mediante una técnica denominada <a href="https://www.elastic.co/es/docs/reference/query-languages/query-dsl/query-dsl-terms-query#query-dsl-terms-lookup">búsqueda de términos</a>. Elasticsearch se encargará de recuperar de forma transparente los valores para que coincidan con otro índice. Por ejemplo, si tiene un índice de equipos que contiene una lista de jugadores:</p>PUT teams/_doc/team1
{
  "players":   ["john", "bill", "michael"]
}
PUT teams/_doc/team2
{
  "players":   ["aaron", "joe", "donald"]
}<p>Es posible consultar un índice de personas para todas las personas que juegan en team1, como se muestra a continuación:</p>GET people/_search?pretty
{
  "query": {
    "terms": {
        "name" : {
            "index" : "teams",
            "id" : "team1",
            "path" : "players"
        }
    }
  }
}<p>En el ejemplo anterior, Elasticsearch recuperará de forma transparente los nombres de los jugadores del documento con id team1 en el índice de equipos (es decir, "John", "Bill" y "Michael") y busque todos los documentos en el índice de personas que contengan cualquiera de esos valores en su campo de nombre.</p><p>Para aquellos que tienen curiosidad, la consulta SQL equivalente sería:</p><h2>Uso del procesador enrich</h2><p>El<a href="https://www.elastic.co/es/docs/reference/enrich-processor/enrich-processor"> procesador</a> <a href="https://www.elastic.co/es/docs/reference/enrich-processor/enrich-processor"><code>enrich</code></a>es otra herramienta poderosa que se puede usar para unir dos índices en Elasticsearch. Este procesador enriquece los datos de los documentos entrantes agregando datos de un índice de enriquecimiento predefinido.</p><p>A continuación, le indicamos cómo puede usar el procesador de enriquecimiento para unir dos índices:</p><p>1. Primero, debe crear una política de enriquecimiento. Esta directiva define qué índice usar para el enriquecimiento, en qué campo coincidir y qué campos usar para enriquecer los documentos entrantes.</p><p>Aquí hay un ejemplo:</p>PUT _enrich/policy/my_enrich_policy
{
  "match": {
    "indices": "first_index",
    "match_field": "field_in_first_index",
    "enrich_fields": ["field_to_enrich"]
  }
}<p>2. Una vez creada la política, debe ejecutarla para crear el índice de enriquecimiento a partir de la política recién creada:</p>PUT _enrich/policy/my_enrich_policy/_execute<p>Esto creará un nuevo índice enriquecido oculto que se usará durante el enriquecimiento. En función del tamaño del índice de origen, esta operación puede tardar algún tiempo. Cerciorar de que la política de enriquecimiento esté completamente desarrollada antes de continuar con el siguiente paso.</p><p>3. Una vez creada la directiva de enriquecimiento, puede emplear el procesador de enriquecimiento en una canalización de ingesta para enriquecer los datos de los documentos entrantes:</p>PUT _ingest/pipeline/my_pipeline
{
  "processors": [
    {
      "enrich": {
        "policy_name": "my_enrich_policy",
        "field": "field_in_second_index",
        "target_field": "enriched_field"
      }
    }
  ]
}<p>En este ejemplo, <code>field_in_second_index</code> es el campo del segundo índice que debe coincidir con el <code>match_field</code> del primer índice. <code>enriched_field</code> es el nuevo campo del segundo índice que contendrá los datos enriquecidos de la <code>enrich_fields</code> del primer índice.</p><p>Un inconveniente de este enfoque es que si los datos cambian en <code>first_index</code>, la política de enriquecimiento debe volver a ejecutar. El índice enriquecido no se actualiza ni sincroniza automáticamente desde el índice de origen a partir del cual se creó. Sin embargo, si <code>first_index</code> es relativamente estable, entonces este enfoque funciona bien.</p><h2>Complemento de filtro Logstash elasticsearch</h2><p>Si usa Logstash, otra opción similar al procesador de <code>enrich</code> descrito anteriormente es usar el complemento de filtro <code>elasticsearch</code> para agregar campos relevantes al evento en función de una consulta específica. La configuración de nuestra canalización de Logstash residiría en un archivo <code>.conf</code> , como <code>my-pipeline.conf</code>.</p><p>Imaginemos que nuestra canalización está extrayendo registros de Elasticsearch usando el<a href="https://www.elastic.co/es/docs/reference/logstash/plugins/plugins-inputs-elasticsearch"> complemento de entrada</a> <a href="https://www.elastic.co/es/docs/reference/logstash/plugins/plugins-inputs-elasticsearch"><code>elasticsearch</code></a>, con una consulta para reducir la selección:</p>input {
  # Read all documents from Elasticsearch matching the given query
  elasticsearch {
    hosts =&gt; "localhost"
    query =&gt; '{ "query": { "match": { "statuscode": 200 } }, "sort": [ "_doc" ] }'
  }
}<p>Si queremos enriquecer estos mensajes con información de un índice determinado, podemos usar el<a href="https://www.elastic.co/es/docs/reference/logstash/plugins/plugins-filters-elasticsearch"> complemento de filtro</a> <a href="https://www.elastic.co/es/docs/reference/logstash/plugins/plugins-filters-elasticsearch"><code>elasticsearch</code></a>en la sección <code>filter</code> para enriquecer nuestros registros:</p>filter {
   elasticsearch {
      hosts =&gt; ["localhost"]
      index =&gt; "index_name"
      query =&gt; "type:start AND operation:%{[opid]}"
      fields =&gt; { "@timestamp" =&gt; "started" }
   }
}<p>El código anterior buscará los documentos del índice <code>index_name</code> donde se inicia <code>type</code> y el campo de operación coincide con el <code>opid</code>especificado y, a continuación, copiará el valor del campo <code>@timestamp</code> en un nuevo campo denominado <code>started</code>.</p><p>Los documentos enriquecidos se enviarían a la fuente de salida adecuada, en este caso a Elasticsearch mediante el<a href="https://www.elastic.co/es/docs/reference/logstash/plugins/plugins-outputs-elasticsearch"> complemento de salida</a> <a href="https://www.elastic.co/es/docs/reference/logstash/plugins/plugins-outputs-elasticsearch"><code>elasticsearch</code></a>:</p>output {
    elasticsearch {
        hosts =&gt; "localhost"
        data_stream =&gt; "true"
    }
}<p>Si ya está empleando Logstash, esta opción puede ser útil para consolidar su lógica de enriquecimiento en un solo lugar y procesar a medida que ingresan nuevos eventos. Sin embargo, si no lo está, agrega complejidad a su solución y otro componente que necesita ejecutar y mantener.</p><h2>ES|ENRIQUECER QL</h2><p>La introducción de <a href="https://www.elastic.co/es/docs/explore-analyze/query-filter/languages/esql">ES|QL</a>, que pasó a ser GA en la versión 8.14, es un lenguaje de consulta canalizado compatible con Elasticsearch que permite filtrar, transformar y analizar datos. El uso del comando de procesamiento ENRICH nos permite agregar datos de índices existentes mediante una política de enriquecimiento.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbeb8992bde773461/6a17f6b663baff00c9741dd4/03aadddc08afffff3f6526c9c052999c97fa09dd-1600x989.png" alt="ESQL enriquecer" /><p>Tomando la misma <code>my_enrich_policy</code> de políticas del ejemplo original del procesador de enriquecimiento, el ES|El ejemplo de QL se vería así:</p><p>También es posible anular los campos de coincidencia y enriquecimiento, que en nuestro ejemplo son <code>field_in_first_index</code> y <code>field_to_enrich</code> respectivamente:</p><p>Si bien la limitación obvia es que primero debe especificar una política de enriquecimiento, ES|QL proporciona la flexibilidad para ajustar los campos según sea necesario.</p><h2>ES|UNIÓN DE BÚSQUEDA DE QL</h2><p>Elasticsearch 8.18 presenta una nueva forma de unir índices en Elasticsearch, a saber, el comando <code>LOOKUP JOIN</code> . Este comando funciona como una LEFT OUTER JOIN de estilo SQL empleando el nuevo modo de <a href="https://www.elastic.co/es/docs/reference/elasticsearch/index-settings/index-modules#index-mode-setting">índice de búsqueda</a> en el lado derecho de la unión.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt783ffb3f9802f92d/6a17f6b8e9ea870608a9c788/1d73495979c4d6bb675c4c966ea86d9a72dc1c48-510x605.png" alt="ES|UNIÓN DE BÚSQUEDA DE QL" /><p>Revisando nuestro ejemplo anterior, la nueva consulta es la siguiente, donde <code>match_field</code> debe estar presente tanto en <code>first_index</code> como en <code>second_index</code>:</p><p>El beneficio de LOOKUP JOIN sobre los otros enfoques es que no requiere ninguna directiva de <code>enrich</code> y, por lo tanto, el procesamiento adicional asociado con la configuración de la directiva. Es útil cuando se trabaja con datos de enriquecimiento que cambian con frecuencia, a diferencia de los otros enfoques que se analizan en este artículo.</p><h2>Conclusión</h2><p>En conclusión, si bien Elasticsearch no admite operaciones de unión tradicionales, proporciona varias características que se pueden usar para lograr resultados similares. Específicamente, cubrimos cómo lograr operaciones de unión usando:</p><ol><li><p>La consulta <code>terms</code></p></li><li><p>El procesador <code>enrich</code> en canalizaciones de ingesta</p></li><li><p>Complemento de filtro <code>elasticsearch</code> Logstash</p></li><li><p>ES|QL <code>ENRICH</code></p></li><li><p>ES|QL <code>LOOKUP JOIN</code></p></li></ol><p>Es importante tener en cuenta que estos métodos tienen sus limitaciones y deben usar juiciosamente según los requisitos específicos y la naturaleza de los datos.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-join-two-indexes</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-join-two-indexes</guid>
    <category><![CDATA[Conceptos básicos]]></category>
    <dc:creator><![CDATA[Carly Richmond]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt74822b3b7cb2a41a/6a17f6b97f6f156288c09cc7/0d4736d10fa3e12e6233cd59993299c7bd48911b-680x450.png" length="0" type="image/png"/>
    <pubDate>Wed, 07 May 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Entendiendo el puntaje de Elasticsearch y la API Explain]]></title>
    <description><![CDATA[Aprende sobre los mecanismos de puntuación de Elasticsearch y la función de puntuación práctica para la auditoría de la relevancia de búsquedas y mejorar la clasificación de documentos con la API Explain.]]></description>
    <content:encoded><![CDATA[<p>Elasticsearch es un poderoso motor de búsqueda que proporciona resultados rápidos y relevantes calculando un puntaje para cada documento del índice. Este puntaje es un factor crucial para determinar el orden de los resultados de búsqueda. En este artículo, profundizaremos en el mecanismo de puntaje de Elasticsearch y exploraremos la API Explica, que ayuda a comprender el proceso de puntaje.</p><h2>Mecanismos de puntaje en Elasticsearch</h2><p>Elasticsearch emplea por defecto un modelo de puntaje llamado Practical Scoring Function (BM25). Este modelo se basa en la teoría probabilística de recuperación de información y tiene en cuenta factores como la frecuencia de términos, la frecuencia inversa de documentos y la normalización longitud-campo. Hablemos brevemente de estos factores:</p><ol><li><p><strong>Frecuencia de término (TF):</strong> Esto representa el número de veces que un término aparece en un documento. Una mayor frecuencia de término indica una relación más fuerte entre el término y el documento.</p></li><li><p><strong>Frecuencia inversa del documento (IDF):</strong> Este factor mide la importancia de un término en toda la colección documental. Un término que aparece en muchos documentos se considera menos importante, mientras que un término que aparece en menos documentos se considera más importante.</p></li><li><p><strong>Normalización de longitud de campo</strong>: Este factor tiene en cuenta la longitud del campo en el que aparece el término. Los campos más cortos tienen más peso, ya que el término se considera más significativo en un campo más corto.</p></li></ol><h2>Usando la API Explain</h2><p>La API Explain en Elasticsearch es una herramienta valiosa para entender el proceso de puntaje. Proporciona una explicación detallada de cómo se calculó el puntaje de un documento específico. Para usar la API Explic, necesitas enviar una solicitud GET al siguiente endpoint:</p>GET /&lt;index&gt;/_explain/&lt;document_id&gt;<p>En el cuerpo de la solicitud, debes proporcionar la consulta para la que quieres entender el puntaje. Aquí tienes un ejemplo:</p>{
  "query": {
    "match": {
      "title": "elasticsearch"
    }
  }
}<p>La respuesta de la API Explain incluirá un desglose detallado del proceso de puntaje, incluyendo los factores individuales (TF, IDF y la normalización de la longitud del campo) y sus contribuciones al puntaje final. Aquí tienes una respuesta de ejemplo:</p>{
  "_index": "example_index",
  "_type": "_doc",
  "_id": "1",
  "matched": true,
  "explanation": {
    "value": 1.2,
    "description": "weight(title:elasticsearch in 0) [PerFieldSimilarity], result of:",
    "details": [
      {
        "value": 1.2,
        "description": "score(doc=0,freq=1.0 = termFreq=1.0\n), product of:",
        "details": [
          {
            "value": 2.2,
            "description": "idf, computed as log(1 + (docCount - docFreq + 0.5) / (docFreq + 0.5)) from:",
            "details": [
              {
                "value": 1,
                "description": "docFreq",
                "details": []
              },
              {
                "value": 1,
                "description": "docCount",
                "details": []
              }
            ]
          },
          {
            "value": 0.5,
            "description": "tfNorm, computed as (freq * (k1 + 1)) / (freq + k1 * (1 - b + b * fieldLength / avgFieldLength)) from:",
            "details": [
              {
                "value": 1,
                "description": "termFreq=1.0",
                "details": []
              },
              {
                "value": 1.2,
                "description": "parameter k1",
                "details": []
              },
              {
                "value": 0.75,
                "description": "parameter b",
                "details": []
              },
              {
                "value": 1,
                "description": "avgFieldLength",
                "details": []
              },
              {
                "value": 1,
                "description": "fieldLength",
                "details": []
              }
            ]
          }
        ]
      }
    ]
  }
}<p>En este ejemplo, la respuesta muestra que el puntaje de 1,2 es un producto del valor IDF (2,2) y el valor tfNorm (0,5). La explicación detallada ayuda a entender los factores que contribuyen al puntaje y puede ser útil para afinar la relevancia en la búsqueda.</p><h2>Conclusión</h2><p>El puntaje de elasticsearch es un aspecto fundamental para proporcionar resultados de búsqueda relevantes. Al comprender los mecanismos de puntaje y emplear la API Explice, puedes obtener información sobre los factores que afectan a los resultados de búsqueda y optimizar tus consultas para mejorar la relevancia y el rendimiento.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-scoring-and-explain-api</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-scoring-and-explain-api</guid>
    <category><![CDATA[Conceptos básicos]]></category>
    <dc:creator><![CDATA[Kofi Bartlett]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbe7de1872f1527e3/6a17de303e9e452974ba1374/a70c5403064d5bbceff66a17373332362227f13c-720x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Mon, 05 May 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Búsqueda de elasticsearch mediante dos campos]]></title>
    <description><![CDATA[Explora técnicas para buscar por dos campos, incluidas consultas multi-coincidencia, consultas booleanas y aumento de campos en tiempo de consulta.]]></description>
    <content:encoded><![CDATA[<p>Buscar en varios campos en Elasticsearch es un requisito común en muchas aplicaciones. En este artículo, exploraremos técnicas avanzadas para realizar búsquedas por dos campos, incluyendo consultas multi-coincidencia, consultas bool y aumento de campos en tiempo de consulta. Estas técnicas te ayudarán a crear resultados de búsqueda más precisos y relevantes para tus usuarios.</p><h2>Técnicas avanzadas para realizar búsquedas en dos campos</h2><h3>1. Consulta multi-coincidencia</h3><p>Una consulta multi-coincidencia te permite buscar una sola cadena de consulta en varios campos. Esto es útil cuando quieres encontrar documentos que contengan la cadena de consulta dada en cualquiera de los dos campos. Aquí tienes un ejemplo de consulta multi-coincidencia que busca el término "ejemplo" en los campos "título" o "descripción":</p>{
  "query": {
    "multi_match": {
      "query": "example",
      "fields": ["title", "description"]
    }
  }
}<h3>2. Consulta de bool</h3><p>Una consulta bool permite combinar varias consultas usando lógica booleana. Puedes usar la cláusula "debería" para buscar documentos que coincidan con la consulta en cualquiera de los dos campos. Aquí tienes un ejemplo de consulta bool que busca el término "ejemplo" en los campos "título" y "descripción":</p>{
  "query": {
    "bool": {
      "should": [
        {"match": {"title": "example"}},
        {"match": {"description": "example"}}
      ]
    }
  }
}<h3>3. Aumento de campos en tiempo de consulta</h3><p>A veces, puede que quieras dar más importancia a un campo que a otro durante la búsqueda. Puedes conseguirlo aplicando un factor de mejora al campo en el momento de la consulta. Un valor de aumento más alto da más peso al campo, haciendo que sea más probable que influya en el puntaje final de búsqueda. Aquí tienes un ejemplo de consulta multi-coincidencia con un factor de impulso aplicado al campo "título":</p>{
  "query": {
    "multi_match": {
      "query": "example",
      "fields": ["title^3", "description"]
    }
  }
}<p>En este ejemplo, el campo "título" tiene un factor de mejora de 3, lo que lo hace tres veces más importante que el campo "descripción" para determinar el puntaje de búsqueda.</p><h3>4. Combinar consultas con diferentes factores de impulso</h3><p>También puedes combinar varias consultas con diferentes factores de boost usando una consulta bool. Esto te permite afinar la importancia de cada campo en los resultados de búsqueda. Aquí tienes un ejemplo de consulta bool con diferentes factores de boost aplicados a los campos "título" y "descripción":</p>{
  "query": {
    "bool": {
      "should": [
        {"match": {"title": {"query": "example", "boost": 3}}},
        {"match": {"description": {"query": "example", "boost": 1}}}
      ]
    }
  }
}<p>En este ejemplo, el campo "título" tiene un factor de mejora de 3, mientras que el campo de "descripción" tiene un factor de aumento de 1.</p><h2>Conclusión</h2><p>La búsqueda mediante dos campos en Elasticsearch se puede lograr mediante técnicas avanzadas como consultas multi-coincidencia, consultas bool y aumento de campos en tiempo de consulta. Combinando estas técnicas, puedes crear resultados de búsqueda más precisos y relevantes para tus usuarios. Experimenta con diferentes combinaciones de consultas y factores de mejora para encontrar la configuración óptima de búsqueda para tu caso de uso específico.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-search-by-two-fields</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-search-by-two-fields</guid>
    <category><![CDATA[Conceptos básicos]]></category>
    <category><![CDATA[Búsqueda en DSL]]></category>
    <dc:creator><![CDATA[Kofi Bartlett]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltda47d75430c4fa7c/6a17f5cae3179149242d5963/d5d04bbcfc3925f48f3487ea4c7e0dd2205316d0-720x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Wed, 30 Apr 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Cómo implementar una Mejor Cuantización Binaria (BBQ) en tu caso de uso]]></title>
    <description><![CDATA[Explora por qué implementarías Better Binary Quantization (BBQ) en tu caso de uso y cómo hacerlo.]]></description>
    <content:encoded><![CDATA[<p>La búsqueda vectorial proporciona la base al implementar la búsqueda semántica de texto o la búsqueda de similitud de imágenes, videos o audio. Con la búsqueda vectorial, los vectores son representaciones matemáticas de datos que pueden ser enormes y, a veces, lentos. Better Binary Quantization (en lo sucesivo, BBQ) funciona como un método de compresión para vectores. Le permite encontrar las coincidencias correctas mientras reduce los vectores para que sean más rápidos de buscar y procesar. Este artículo cubrirá BBQ y rescore_vector, un campo solo disponible para índices cuantificados que vuelve a calificar automáticamente los vectores.</p><p>Todas las consultas y salidas completas mencionadas en este artículo se pueden encontrar en nuestro <a href="https://github.com/elastic/elasticsearch-labs/tree/main/supporting-blog-content/how-and-why-bbq">repositorio de código de Elasticsearch Labs</a>.</p><h2>¿Por qué implementar Better Binary Quantization (BBQ) en tu caso de uso?</h2>Nota: para una comprensión profunda de cómo funcionan las matemáticas detrás del asado, consulte la <a href="https://www.elastic.co/es/search-labs/blog/bbq-implementation-into-use-case#further-learning">sección "Aprendizaje adicional"</a> a continuación. Para los propósitos de este blog, la atención se centra en la implementación.<p>Aunque las matemáticas son interesantes, son cruciales si quieres comprender completamente por qué tus búsquedas vectoriales siguen siendo precisas. En última instancia, todo esto se reduce a la compresión, ya que resulta que con los algoritmos actuales de búsqueda vectorial estás limitado por la velocidad de lectura de los datos. Por lo tanto, si puedes meter todos esos datos en la memoria, obtienes un aumento significativo de velocidad en comparación con leer desde el almacenamiento (<a href="https://sre.google/static/pdf/rule-of-thumb-latency-numbers-letter.pdf">la memoria es aproximadamente 200 veces más rápida que los SSD</a>).</p><p>Hay algunas cosas a tener en cuenta:</p><ul><li><p>Los índices basados en gráficos como <a href="https://arxiv.org/pdf/1603.09320">HNSW</a> (Hierarchical Navigable Small World) son los más rápidos para la recuperación de vectores.</p><ul><li><p>HNSW: Un algoritmo de búsqueda aproximado del vecino más cercano que construye una estructura de gráficos multicapa para permitir búsquedas eficientes de similitud de alta dimensión.</p></li></ul></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt760bd95c206bfa8f/6a17e2ad505ac393f7ad8a95/590f3b3c72a76023a38a0436cd9ff90a9f80e936-1964x1262.png" alt="HNSW: Un algoritmo de búsqueda aproximado del vecino más cercano que construye una estructura de gráficos multicapa para permitir búsquedas eficientes de similitud de alta dimensión." /><ul><li><p>HNSW está fundamentalmente limitado en velocidad por la velocidad de lectura de datos de la memoria o, en el peor de los casos, del almacenamiento.</p><ul><li><p>Idealmente, desea poder cargar todos sus vectores almacenados en la memoria.</p></li></ul></li><li><p>Los modelos de incrustación generalmente producen vectores con precisión float32, 4 bytes por número de punto flotante.</p></li><li><p>Y finalmente, dependiendo de cuántos vectores y / o dimensiones tenga, puede quedar sin memoria muy rápidamente para mantener todos sus vectores.</p></li></ul><p>Dando esto por sentado, ve que surge un problema rápidamente una vez que comienza a ingerir millones o incluso miles de millones de vectores, cada uno con potencialmente cientos o incluso miles de dimensiones. La sección titulada "<a href="https://www.elastic.co/es/search-labs/blog/bbq-implementation-into-use-case#approximate-numbers-on-the-compression-ratios">Números aproximados en las relaciones de compresión</a>" proporciona algunos números aproximados.</p><h2>¿Qué necesitas para empezar?</h2><p>Para comenzar, necesitará lo siguiente:</p><ul><li><p>Si usas Elastic Cloud o en las instalaciones, necesitarás una versión de Elasticsearch superior a la 8.18. Si bien BBQ se introdujo en 8.16, en este artículo, usará <code>vector_rescore</code>, que se introdujo en 8.18.</p></li><li><p>Además, también deberá cerciorar de que haya un <a href="https://www.elastic.co/es/guide/en/elasticsearch/reference/8.18/ml-settings.html">nodo de aprendizaje automático (ML)</a> en el clúster. (Nota: se necesita un nodo de ML con un mínimo de 4 GB para cargar el modelo, pero es probable que necesite nodos mucho más grandes para cargas de trabajo de producción completas).</p></li><li><p>Si emplea Serverless, deberá seleccionar una instancia optimizada para vectores.</p></li><li><p>También necesitará un nivel básico de conocimiento sobre bases de datos vectoriales. Si aún no estás familiarizado con los conceptos de búsqueda vectorial en Elastic, es posible que desees consultar primero los siguientes recursos:</p><ul><li><p><a href="https://www.elastic.co/es/search-labs/blog/elastic-vector-database-practical-example">Navegación por una base de datos vectorial elástica</a></p></li><li><p><a href="https://www.elastic.co/es/blog/retrieval-augmented-generation-explained">Las grandes ideas detrás de la generación aumentada de recuperación</a></p></li></ul></li></ul><h2>Mejor implementación de cuantización binaria (BBQ)</h2><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt18df00df95ff2ca7/6a17e2af414c6411989450df/4d388078495566f0527e931e0c2e38facdce83c6-1503x748.png" alt="Implementación de asado con Elasticsearch." /><p>Para simplificar este blog, empleará funciones integradas cuando estén disponibles. En este caso, tienes el modelo de incrustación de vectores <a href="https://www.elastic.co/es/guide/en/machine-learning/8.17/ml-nlp-e5.html"><code>.multilingual-e5-small</code></a> que se ejecutará directamente dentro de Elasticsearch en un nodo de aprendizaje automático. Tenga en cuenta que puede reemplazar el modelo <code>text_embedding</code> con el incrustador de su elección (<a href="https://www.elastic.co/es/guide/en/elasticsearch/reference/8.18/infer-service-openai.html">OpenAI,</a> <a href="https://www.elastic.co/es/guide/en/elasticsearch/reference/8.18/infer-service-google-ai-studio.html">Google AI Studio</a>, <a href="https://www.elastic.co/es/guide/en/elasticsearch/reference/8.18/infer-service-cohere.html">Cohere</a> y muchos más). Si su modelo preferido aún no está integrado, también puede <a href="https://www.elastic.co/es/guide/en/elasticsearch/reference/8.18/bring-your-own-vectors.html">traer sus propias incrustaciones de vectores densos</a>).</p><p>En primer lugar, deberá crear un punto de enlace de inferencia para generar vectores para un fragmento de texto determinado. Ejecutarás todos estos comandos desde la <a href="https://www.elastic.co/es/guide/en/kibana/8.18/console-kibana.html">consola de herramientas de desarrollo de Kibana</a>. Este comando descargará el <code>.multilingual-e5-small</code>. Si aún no existe, configurará su punto final; Esto puede tardar un minuto en ejecutar. Puede ver la salida esperada en el <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/01-create-an-inference-endpoint-output.json">archivo 01-create-an-inference-endpoint-output.json</a> en la carpeta Salidas. </p>PUT _inference/text_embedding/my_e5_model
{
  "service": "elasticsearch",
  "service_settings": {
    "num_threads": 1,
    "model_id": ".multilingual-e5-small",
    "adaptive_allocations": {
      "enabled": true,
      "min_number_of_allocations": 1
    }
  }
}<p>Una vez que esto regresó, su modelo se configurará y podrá probar que el modelo funciona como se espera con el siguiente comando. Puede ver el resultado esperado en el <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/02-embed-text-output.json">archivo 02-embed-text-output.json</a> en la carpeta Salidas.</p>POST _inference/text_embedding/my_e5_model
{
  "input": "my awesome piece of text"
}<p>Si tiene problemas relacionados con el modelo capacitado que no se asigna a ningún nodo, es posible que deba iniciar el modelo manualmente.</p>POST _ml/trained_models/.multilingual-e5-small/deployment/_start<p>Ahora vamos a crear una nueva asignación con 2 propiedades, un campo de texto estándar (<code>my_field</code>) y un campo vectorial denso (<code>my_vector</code>) con 384 dimensiones para que coincida con la salida del modelo de incrustación. También anulará el <code>index_options.type to bbq_hnsw</code>. Puede ver el resultado esperado en el <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/03-create-byte-qauntized-index-output.json">archivo 03-create-byte-qauntized-index-output.json</a> en la carpeta Salidas.</p>PUT bbq-my-byte-quantized-index
{
  "mappings": {
    "properties": {
      "my_field": {
        "type": "text"
      },
      "my_vector": {
        "type": "dense_vector",
        "dims": 384,
        "index_options": {
          "type": "bbq_hnsw"
        }
      }
    }
  }
}<p>Para cerciorarte de que Elasticsearch genere tus vectores, puedes usar una <a href="https://www.elastic.co/es/guide/en/elasticsearch/reference/8.18/ingest.html">canalización de ingesta</a>. Esta canalización requerirá 3 cosas: el punto final, (<code>model_id</code>), el <code>input_field</code> para el que desea crear vectores y el <code>output_field</code> en el que almacenar esos vectores. El primer comando siguiente creará una canalización de ingesta de inferencia, que usa el <a href="https://www.elastic.co/es/guide/en/elasticsearch/reference/current/inference-apis.html">servicio de inferencia </a>en segundo plano, y el segundo probará que la canalización funciona correctamente. Puede ver la salida esperada en el <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/04-create-and-simulate-ingest-pipeline-output.json">archivo 04-create-and-simulate-ingest-pipeline-output.json</a> en la carpeta Salidas. </p>PUT _ingest/pipeline/my_inference_pipeline
{
  "processors": [
    {
      "inference": {
        "model_id": "my_e5_model",
        "input_output": [
          {
            "input_field": "my_field",
            "output_field": "my_vector"
          }
        ]
      }
    }
  ]
}

POST _ingest/pipeline/my_inference_pipeline/_simulate
{
  "docs": [
    {
      "_source": {
        "my_field": "my awesome text field"
      }
    }
  ]
}<p>Ahora está listo para agregar algunos documentos con los primeros 2 comandos a continuación y para probar que sus búsquedas funcionan con el 3er comando. Puede desproteger el resultado esperado en el <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/05-bbq-index-output.json">archivo 05-bbq-index-output.json</a> en la carpeta Salidas. </p>PUT bbq-my-byte-quantized-index/_doc/1?pipeline=my_inference_pipeline
{
    "my_field": "my awesome text field"
}

PUT bbq-my-byte-quantized-index/_doc/2?pipeline=my_inference_pipeline
{
    "my_field": "some other sentence"
}

GET bbq-my-byte-quantized-index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "knn": {
            "field": "my_vector",
            "query_vector_builder": {
              "text_embedding": {
                "model_id": "my_e5_model",
                "model_text": "my awesome search field"
              }
            },
            "k": 10,
            "num_candidates": 100
          }
        }
      ]
    }
  },
  "_source": [
    "my_field"
  ]
}<p>Como se recomienda en <a href="https://www.elastic.co/es/search-labs/blog/better-binary-quantization-lucene-elasticsearch#lucene-benchmarking">esta publicación</a>, se recomienda volver a puntuar y sobremuestrear cuando se escala a cantidades no triviales de datos porque ayudan a mantener una alta precisión de recuperación mientras se benefician de los beneficios de la compresión. A partir de la versión 8.18 de Elasticsearch, puedes hacerlo de esta manera usando <a href="https://www.elastic.co/es/guide/en/elasticsearch/reference/8.18/knn-search.html#dense-vector-knn-search-rescoring">rescore_vector</a>. La salida esperada se encuentra en el <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/06-bbq-search-8-18-output.json">archivo 06-bbq-search-8-18-output.json</a> en la carpeta Outputs.</p>GET bbq-my-byte-quantized-index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "knn": {
            "field": "my_vector",
            "query_vector_builder": {
              "text_embedding": {
                "model_id": "my_e5_model",
                "model_text": "my awesome search field"
              }
            },
            "rescore_vector": {
              "oversample": 3
            },
            "k": 10,
            "num_candidates": 100
          }
        }
      ]
    }
  },
  "_source": [
    "my_field"
  ]
}<p>¿Cómo se comparan estos puntajes con los que obtendría por los datos sin procesar? Si vuelves a hacer todo lo anterior pero con <code>index_options.type: hnsw</code>, verás que los puntajes son muy comparables. Puede ver el resultado esperado en el <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/07-raw-vector-output.json">archivo 07-raw-vector-output.json</a> en la carpeta Salidas.</p>PUT my-raw-vector-index
{
  "mappings": {
    "properties": {
      "my_field": {
        "type": "text"
      },
      "my_vector": {
        "type": "dense_vector",
        "dims": 384,
        "index_options": {
          "type": "hnsw"
        }
      }
    }
  }
}

PUT my-raw-vector-index/_doc/1?pipeline=my_inference_pipeline
{
    "my_field": "my awesome text field"
}

PUT my-raw-vector-index/_doc/2?pipeline=my_inference_pipeline
{
    "my_field": "some other sentence"
}

GET my-raw-vector-index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "knn": {
            "field": "my_vector",
            "query_vector_builder": {
              "text_embedding": {
                "model_id": "my_e5_model",
                "model_text": "my awesome search field"
              }
            },
            "k": 10,
            "num_candidates": 100
          }
        }
      ]
    }
  },
  "_source": [
    "my_field"
  ]
}<h2>Números aproximados en las relaciones de compresión</h2><p>Los requisitos de almacenamiento y memoria pueden convertir rápidamente en un desafío importante cuando se trabaja con la búsqueda vectorial. El siguiente desglose ilustra cómo las diferentes técnicas de cuantificación reducen significativamente la huella de memoria de los datos vectoriales.</p><p>Vectores (V)</p><p>Dimensiones (D)</p><p>sin procesar (V x P x 4)</p><p>int8 (V x (D x 1 + 4))</p><p>int4 (V x (D x 0.5 + 4))</p><p>asado (V x (D x 0.125 + 4))</p><p>10,000,000</p><p>384</p><p>14,31 GB</p><p>3,61 GB</p><p>1,83 GB</p><p>0,58 GB</p><p>50,000,000</p><p>384</p><p>71,53 GB</p><p>18,07 GB</p><p>9,13 GB</p><p>2,89 GB</p><p>100,000,000</p><p>384</p><p>143,05 GB</p><p>36,14 GB</p><p>18,25 GB</p><p>5,77 GB</p><h2>Conclusión</h2><p>BBQ es una optimización que puede aplicar a sus datos vectoriales para la compresión sin sacrificar la precisión. Funciona convirtiendo vectores en bits, lo que le permite buscar los datos de manera efectiva y le permite escalar sus flujos de trabajo de IA para acelerar las búsquedas y optimizar el almacenamiento de datos.</p><h2>Aprendizaje adicional</h2><p>Si está interesado en obtener más información sobre el asado, cerciorar de consultar los siguientes recursos:</p><ul><li><p><a href="https://www.elastic.co/es/search-labs/blog/better-binary-quantization-lucene-elasticsearch">Cuantificación binaria (BBQ) en Lucene y Elasticsearch</a></p></li><li><p><a href="https://www.elastic.co/es/search-labs/blog/bit-vectors-elasticsearch-bbq-vs-pq">Mejor cuantización binaria (BBQ) frente a cuantificación de productos</a></p></li><li><p><a href="https://www.elastic.co/es/search-labs/blog/optimized-scalar-quantization-elasticsearch">Cuantización escalar optimizada: cuantificación binaria aún mejor</a></p></li><li><p><a href="https://www.youtube.com/watch?v=04NzMt2Nigc">Mejor cuantificación binaria (BBQ): De bytes a BBQ, el secreto para una mejor búsqueda vectorial por Ben Trent</a></p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/bbq-implementation-into-use-case</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/bbq-implementation-into-use-case</guid>
    <category><![CDATA[Base de datos vectorial]]></category>
    <category><![CDATA[Conceptos básicos]]></category>
    <dc:creator><![CDATA[Sachin Frayne,Jessica Garson]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3dd0495b536b2615/6a17e2b0414c6488459450e3/66842055367cdd795532b01c167f2a4b03dc65e3-1200x628.png" length="0" type="image/png"/>
    <pubDate>Wed, 23 Apr 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Uso del tamaño del montón de Elasticsearch y recogida de basura de la JVM]]></title>
    <description><![CDATA[Explorando el uso del tamaño del heap en Elasticsearch y la recogida de basura de la JVM, incluyendo las mejores prácticas y cómo resolver problemas cuando el uso de memoria del heap es demasiado alto o cuando el rendimiento de la JVM no es óptimo.]]></description>
    <content:encoded><![CDATA[<p>El tamaño del heap es la cantidad de RAM asignada a la Máquina Virtual Java de un nodo Elasticsearch.</p><p>A partir de la versión 7.11, Elasticsearch por defecto establece automáticamente el tamaño del montón de la JVM en función de los roles y la memoria total de un nodo. Se recomienda usar el tamaño por defecto para la mayoría de entornos de producción. Sin embargo, si quieres configurar manualmente el tamaño del montón de tu JVM, como regla general deberías poner -Xms y -Xmx al MISMO valor, que debería ser el 50% de tu RAM disponible total, sujeto a un máximo (aproximadamente) 31GB.</p><p>Un tamaño de heap mayor le dará a tu nodo más memoria para las operaciones de indexación y búsqueda. Sin embargo, tu nodo también requiere memoria para la caché, así que usar el 50% mantiene un equilibrio saludable entre ambos. Por esta misma razón, en producción deberías evitar usar otros procesos que consumen mucho memoria en el mismo nodo que Elasticsearch.</p><p>Normalmente, el uso del montón sigue un patrón de dientes de sierra, oscilando entre alrededor del 30 y el 70% del montón máximo empleado. Esto se debe a que la JVM aumenta de forma constante el porcentaje de uso del montón hasta que el proceso de recogida de basura libera memoria de nuevo. El alto uso del montón ocurre cuando el proceso de recogida de basura no puede seguir el ritmo. Un indicador de un alto uso del montón es cuando la recolección de basura no es capaz de reducir el uso del montón a alrededor del 30%.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt03908d8eea824755/6a17dbe63e03d71e314f2b3e/0a17a67cc589a3c1fbf9e918eadc119df7bd7619-858x278.png" alt="" /><p>En la imagen de arriba, puedes ver un diente de sierra normal del montón de JVM.</p><p>También verás que hay dos tipos de recogida de basura: GC joven y vieja.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0d527a7905c78a45/6a17dbe84b055d09484320c2/8df5c24c4894404de4617be7a13683c9027d607d-875x281.png" alt="" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt681db7f60d9dbe40/6a17dbe97f6f152b9bc099f0/e01eb2537310b052580411153b8eddc187d97687-890x264.png" alt="" /><p>En una JVM saludable, la recogida de basura debería cumplir idealmente las siguientes condiciones:</p><ul><li><p>El GC joven se procesa rápidamente (en menos de 50 ms).</p></li><li><p>La GC joven no se ejecuta con frecuencia (unos 10 segundos).</p></li><li><p>El GC antiguo se procesa rápidamente (en menos de 1 segundo).</p></li><li><p>El GC antiguo no se ejecuta con frecuencia (una vez cada 10 minutos o más).</p></li></ul><h3><strong>Cómo resolver cuando el uso de memoria del heap es demasiado alto o cuando el rendimiento de la JVM no es óptimo</strong></h3><p>Puede haber varias razones por las que el uso de memoria heap puede aumentar:</p><h4><strong>Fragmentación de fragmentos</strong></h4><p>Por favor, consulta el documento sobre <a href="https://www.elastic.co/docs/deploy-manage/production-guidance/optimize-performance/size-shards#sizing-shard-guidelines">sobrefragmentación aquí</a>.</p><h4><strong>Grandes tamaños de agregación</strong></h4><p>Para evitar grandes tamaños de agregación, mantén al mínimo el número de cubos de agregación (tamaño) en tus consultas.</p>GET /_search
{
   "aggs" : {
       "products" : {
           "terms" : {
               "field" : "product",
               "size" : 5
                          }
       }
   }
}<p>Puedes usar el registro lento de consultas (registros lentos) e implementarlo en un índice específico usando lo siguiente.</p>PUT /my_index/_settings
{
   "index.search.slowlog.threshold.query.warn": "10s",
   "index.search.slowlog.threshold.query.info": "5s",
   "index.search.slowlog.threshold.query.debug": "2s",
   "index.search.slowlog.threshold.query.trace": "500ms",
   "index.search.slowlog.threshold.fetch.warn": "1s",
   "index.search.slowlog.threshold.fetch.info": "800ms",
   "index.search.slowlog.threshold.fetch.debug": "500ms",
   "index.search.slowlog.threshold.fetch.trace": "200ms",
   "index.search.slowlog.level": "info"
}<p>Las consultas que tardan mucho en devolver los resultados suelen ser las que requieren muchos recursos.</p><h4><strong>Tamaño excesivo del índice de volumen</strong></h4><p>Si envías peticiones grandes, esto puede ser una causa de un alto consumo de heaps. Prueba a reducir el tamaño de las solicitudes de índice masivo.</p><h4><strong>Problemas de cartografía</strong></h4><p>En individuo, si usas "fielddata: true", entonces puede ser un usuario importante de tu montón JVM.</p><h4><strong>Tamaño del montón incorrectamente configurado</strong></h4><p>El tamaño del heap puede definir manualmente por:</p><p>Establecer la variable de entorno:</p>ES_JAVA_OPTS="-Xms2g -Xmx2g"<p>Editar el archivo jvm.options en tu directorio de configuración de Elasticsearch:</p>-Xms2g
-Xmx2g<p>La configuración de la variable ambiental tiene prioridad sobre la configuración de archivo.</p><p>Es necesario resetear el nodo para tener en cuenta la configuración.</p><h4><strong>Nuevo ratio de JVM configurado incorrectamente</strong></h4><p>Generalmente NO es necesario establecer esto, ya que Elasticsearch establece este valor por defecto. Este parámetro define la proporción de espacio disponible para objetos de "nueva generación" y "generación antigua" en la JVM.</p><p>Si ves que el antiguo GC se está volviendo muy frecuente, puedes probar a establecer específicamente este valor en el archivo jvm.options de tu directorio de configuración de Elasticsearch.</p>-XX:NewRatio=3<h3><strong>¿Cuáles son las mejores prácticas para gestionar el uso del tamaño del heap y la recogida de basura de la JVM en un gran clúster de Elasticsearch?</strong></h3><p>Las mejores prácticas para gestionar el uso del tamaño del heap y la recolección de basura de la JVM en un gran clúster de Elasticsearch son cerciorar que el tamaño del heap esté fijado en un máximo del 50% de la RAM disponible, y que la configuración de recogida de basura de la JVM esté optimizada para el caso de uso específico. Es importante monitorizar el tamaño del montón y las métricas de recogida de basura para cerciorar de que el clúster funciona de forma óptima. En concreto, es importante monitorizar el tamaño del montón de la JVM, el tiempo de recogida de basura y las pausas en la recogida. Además, es importante controlar el número de ciclos de recogida de basura y el tiempo dedicado a la recogida. Al monitorizar estas métricas, es posible identificar posibles problemas con el tamaño del montón o la configuración de recogida de basura y tomar medidas correctivas si es necesario.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-heap-size-jvm-garbage-collection</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-heap-size-jvm-garbage-collection</guid>
    <category><![CDATA[Conceptos básicos]]></category>
    <dc:creator><![CDATA[Kofi Bartlett]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc58290fbc9f4efb9/6a1705f97d8d67cae970e632/b162c28623b9070fd1980bcd891b9dd1e868f2f0-720x421.jpg" length="0" type="image/jpeg"/>
    <pubDate>Tue, 22 Apr 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Cómo aumentar el conteo de fragmentos primarios en Elasticsearch]]></title>
    <description><![CDATA[Aprende cómo aumentar la cantidad de shards primarios en Elasticsearch usando las API split y reindex para un escalado óptimo de shards.]]></description>
    <content:encoded><![CDATA[<p>No es posible aumentar el número de fragmentos primarios de un índice existente, lo que significa que hay que recrear un índice si quieres aumentar el número de fragmentos primarios. En estas situaciones se emplean generalmente dos métodos: la API _reindex y la API _split.</p><p>La API _split suele ser un método más rápido que la API _reindex. <strong>La indexación</strong> <strong>debe detener</strong> antes de ambas operaciones, de lo contrario, el source_index y el target_index el recuentos de documentos variarán.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt46dd6abe0e6fe1eb/6a17e368148009d6a7b486d3/aa0ae010c2f5691ca00440fb453ed6b47bacd24f-1200x628.png" alt="Mayor cantidad de shards en Elasticsearch al recrear un índice" /><h2>Método 1 – usando la API dividida</h2><p>La API dividida se emplea para crear un nuevo índice con el número deseado de fragmentos primarios copiando los ajustes y mapeando un índice existente. El número deseado de fragmentos primarios puede establecer durante la creación. Se deben comprobar las siguientes configuraciones antes de implementar la API de división:</p><ol><li><p>El índice de origen debe ser de solo lectura. Esto significa que el proceso de indexación debe detener.</p></li><li><p>El número de fragmentos primarios en el índice objetivo debe ser un múltiplo del número de fragmentos primarios en el índice fuente. Por ejemplo, si el índice fuente tiene 5 fragmentos primarios, los fragmentos primarios del índice objetivo pueden establecer en 10, 15, 20, y así sucesivamente.</p></li></ol><p>Nota: Si solo es necesario cambiar el número principal del fragmento, se prefiere la API dividida porque es mucho más rápida que la API de Reindex.</p><h3>Implementación de la API de división</h3><p>Crea un índice de prueba:</p>POST test_split_source/_doc
{
  "test": "test"
}<p>El índice fuente debe ser de solo lectura para poder dividir:</p>PUT test_split_source/_settings
{
  "index.blocks.write": true
}<p>Los ajustes y mapeos se copiarán automáticamente desde el índice fuente:</p>POST /test_split_source/_split/test_split_target
{
  "settings": {
    "index.number_of_shards": 3
  }
}<p>Puedes consultar el progreso con:</p>GET _cat/recovery/test_split_target?v&amp;h=index,shard,time,stage,files_percent,files_total<p>Como los ajustes y mapeos se copian de los índices fuente, el índice destino es de solo lectura. Activemos la operación de escritura para el índice objetivo:</p>PUT test_split_target/_settings
{
    "index.blocks.write": null
}<p>Consulta el índice de origen y destino docs.count antes de eliminar el índice original:</p>GET _cat/indices/test_split*?v&amp;h=index,pri,rep,docs.count<p>El nombre del índice y el nombre del alias no pueden ser iguales. Necesitas eliminar el índice fuente y agregar el nombre del índice fuente como alias al índice objetivo:</p>DELETE test_split_source
PUT /test_split_target/_alias/test_split_source<p>Luego de agregar el <strong>alias test_split_source</strong> al <strong>índice de test_split_target</strong> , deberías probarlo con:</p>GET test_split_source
POST test_split_source/_doc
{
  "test": "test"
}<h2>Método 2 – usando la API de reindex</h2><p>Al crear un nuevo índice con la API Reindex, se puede obtener cualquier número de conteos de fragmentos primarios. Tras crear un nuevo índice con el número previsto de fragmentos primarios, todos los datos del índice fuente pueden reindexar a este nuevo índice.</p><p>Además de las funciones de API dividida, los datos pueden manipular usando el ingest_pipeline en el AP de reindexación. Con la tubería de ingest, solo los campos especificados que encajen con el filtro se indexarán en el índice objetivo usando la consulta. El contenido de los datos puede modificar usando un script sencillo, y varios índices pueden fusionar en un solo índice.</p><h3>Implementación de la API de reindex</h3><p>Crea un reindexado de prueba:</p>POST test_reindex_source/_doc
{
    "test": "test"
}<p>Copia la configuración y los mapeos del índice fuente:</p>GET test_reindex_source<p>Crea un índice objetivo con ajustes, mapeos y el número de fragmentos deseado:</p>PUT test_reindex_target
{
  "mappings" : {},
  "settings": {
    "number_of_shards": 10,
    "number_of_replicas": 0,
    "refresh_interval": -1
  }
}<p>*Nota: ajustar number_of_replicas: 0 y refresh_interval: -1 aumentará la velocidad de reindexación.</p><p>Inicia el proceso de reindexación. Configurar requests_per_second=-1 y slices=auto ajustará la velocidad de reindexación.</p>POST _reindex?requests_per_second=-1&amp;slices=auto&amp;wait_for_completion=false
{
  "source": {
    "index": "test_reindex_source"
  },
  "dest": {
    "index": "test_reindex_target"
  }
}<p>Verás el task_id cuando ejecutes la API de reindex. Cópila y comprueba con _tasks API:</p>GET _tasks/&lt;task_id&gt;<p>Actualiza la configuración después de que termine el reindexado:</p>PUT test_reindex_target/_settings
{
  "number_of_replicas": 1,
  "refresh_interval": "1s"
}<p>Consulta el índice fuente y destino docs.count antes de borrar el índice original, debería ser el mismo:</p>GET _cat/indices/test_reindex_*?v&amp;h=index,pri,rep,docs.count<p>El nombre del índice y el nombre del alias no pueden ser iguales. Elimina el índice fuente y agrega el nombre del índice fuente como alias al índice objetivo:</p>DELETE test_reindex_source
PUT /test_reindex_target/_alias/test_reindex_source<p>Luego de agregar el alias test_split_source al índice de test_split_target, pruébalo usando:</p>GET test_reindex_source<h2>Resumen</h2><p>Si quieres aumentar el recuento de fragmentos primarios de un índice existente, necesitas recrear los ajustes y asignaciones a un nuevo índice. Hay 2 métodos principales para hacerlo: la API de reindex y la API de split. La indexación activa debe detener antes de usar cualquiera de los dos métodos.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-increase-primary-shard-count</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-increase-primary-shard-count</guid>
    <category><![CDATA[Conceptos básicos]]></category>
    <dc:creator><![CDATA[Kofi Bartlett]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta8aa774fc00d7233/6a17e223dbb4ff68b3fb5611/7034b76019a0cba52c25eda29fceb18afc96ed0b-720x420.png" length="0" type="image/png"/>
    <pubDate>Thu, 17 Apr 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Cómo migrar datos entre diferentes versiones de Elasticsearch y entre clusters]]></title>
    <description><![CDATA[Exploración de métodos para transferir datos entre versiones y clústeres de Elasticsearch.]]></description>
    <content:encoded><![CDATA[<p>Cuando deseas actualizar un clúster de Elasticsearch, a veces es más fácil crear un clúster nuevo e independiente y transferir datos del clúster anterior al nuevo. Esto brinda a los usuarios el beneficio de poder probar todos sus datos y configuraciones en el nuevo clúster con todas sus aplicaciones sin ningún riesgo de tiempo de inactividad o pérdida de datos.</p><p>Las desventajas de ese enfoque son que requiere cierta duplicación de hardware y podría crear dificultades al intentar transferir y sincronizar sin problemas todos los datos.</p><p>También puede ser necesario realizar un procedimiento similar si necesita migrar aplicaciones de un centro de datos a otro.</p><p>En este artículo, analizaremos y detallaremos tres formas de transferir datos entre clústeres de Elasticsearch.</p><p><strong>¿Cómo migrar datos entre clusters de Elasticsearch?</strong></p><p>Hay 3 formas de transferir datos entre clústeres de Elasticsearch:</p><ol><li><p><a href="https://www.elastic.co/es/search-labs/blog/elasticsearch-migrate-data-versions-clusters#1.-reindexing-data-from-a-remote-cluster">Reindexación desde un clúster remoto</a></p></li><li><p><a href="https://www.elastic.co/es/search-labs/blog/elasticsearch-migrate-data-versions-clusters#2.-transferring-data-using-snapshots">Transferencia de datos mediante instantáneas</a></p></li><li><p><a href="https://www.elastic.co/es/search-labs/blog/elasticsearch-migrate-data-versions-clusters#3.-transferring-data-using-logstash">Transferencia de datos mediante Logstash</a></p></li></ol><p>El uso de instantáneas suele ser la forma más rápida y confiable de transferir datos. Sin embargo, tenga en cuenta que solo puede restaurar una instantánea en un clúster de una versión igual o superior y nunca con una diferencia de más de una versión principal. Esto significa que puede restaurar una instantánea 6.x en un clúster 7.x, pero no en un clúster 8.x.</p><p>Si necesita aumentar en más de una versión principal, deberá volver a indexar o usar Logstash.</p><p>Ahora, veamos en detalle cada una de las tres opciones para transferir datos entre clústeres de Elasticsearch.</p><h2>1. Reindexación de datos de un clúster remoto</h2><p>Antes de comenzar a volver a indexar, recuerde que deberá configurar asignaciones adecuadas para todos los índices del nuevo clúster. Para ello, debe crear los índices directamente con las asignaciones adecuadas o emplear plantillas de índice.</p><h3>Reindexación desde remoto: se requiere configuración</h3><p>Para poder reindexar desde remoto, debe agregar la siguiente configuración al archivo elasticseearch.yml para el clúster que recibe los datos, que, en los sistemas Linux, generalmente se encuentra aquí: /etc/elasticsearch/elasticsearch.yml. La configuración a agregar es la siguiente:</p>reindex.remote.whitelist: "192.168.1.11:9200"<p>Si emplea SSL, debe agregar el certificado de CA a cada nodo e incluir lo siguiente en el comando para cada nodo de elasticsearch.yml:</p>reindex.ssl.certificate_authorities: “/path/to/ca.pem”<p>Alternativamente, puede agregar la siguiente línea a todos los nodos de Elasticsearch para deshabilitar la verificación SSL. Sin embargo, ese enfoque es menos recomendable ya que no es tan seguro como la opción anterior:</p>reindex.remote.whitelist: "192.168.1.11:9200"
reindex.ssl.verification_mode: none
systemctl restart elasticsearch service <p>Deberá realizar estas modificaciones en cada nodo y realizar un resetear continuo. Para obtener más información sobre cómo hacerlo, consulte <a href="https://www.elastic.co/es/guide/en/elasticsearch/reference/8.17/restart-cluster.html#restart-cluster-rolling">nuestra guía</a>.</p><h3>Comando de reindexación</h3><p>Luego de definir el host remoto en el archivo elasticsearch.yml y agregar los certificados SSL si es necesario, puede comenzar a reindexar datos con el siguiente comando:</p>POST _reindex
{
  "source": {
    "remote": {
      "host": "http://192.168.1.11:9200",
      "username": "elastic",
      "password": "123456",
     "socket_timeout": "1m",
      "connect_timeout": "1m"

    },
    "index": "companydatabase"
  },
  "dest": {
    "index": "my-new-index-000001"
  }
}<p>Al hacerlo, es posible que se enfrente a errores de tiempo de espera, por lo que puede ser útil establecer valores generosos para los tiempos de espera en lugar de depender de los valores predeterminados.</p><p>Ahora, echemos un vistazo a algunos otros errores comunes que puede encontrar al reindexar desde el control remoto.</p><h3>Errores comunes al reindexar desde el control remoto</h3><h4>1. Reindexación no incluida en la lista blanca</h4>{
  "error": {
    "root_cause": [
      {
        "type": "illegal_argument_exception",
        "reason": "[192.168.1.11:9200] not whitelisted in reindex.remote.whitelist"
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "[192.168.1.11:9200] not whitelisted in reindex.remote.whitelist"
  },
  "status": 400
}<p>Si encuentra este error, muestra que no definió la dirección IP del host remoto o el nombre DNS del nodo en Elasticsearch como se describió anteriormente u olvidó resetear los servicios de Elasticsearch.</p><p>Para solucionar eso para el clúster de Elasticsearch, debe agregar el host remoto a todos los nodos de Elasticsearch y resetear los servicios de Elasticsearch.</p><h4>2. Excepción de protocolo de enlace SSL</h4>{
  "error": {
    "root_cause": [
      {
        "type": "s_s_l_handshake_exception",
        "reason": "PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target"
      }
    ],
    "type": "s_s_l_handshake_exception",
    "reason": "PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target",
    "caused_by": {
      "type": "validator_exception",
      "reason": "PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target",
      "caused_by": {
        "type": "sun_cert_path_builder_exception",
        "reason": "unable to find valid certification path to requested target"
      }
    }
  },
  "status": 500
}<p>Este error significa que olvidó agregar el reindex.ssl.certificate_authorities a elasticsearch.yml como se describió anteriormente. Para agregarlo:</p>#elasticsearch.yml
reindex.ssl.certificate_authorities: "/path/to/ca.pem"<h2>2. Transferencia de datos mediante instantáneas</h2><p>Recuerde, como se mencionó anteriormente, solo puede restaurar una instantánea en un clúster de una versión igual o superior y nunca con una diferencia de más de una versión principal</p><p>Si necesita aumentar en más de una versión principal, deberá volver a indexar o usar Logstash.</p><p>Se requieren los siguientes pasos para transferir datos a través de instantáneas:</p><p>Paso 1. Agregar el complemento del repositorio al primer clúster de Elasticsearch: para transferir datos entre clústeres a través de instantáneas, debe cerciorar de que se pueda acceder al repositorio tanto desde los clústeres nuevos como desde los antiguos. Los repositorios de espacio en la nube como AWS, Google y Azure son generalmente ideales para esto. Para tomar instantáneas, consulte <a href="https://www.elastic.co/es/guide/en/elasticsearch/reference/current/snapshot-restore.html">nuestra guía</a> y siga los pasos que describe.</p><p>Paso 2. Resetear el servicio Elasticsearch (resetear continuo).</p><p>Paso 3. Crea un repositorio para el primer cluster de Elasticsearch.</p><p>Paso 4- Agrega el plugin del repositorio al segundo clúster de Elasticsearch.</p><p>Paso 5: Agregar repositorio como de solo lectura al segundo clúster de Elasticsearch: deberá agregar un repositorio repitiendo los mismos pasos que realizó para crear el primer clúster de Elasticsearch.</p><p>Nota importante: Al conectar el segundo clúster de Elasticsearch al mismo repositorio de AWS S3, debe definir el repositorio como un repositorio de solo lectura:</p>PUT _snapshot/my_s3_repository
{
  "type": "s3",
  "settings": {
    "bucket": "my-analytic-data",
    "endpoint": "s3.eu-de.cloud-object-storage.appdomain.cloud",
    "readonly": "true"
  }
}<p>Esto es importante porque desea evitar el riesgo de mezclar versiones de Elasticsearch dentro del mismo repositorio de instantáneas.</p><p>Paso 6- Restauración de datos en el segundo clúster de Elasticsearch: luego de seguir los pasos anteriores, puede restaurar los datos y transferirlos al nuevo clúster. Siga los pasos descritos en <a href="https://www.elastic.co/es/guide/en/elasticsearch/reference/current/snapshot-restore.html">este artículo</a> para restaurar los datos en el nuevo clúster. </p><h2>3. Transferencia de datos mediante Logstash</h2><p>Antes de comenzar a transferir los datos con logstash, recuerde que deberá configurar las asignaciones adecuadas para todos los índices del nuevo clúster. Para ello, deberá crear los índices directamente o emplear plantillas de índice.</p><p>Para transferir datos entre dos clústeres de Elasticsearch, puedes configurar un servidor temporal de Logstash y usarlo para transferir tus datos entre dos clústeres. Para clústeres pequeños, una instancia de RAM de 2 GB debería ser suficiente. Para clústeres más grandes, puede usar CPU de cuatro núcleos con 8 GB de RAM.</p><p>Para obtener orientación sobre la instalación de Logstash, <a href="https://www.elastic.co/es/guide/en/logstash/current/installing-logstash.html">consulte aquí</a>.</p><h3>Configuración de Logstash para transferir datos de un clúster a otro</h3><p>Una configuración básica para copiar un solo índice del clúster A al clúster B es:</p>iinput
{
elasticsearch
      {
        hosts =&gt; ["192.168.1.11:9200"]
        index =&gt; "index_name"
       docinfo =&gt; true      
      }
}

output 
{
  elasticsearch {
        hosts =&gt; "https://192.168.1.12:9200"
        index =&gt; "index_name"
        
  }
}<p>Para elasticsearch seguro, puede usar la siguiente configuración:</p>input
{
  elasticsearch
      {
        hosts =&gt; ["192.168.1.11:9200"]
        index =&gt; "index_name"
        docinfo =&gt; true 
        user =&gt; "elastic"
        password =&gt; "elastic_password"
        ssl =&gt; true
        ssl_certificate_verification =&gt; false
            
      }
}

output 
{
  elasticsearch {
        hosts =&gt; "https://192.168.1.12:9200"
        index =&gt; "index_name"
        user =&gt; "elastic"
        password =&gt; "elastic_password"
        ssl =&gt; true
        ssl_certificate_verification =&gt; false
  }
}<h3>Metadatos de índice</h3><p>Los comandos anteriores escribirán en un único índice con nombre. Si desea transferir varios índices y conservar los nombres de índice, deberá agregar la siguiente línea a la salida de Logstash:</p>index =&gt; "%{[@metadata][_index]}"<p>Además, si desea conservar la identificación original del documento, deberá agregar:</p>document_id =&gt; "%{[@metadata][_id]}"<p>Tenga en cuenta que configurar el ID del documento hará que la transferencia de datos sea significativamente más lenta, así que solo conserve el ID original si es necesario.</p><h2>Sincronización de actualizaciones</h2><p>Todos los métodos descritos anteriormente tardarán un periodo de tiempo relativamente largo y es posible que los datos del clúster original se actualizaron mientras espera que se complete el proceso.</p><p>Existen varias estrategias para habilitar la sincronización de cualquier actualización que pueda ocurrir durante el proceso de transferencia de datos, y debe pensar en estos problemas antes de iniciar ese proceso. En individuo, debe pensar en:</p><ul><li><p>¿Qué método tiene para identificar cualquier dato que se actualizó/agregado desde el inicio del proceso de transferencia de datos (por ejemplo, un campo "last_update_time" en los datos)?</p></li><li><p>¿Qué método puede emplear para transferir el último dato?</p></li><li><p>¿Existe el riesgo de que se dupliquen los registros? Por lo general, lo hay, a menos que el método que está empleando establezca el ID del documento durante la reindexación en un valor conocido).</p></li></ul><p>A continuación se describen los diferentes métodos para habilitar la sincronización de actualizaciones.</p><h3>1. Uso de sistemas de colas</h3><p>Algunos sistemas de ingesta/actualización emplean colas que permiten "reproducir" las modificaciones de datos recibidas en los últimos x días. Eso puede proporcionar un medio para sincronizar cualquier cambio realizado. </p><h3>2. Reindexar desde remoto</h3><p>Repita el proceso de reindexación para todos los elementos en los que "last_update_time" &gt; hace x días. Para ello, agregue un parámetro "query" a la solicitud de reindexación.</p><h3>3. Logstash</h3><p>En la entrada de Logstash, puede agregar una consulta para filtrar todos los elementos donde "last_update_time" &gt; hace x días. Sin embargo, este proceso provocará duplicados en los datos que no sean de seriales temporales a menos que estableció el document_id.</p><h3>4. Instantáneas</h3><p>No es posible restaurar solo una parte de un índice, por lo que tendría que usar uno de los otros métodos de transferencia de datos descritos anteriormente (o un script) para actualizar los cambios que se produjeron desde que se llevó a cabo el proceso de transferencia de datos.</p><p>Sin embargo, la restauración de instantáneas es un proceso mucho más rápido que la reindexación/Logstash, por lo que puede ser posible suspender las actualizaciones durante un breve periodo de tiempo mientras se transfieren las instantáneas para evitar el problema por completo.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-migrate-data-versions-clusters</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-migrate-data-versions-clusters</guid>
    <category><![CDATA[Conceptos básicos]]></category>
    <dc:creator><![CDATA[Kofi Bartlett]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfc041ebca11476c6/6a16f70560084b31b93c4344/01fde3b1d714f12bf8673140c9f2f940d443de31-1440x823.jpg" length="0" type="image/jpeg"/>
    <pubDate>Mon, 14 Apr 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Cómo automatizar sinónimos y subir usando nuestra API de Sinónimos]]></title>
    <description><![CDATA[Descubre cómo los LLMs pueden usar para identificar y generar sinónimos automáticamente, permitiendo que los términos se carguen programáticamente en la API de sinónimos de Elasticsearch.]]></description>
    <content:encoded><![CDATA[<p>Mejorar la calidad de los resultados de búsqueda es esencial para ofrecer una experiencia de usuario eficiente. Una forma de optimizar las búsquedas es expandiendo automáticamente los términos consultados mediante sinónimos. Esto permite interpretar las consultas de forma más amplia, cubriendo variaciones lingüísticas y así mejorando la coincidencia de resultados.</p><p>Este blog explora cómo los grandes modelos de lenguaje (LLMs) pueden usar para identificar y generar sinónimos automáticamente, permitiendo que estos términos se carguen programáticamente en la API de sinónimos de Elasticsearch.</p><h2>¿Cuándo usar sinónimos?</h2><p>El uso de sinónimos puede ser una solución más rápida y rentable en comparación con la búsqueda vectorial. Su implementación es más sencilla ya que no requiere un conocimiento profundo de embeddings ni un proceso complejo de ingestión vectorial.</p><p>Además, el consumo de recursos es menor, ya que la búsqueda vectorial exige mayor capacidad de almacenamiento y memoria para incrustar, indexar y recuperar.</p><p>Otro aspecto importante es la regionalización de la búsqueda. Con los sinónimos, es posible adaptar términos según el idioma y las costumbres locales. Esto es útil en situaciones donde las incrustaciones pueden no coincidir con expresiones regionales o términos específicos de cada país. Por ejemplo, algunas palabras o siglas pueden tener significados diferentes según la región, pero los usuarios locales los tratan naturalmente como sinónimos. En Brasil, esto es bastante común. "Abacaxi" y "ananás" son la misma fruta (piña), pero el segundo término se usa más comúnmente en algunas regiones del noreste. De manera similar, el conocido "pão francês" en el sudeste puede ser conocido como "pão careca" en el noreste.</p><h2>¿Cómo usar los LLMs para generar sinónimos?</h2><p>Para obtener sinónimos automáticamente, podemos usar LLMs, que analizan el contexto de un término y sugieren variaciones apropiadas. Este enfoque permite expandir dinámicamente los sinónimos, cerciorando una búsqueda más amplia y precisa sin depender de un diccionario fijo.</p><p>En esta demostración, emplearemos un LLM para generar sinónimos de productos de comercio electrónico. Muchas búsquedas demuestran pocos o ningún resultado debido a las variaciones en los términos consultados. Con sinónimos, podemos resolver este problema. Por ejemplo, una búsqueda de "smartphone" puede abarcar diferentes modelos de teléfonos móviles, cerciorando que los usuarios encuentren los productos que buscan.</p><h3>Prerrequisitos</h3><p>Antes de empezar, necesitamos configurar el entorno y definir las dependencias necesarias. Emplearemos la solución proporcionada por Elastic para <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/run-elasticsearch-locally.html">ejecutar Elasticsearch y Kibana localmente en Docker</a>. El código estará escrito en Python, v3.9.6, con las siguientes dependencias:</p>pip install openai==1.59.8 elasticsearch==8.15.1<h3>Creación del índice de productos</h3><p>Inicialmente, crearemos un índice de productos sin soporte de sinónimos. Esto nos permitirá validar consultas y luego compararlas con un índice que incluya sinónimos.</p><p>Para crear el índice, cargamos en masa un conjunto de datos de producto usando el siguiente comando en Kibana DevTools:</p>POST _bulk
{"index": {"_index": "products", "_id": 10001}}
{"category": "Electronics", "name": "iPhone 14 Pro"}
{"index": {"_index": "products", "_id": 10007}}
{"category": "Electronics", "name": "MacBook Pro 16-inch"}
{"index": {"_index": "products", "_id": 10013}}
{"category": "Electronics", "name": "Samsung Galaxy Tab S8"}
{"index": {"_index": "products", "_id": 10037}}
{"category": "Electronics", "name": "Apple Watch Series 8"}
{"index": {"_index": "products", "_id": 10049}}
{"category": "Electronics", "name": "Kindle Paperwhite"}
{"index": {"_index": "products", "_id": 10067}}
{"category": "Electronics", "name": "Samsung QLED 4K TV"}
{"index": {"_index": "products", "_id": 10073}}
{"category": "Electronics", "name": "HP Spectre x360 Laptop"}
{"index": {"_index": "products", "_id": 10079}}
{"category": "Electronics", "name": "Apple AirPods Pro"}
{"index": {"_index": "products", "_id": 10115}}
{"category": "Electronics", "name": "Amazon Echo Show 10"}
{"index": {"_index": "products", "_id": 10121}}
{"category": "Electronics", "name": "Apple iPad Air"}
{"index": {"_index": "products", "_id": 10127}}
{"category": "Electronics", "name": "Apple AirPods Max"}
{"index": {"_index": "products", "_id": 10151}}
{"category": "Electronics", "name": "Sony WH-1000XM4 Headphones"}
{"index": {"_index": "products", "_id": 10157}}
{"category": "Electronics", "name": "Google Pixel 6 Pro"}
{"index": {"_index": "products", "_id": 10163}}
{"category": "Electronics", "name": "Apple MacBook Air"}
{"index": {"_index": "products", "_id": 10181}}
{"category": "Electronics", "name": "Google Pixelbook Go"}
{"index": {"_index": "products", "_id": 10187}}
{"category": "Electronics", "name": "Sonos Beam Soundbar"}
{"index": {"_index": "products", "_id": 10199}}
{"category": "Electronics", "name": "Apple TV 4K"}
{"index": {"_index": "products", "_id": 10205}}
{"category": "Electronics", "name": "Samsung Galaxy Watch 4"}
{"index": {"_index": "products", "_id": 10211}}
{"category": "Electronics", "name": "Apple MacBook Pro 16-inch"}
{"index": {"_index": "products", "_id": 10223}}
{"category": "Electronics", "name": "Amazon Echo Dot (4th Gen)"}<h3>Generación de sinónimos con LLM</h3><p>En este paso, emplearemos un LLM para generar sinónimos dinámicamente. Para lograrlo, integraremos la API de OpenAI, definiendo un modelo y un prompt apropiados. El LLM recibirá la categoría y el nombre del producto, cerciorando que los sinónimos sean relevantes en el contexto.</p>import json
import logging

from openai import OpenAI

def call_gpt(prompt, model):
    try:
        logging.info("generate synonyms by llm...")
        response = client.chat.completions.create(
            model=model,
            messages=[{"role": "user", "content": prompt}],
            temperature=0.7,
            max_tokens=1000
        )
        content = response.choices[0].message.content.strip()
        return content
    except Exception as e:
        logging.error(f"Failed to use model: {e}")
        return None

def generate_synonyms(category, products):
   synonyms = {}

   for product in products:
       prompt = f"You are an expert in generating synonyms for products. Based on the category and product name provided, generate synonyms or related terms. Follow these rules:\n"
       prompt += "1. **Format**: The first word should be the main item (part of the product name, excluding the brand), followed by up to 3 synonyms separated by commas.\n"
       prompt += "2. **Exclude the brand**: Do not include the brand name in the synonyms.\n"
       prompt += "3. **Maximum synonyms**: Generate a maximum of 3 synonyms per product.\n\n"
       prompt += f"The category is: **{category}**, and the product is: **{product}**. Return only the synonyms in the requested format, without additional explanations."

       response = call_gpt(prompt, "gpt-4o")
       synonyms[product] = response

   return synonyms<p>A partir del índice de productos creados, recuperaremos todos los artículos de la categoría "Electrónica" y enviaremos sus nombres al LLM. La salida esperada será algo así:</p>{
  "iPhone 14 Pro": ["iPhone", "smartphone", "mobile", "handset"],
  "MacBook Pro 16-inch": ["MacBook", "Laptop", "Notebook", "Ultrabook"],
  "Samsung Galaxy Tab S8": ["Tab", "Tablet", "Slate", "Pad"],
  "Bose QuietComfort 35 Headphones": ["Headphones", "earphones", "earbuds", "headset"]
}<p>Con los sinónimos generados, podemos registrarlos en Elasticsearch usando la API de Sinónimos.</p><h3>Gestión de sinónimos con la API de Sinónimos</h3><p>La API de Sinónimos proporciona una forma eficiente de gestionar conjuntos de sinónimos directamente dentro del sistema. Cada conjunto de sinónimos consiste en reglas de sinónimos, donde un grupo de palabras se considera equivalente en las búsquedas.</p><p><strong>Ejemplo de creación de un conjunto de sinónimos</strong></p>PUT _synonyms/my-synonyms-set
{
  "synonyms_set": [
    {
      "id": "rule-1",
      "synonyms": "hello, hi"
    },
    {
      "synonyms": "bye, goodbye"
    }
  ]
}<p>
Esto crea un conjunto llamado "mis-sinónimos-conjunto", donde "hola" y "hola" se tratan como equivalentes, así como "adiós" y "adiós".</p><h2>Implementación de la creación de sinónimos para el catálogo de productos</h2><p>A continuación se muestra el método responsable de construir un conjunto de sinónimos e insertarlo en Elasticsearch. Las reglas de sinónimos se generan a partir del mapeo de sinónimos sugerido por el LLM. Cada regla tiene un ID, correspondiente al nombre del producto en formato slug, y a la lista de sinónimos calculada por el LLM.</p>import json
import logging

from elasticsearch import Elasticsearch
from slugify import slugify

es = Elasticsearch(
    "http://localhost:9200",
    api_key="your_api_key"
)

def mount_synonyms(results):
   synonyms_set = [{"id": slugify(product), "synonyms": synonyms} for product, synonyms in
                   results.items()]

   try:
       response = es.synonyms.put_synonym(id="products-synonyms-set",
                                                 synonyms_set=synonyms_set)

       logging.info(json.dumps(response.body, indent=4))
       return response.body
   except Exception as e:
       logging.error(f"Error create synonyms: {str(e)}")
       return None<p>A continuación se muestra la carga útil de la solicitud para crear el conjunto de sinónimos:</p>{
   "synonyms_set":[
      {
         "id": "iphone-14-pro",
         "synonyms": "iPhone, smartphone, mobile, handset"
      },
      {
         "id": "macbook-pro-16-inch",
         "synonyms": "MacBook, Laptop, Notebook, Computer"
      },
      {
         "id": "samsung-galaxy-tab-s8",
         "synonyms": "Tablet, Slate, Pad, Device"
      },
      {
         "id": "garmin-forerunner-945",
         "synonyms": "Forerunner, smartwatch, fitness watch, GPS watch"
      },
      {
         "id": "bose-quietcomfort-35-headphones",
         "synonyms": "Headphones, Earphones, Headset, Cans"
      }
   ]
}<p>Con el conjunto de sinónimos creado en el clúster, podemos pasar al siguiente paso, que es crear un nuevo índice con soporte de sinónimos usando el conjunto definido.</p><p>El código completo en Python con los sinónimos generados por LLM y la creación de conjuntos de sinónimos definida por la API de Sinónimos es el siguiente:</p>import json
import logging

from elasticsearch import Elasticsearch
from openai import OpenAI
from slugify import slugify

logging.basicConfig(level=logging.INFO)

client = OpenAI(
   api_key="your-key",
)

es = Elasticsearch(
    "http://localhost:9200",
    api_key="your_api_key"
)


def call_gpt(prompt, model):
   try:
       logging.info("generate synonyms by llm...")
       response = client.chat.completions.create(
           model=model,
           messages=[{"role": "user", "content": prompt}],
           temperature=0.7,
           max_tokens=1000
       )
       content = response.choices[0].message.content.strip()
       return content
   except Exception as e:
       logging.error(f"Failed to use model: {e}")
       return None


def generate_synonyms(category, products):
   synonyms = {}

   for product in products:
       prompt = f"You are an expert in generating synonyms for products. Based on the category and product name provided, generate synonyms or related terms. Follow these rules:\n"
       prompt += "1. **Format**: The first word should be the main item (part of the product name, excluding the brand), followed by up to 3 synonyms separated by commas.\n"
       prompt += "2. **Exclude the brand**: Do not include the brand name in the synonyms.\n"
       prompt += "3. **Maximum synonyms**: Generate a maximum of 3 synonyms per product.\n\n"
       prompt += f"The category is: **{category}**, and the product is: **{product}**. Return only the synonyms in the requested format, without additional explanations."

       response = call_gpt(prompt, "gpt-4o")
       synonyms[product] = response

   return synonyms


def get_products(category):
   query = {
       "size": 50,
       "_source": ["name"],
       "query": {
           "bool": {
               "filter": [
                   {
                       "term": {
                           "category.keyword": category
                       }
                   }
               ]
           }
       }
   }
   response = es.search(index="products", body=query)

   if response["hits"]["total"]["value"] &gt; 0:
       product_names = [hit["_source"]["name"] for hit in response["hits"]["hits"]]
       return product_names
   else:
       return []


def mount_synonyms(results):
   synonyms_set = [{"id": slugify(product), "synonyms": synonyms} for product, synonyms in
                   results.items()]

   try:
       es_client = get_client_es()
       response = es_client.synonyms.put_synonym(id="products-synonyms-set",
                                                 synonyms_set=synonyms_set)

       logging.info(json.dumps(response.body, indent=4))
       return response.body
   except Exception as e:
       logging.error(f"Erro update synonyms: {str(e)}")
       return None


if __name__ == '__main__':
   category = "Electronics"
   products = get_products("Electronics")
   llm_synonyms = generate_synonyms(category, products)
   mount_synonyms(llm_synonyms)<h3>Creación de un índice con soporte de sinónimos</h3><p>Se creará un nuevo índice donde todos los datos del índice de <code>products</code> serán reindexados. Este índice usará la <code>synonyms_filter</code>, que aplica la <code>products-synonyms-set</code> creada anteriormente.</p><p>A continuación se muestra el mapeo de índices configurado para usar sinónimos:</p>PUT products_02
{
  "settings": {
    "analysis": {
      "filter": {
        "synonyms_filter": {
          "type": "synonym",
          "synonyms_set": "products-synonyms-set",
          "updateable": true
        }
      },
      "analyzer": {
        "synonyms_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "synonyms_filter"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "ID": {
        "type": "long"
      },
      "category": {
        "type": "keyword"
      },
      "name": {
        "type": "text",
        "analyzer": "standard",
        "search_analyzer": "synonyms_analyzer"
      }
    }
  }
}<h3>Reindexando el índice de <code>products</code></h3><p>Ahora, usaremos la <strong>API Reindex</strong> para migrar los datos del índice de <code>products</code> al nuevo índice de <code>products_02</code> , que incluye soporte para sinónimos. El siguiente código se ejecutó en Kibana DevTools:
</p>POST _reindex
{
  "source": {
    "index": "products"
  },
  "dest": {
    "index": "products_02"
  }
}<p>Tras la migración, el índice de <code>products_02</code> estará llenado y listo para validar búsquedas usando el conjunto de sinónimos configurado.</p><h3>Validación de la búsqueda con sinónimos</h3><p>Comparemos los resultados de búsqueda entre los dos índices. Ejecutaremos la misma consulta en ambos índices y validaremos si los sinónimos se están empleando para obtener resultados.</p><h4>Buscar en el índice de <code>products</code> (sin sinónimos)</h4><p>Emplearemos a Kibana para realizar búsquedas y analizar los resultados. En el menú de Analítica &gt; Descubrimiento, crearemos una Vista de Datos para visualizar los datos de los índices que creamos.</p><p>Dentro de Discovery, haz clic en Vista de datos y define un nombre y un patrón de índice. Para el índice de "<strong>productos</strong>", usaremos el patrón de "<strong>productos</strong>". Luego, repetiremos el proceso para crear una nueva Vista de Datos para el índice "<strong>products_02</strong>", usando el patrón "<strong>products_02".</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte826fd932cfeb9df/6a17fdffec0f8912aa5a6841/3ad4a6891a3905e96532a312932fdf3a8216aec2-1600x599.png" alt="" /><p>Con las Vistas de Datos configuradas, podemos volver a Analytics &gt; Discovery y comenzar las validaciones.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltba3729c60068e8a0/6a17fe01e9ea87ba2aa9c82a/422c4b2b51abae6580cad25085d1b8a365fc6b9e-1294x850.png" alt="" /><p>Aquí, tras seleccionar productos DataView y buscar el término "tablet", no obtenemos resultados, aunque sabemos que existen productos como "Kindle Paperwhite" y "Apple iPad Air".</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2c6a383dd4cb0157/6a17fe02577262671d1bce0c/e4ae3a785fdd93f48d7c7d204185ded149126f2c-1600x862.png" alt="" /><h4>Buscar en el índice de <code>products_02</code> (sinónimos de soporte)</h4><p>Al realizar la misma consulta en la Vista de Datos "<strong>products_synonyms</strong>", que soporta sinónimos, los productos se recuperaron con éxito. Esto demuestra que el conjunto de sinónimos configurado funciona correctamente, cerciorando que diferentes variaciones de los términos buscados devuelvan los resultados esperados.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt986b4706e2f70014/6a17fe043e9e454edbba16d3/e609749c39e90d5c82fa846af6124679dd62bcb8-1600x526.png" alt="" /><p>Podemos lograr el mismo resultado ejecutando la misma consulta directamente en Kibana DevTools. Simplemente busca en el índice de products_02 usando la API de búsqueda de Elasticsearch:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbe829a3c4d7aac60/6a17fe05e8fbce03d73a1bd7/504d0d1f96dcfbceb309063dc0716bcee64ad2f8-1600x870.png" alt="" /><h2>Conclusión</h2><p>La implementación de sinónimos en Elasticsearch mejoró la precisión y cobertura de las búsquedas en catálogos de productos. El diferenciador clave era el uso de un <strong>LLM</strong>, que generaba sinónimos automáticamente y contextualmente, eliminando la necesidad de listas predefinidas. El modelo analizó nombres y categorías de productos, cerciorando sinónimos relevantes para el comercio electrónico.</p><p>Además, la <strong>API de Sinónimos</strong> simplificó la gestión de diccionarios, permitiendo modificar dinámicamente los conjuntos de sinónimos. Con este enfoque, la búsqueda se volvió más flexible y adaptable a diferentes patrones de consulta de usuario.</p><p>Este proceso puede mejorar continuamente con nuevos datos y ajustes de modelos, cerciorando una experiencia de investigación cada vez más eficiente.</p><h2>Referencias</h2><p><strong>Ejecuta Elasticsearch localmente</strong></p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/run-elasticsearch-locally.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/run-elasticsearch-locally.html</a></p><p><strong>Sinónimos API</strong></p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/synonyms-apis.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/synonyms-apis.html</a></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-synonyms-automate</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-synonyms-automate</guid>
    <category><![CDATA[Relevancia]]></category>
    <category><![CDATA[Conceptos básicos]]></category>
    <dc:creator><![CDATA[Andre Luiz]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0f0247b9bc1d1ccd/6a17fe07ec0f891c745a6845/05a3cfeaa387561d5334ca3f1609035ddfff7481-1200x628.png" length="0" type="image/png"/>
    <pubDate>Thu, 27 Mar 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Logs y prosperidad: Modo de índice logsdb recientemente especializado de Elasticsearch]]></title>
    <description><![CDATA[La última innovación de Elasticsearch en gestión de logs, logsdb, reduce la huella de almacenamiento de los datos de logs hasta en un 65%, lo que permite a los equipos de observabilidad y seguridad ampliar la visibilidad sin exceder su cotización y, al mismo tiempo, mantener todos los datos accesibles y con capacidad de búsqueda.]]></description>
    <content:encoded><![CDATA[<h2>El nuevo modo de índice de Elasticsearch, logsdb, reduce las necesidades de almacenamiento de logs hasta en un 65 %</h2><p>Hoy, anunciamos la disponibilidad general del nuevo modo de índice de Elasticsearch, logsdb, que <strong>reduce la huella de almacenamiento de los datos de registro hasta en un 65%</strong> en comparación con las versiones recientes de Elasticsearch sin logsdb. Esta mejora sustancial permite a los equipos de observabilidad y seguridad ampliar la visibilidad sin exceder su cotización, al tiempo que mantienen todos los datos accesibles de inmediato para su análisis.</p><p>Logsdb optimiza el ordenamiento de los datos, elimina la duplicación al reconstruir los valores de los campos no almacenados sobre la marcha con <code>synthetic _source</code> y mejora la compresión con algoritmos y códecs avanzados, lo que aprovecha el almacenamiento columnar dentro de Elasticsearch para un almacenamiento y recuperación de logs eficientes.</p><h2>Mejora el análisis y reduce los costos mejorando la eficiencia del almacenamiento con el modo de índice logsdb</h2><p>Los logs proporcionan señales críticas para detectar y remediar problemas de observabilidad y seguridad, y su utilidad está aumentando a medida que los avances en AI facilitan el análisis de datos basados en texto, por lo que el almacenamiento eficiente y el acceso de alto rendimiento son más importantes que nunca.</p><p>Lamentablemente, el creciente volumen de logs generado por la infraestructura y las aplicaciones está aumentando los costos, lo que obliga a compromisos que dificultan el análisis: limitar la recopilación, reducir la retención o relegar los datos nuevos a niveles de archivo en silos.</p><p>Logsdb aborda directamente estos desafíos. Con una mayor eficiencia de almacenamiento, puedes recopilar más datos y evitar la molestia del filtrado complicado de datos. Puedes conservar los logs por más tiempo para apoyar la búsqueda de amenazas, la respuesta a incidentes y los requisitos de cumplimiento. Y porque todos los datos siempre se pueden buscar, puedes obtener información rápida, sin importar cuánto crezca tu set de datos.</p><h2>Innovación técnica detrás del modo de índice logsdb</h2><p>El modo de índice de logsdb reduce drásticamente la huella de disco de los datos de logs con clasificación de índices inteligente, synthetic _source y compresión avanzada. Implementarlo puede reducir las necesidades de almacenamiento de logs hasta en un 65 %, en comparación con versiones recientes de Elasticsearch sin logsdb. Aunque logsdb actualmente utiliza más CPU durante la indexación, su almacenamiento eficiente reduce los costos generales para la mayoría de los clientes. Para los clientes que necesitan retención a largo plazo, esperamos reducciones del costo total de propiedad (TCO) de hasta un 50 %.</p><p><strong>La clasificación inteligente de índices</strong> mejora la eficiencia del almacenamiento hasta en un 30% y reduce la latencia de las consultas en algunos conjuntos de datos de registro al ubicar datos similares muy juntos. De forma predeterminada, ordena los índices por host.name y @timestamp. Si los datos tienen campos más adecuados, puede especificarlos en su lugar.</p><p><strong>La compresión avanzada</strong> reduce significativamente los requisitos de almacenamiento para datos con mucho texto, como registros a través de la compresión Zstandard (Zstd), la codificación delta, la codificación de longitud de ejecución y otros códecs inteligentes que se eligen automáticamente. Los valores de documento, que se almacenan en un formato de columnas optimizado para la compresión y el rendimiento, permiten el almacenamiento y la recuperación eficientes de valores de campo para ordenar, agregar y crear secuencias de comandos.</p><p><strong>El _source sintético</strong> permite a las organizaciones recortar las necesidades de almacenamiento en otro 20-40% al descartar el campo _source y reconstruirlo total o parcialmente bajo demanda. Si bien la función a veces requiere más computación para la indexación y la recuperación, las pruebas muestran que ofrece mejoras medibles en la eficiencia neta. Synthetic _source se basa en casi dos años de uso de producción con métricas, con numerosas mejoras para los registros, incluida la compatibilidad con casi todos los tipos de campos.</p><p>Los ahorros de almacenamiento resultantes se propagan a través de las fases del ciclo de vida del índice. Una reducción del 65 % en el almacenamiento del nivel caliente tendrá como resultado la misma reducción en los niveles tibio, frío y congelado, así como reducirá el espacio ocupado para almacenar snapshots en el almacenamiento en cubetas.</p><h2>No se compromete la visibilidad: Conservar todos los logs para la observabilidad y la seguridad</h2><p>Los logs son la base de la visibilidad en la infraestructura y las aplicaciones, proporcionando la señal más simple y esencial para el monitoreo y la solución de problemas. Sin embargo, los costos aumentan a medida que crecen los volúmenes de logging. Este desafío está obligando a los clientes a implementar políticas complejas de filtrado y gestión, eliminar datos antes de tiempo y dejar los logs relevantes en almacenes que requieren de un día o más para rehidratarse antes del análisis. Sin un set de datos completo, fácil de buscar y accesible, encontrar y resolver problemas es sustancialmente más desafiante.</p><p>El modo de índice de Logsdb se basa en capacidades innovadoras de Elasticsearch, como <a href="https://www.elastic.co/es/elasticsearch/elasticsearch-searchable-snapshots">snapshots con capacidad de búsqueda</a> e <a href="https://www.elastic.co/es/blog/automatic-import-ai-data-integration-builder">importación automática</a> , para abordar estos puntos débiles para los equipos de operaciones y seguridad:</p><p><strong>Reducir costos: </strong>Logsdb reduce la huella de almacenamiento de los registros hasta en un 65%, lo que permite a las organizaciones reducir los gastos de almacenamiento mientras retienen más datos. Esto se traduce en ahorros de costos en todos los niveles de almacenamiento, desde caliente hasta congelado, y una mayor productividad para los equipos de observabilidad y seguridad que emplean estos datos.</p><p><strong>Conserve los datos valiosos: </strong>Logsdb mantiene todos sus datos de registro y mejora la eficiencia operativa sin depender de herramientas adicionales o filtros complicados. Con características como la _source sintética, conserve el valor de los datos sin almacenar todo el documento de origen.</p><p><strong>Ampliar visibilidad:</strong> Logsdb proporciona un acceso eficiente a todos los datos en una plataforma, sin aislamiento separado para la observabilidad, la seguridad y los datos históricos. Para los ingenieros de confiabilidad del sitio (SRE), acelera la resolución de problemas al permitir el análisis de registros junto con métricas, seguimientos y datos comerciales. Del mismo modo, para los equipos del centro de operaciones de seguridad (SOC), acelera la investigación y la corrección al eliminar los puntos ciegos.</p><p><strong>Optimice el acceso a los datos:</strong> Logsdb permite a los equipos de SRE retener de manera eficiente datos procesables para la resolución de problemas, tendencias y análisis. Del mismo modo, los equipos de SOC pueden buscar rápidamente todos sus datos para la investigación y la búsqueda de amenazas sin incurrir en costos exorbitantes.</p><h2>Logsdb está listo para su entorno</h2><p>El modo de índice de logsdb de Elasticsearch está disponible de forma general para los clientes alojados y autogestionados de Elastic Cloud a partir de la versión 8.17 y está habilitado de forma predeterminada para los logs en <a href="https://www.elastic.co/es/elasticsearch/serverless">Elastic Cloud Serverless</a>.</p><p>Las capacidades básicas de logsdb (incluida la clasificación de índices inteligente y la compresión avanzada) están disponibles para organizaciones con licencias Estándar, Oro y Platino. Las capacidades completas de logsdb que reducen aún más los requisitos de almacenamiento (incluido synthetic _source) están disponibles para los clientes sin servidor y las organizaciones con una licencia Empresarial.</p><h2>Elasticsearch logsdb en acción</h2><p>Logsdb te permite mantener todos tus datos de logs y mejorar la eficiencia operativa sin limitar la recopilación, descartar o aislar datos. Con capacidades como la clasificación de índices inteligente, la compresión avanzada y synthetic _source, conserva y analiza los datos que necesitas dentro de un presupuesto que funcione para ti.</p><p>¿Quieres experimentarlo por ti mismo? <a href="https://cloud.elastic.co/registration">Prueba Elastic sin costo</a>.</p><p><em>El lanzamiento y el momento de cualquier característica o funcionalidad descrita en esta publicación quedan a exclusivo criterio de Elastic. Es posible que cualquier característica o funcionalidad que no esté disponible en este momento no se lance a tiempo o no se lance en absoluto.</em></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-logsdb-index-mode</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-logsdb-index-mode</guid>
    <category><![CDATA[Conceptos básicos]]></category>
    <dc:creator><![CDATA[Mark Settle,George Kobar,Amena Siddiqi]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt982a3c761d66169f/6a17de7c7b54f9788d8b37ff/d3daacafea7a1d78c825a18f8281460c7106d3a5-721x420.png" length="0" type="image/png"/>
    <pubDate>Thu, 12 Dec 2024 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Implementación de búsqueda semántica: Construcción de una búsqueda de recetas con Elasticsearch]]></title>
    <description><![CDATA[Implementación de la búsqueda semántica en el contexto de sitios web de comercio electrónico.]]></description>
    <content:encoded><![CDATA[<h2>Introducción</h2><p>Muchos sitios web de comercio electrónico están interesados en mejorar su experiencia de búsqueda de recetas. La búsqueda semántica, cuando se aplica correctamente, permite a los clientes encontrar rápidamente los ingredientes necesarios basar en consultas más naturales, como "algo para Santo Valentín" o "comidas de Acción de Gracias".</p><p>En este artículo, demostraremos cómo usar Elasticsearch para implementar una búsqueda semántica que soporte este tipo de consultas. Configuraremos un índice para almacenar el catálogo de ingredientes y productos de un supermercado y demostraremos cómo este índice puede emplear para mejorar la búsqueda de recetas. A lo largo del artículo, explicaremos cómo crear esta estructura de datos y aplicar técnicas de procesamiento de lenguaje natural para proporcionar resultados relevantes alineados con la intención del cliente.</p><p>Todo el código presentado en este artículo fue desarrollado en Python y está disponible en <a href="https://github.com/elastic/elasticsearch-labs/tree/main/supporting-blog-content/building-a-recipe-search-with-elasticsearch">GitHub</a>. Puedes acceder al repositorio para revisar el código fuente, hacer ajustes según sea necesario e implementar las soluciones directamente en tu entorno de desarrollo.</p><h2>Inicio de la implementación de la búsqueda semántica</h2><p>Para empezar a implementar la búsqueda semántica, primero necesitamos definir el modelo del lenguaje natural. Elastic proporciona su propio modelo, <a href="https://www.elastic.co/guide/en/machine-learning/8.15/ml-nlp-elser.html"><strong>ELSER</strong></a>, pero también ofrece soporte para integrar modelos de PLN de varios proveedores, como Hugging Face. Esta flexibilidad te permite elegir la opción que mejor se adapte a tus necesidades.</p><p>En este artículo, emplearemos <strong>ELSER</strong>, que reduce la complejidad de desplegar y gestionar modelos de PLN. Además, Elastic ofrece la <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search-semantic-text.html"><strong>función semantic_text</strong></a> , que simplifica mucho el proceso. Con <strong>semantic_text</strong>, todo el proceso de generación de incrustaciones se vuelve sencillo y automatizado. Simplemente necesitas definir un punto de inferencia y especificar el campo que recibirá las incrustaciones en tu mapeo de índice. Durante la indexación de documentos, se generarán incrustaciones que se asociarán automáticamente con el campo especificado.</p><h3>Pasos de preparación</h3><p>A continuación se muestran los pasos para crear un índice con soporte para búsqueda semántica. Siguiendo estas instrucciones, tendrás un índice configurado y listo para búsquedas semánticas:</p><ol><li><p><strong>Crea el </strong><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/infer-service-elser.html"><strong>punto de inferencia</strong></a>.</p></li><li><p><a href="https://github.com/andreluiz1987/semantic-search-market/blob/main/infra.py"><strong>Crea el índice</strong></a>, configurando el campo de descripción como semantic_text para que pueda recibir las incrustaciones.</p></li><li><p><a href="https://github.com/andreluiz1987/semantic-search-market/blob/main/ingestion.py"><strong>Indexa los datos</strong></a> en el índice de catálogos de supermercados, que almacenará un catálogo de productos. Este catálogo se obtuvo a partir de un conjunto de datos disponible <a href="https://www.kaggle.com/datasets/bhavikjikadara/grocery-store-dataset?select=GroceryDataset.csv">aquí</a>.</p></li></ol><h2>Aplicación de la búsqueda semántica en supermercados</h2><p>Ahora que tenemos el índice lleno de datos de productos de supermercados, estamos probando y validando consultas para mejorar los resultados de búsqueda usando búsqueda semántica. Nuestro objetivo es ofrecer una experiencia de búsqueda más inteligente que entienda el contexto y la intención del usuario, ofreciendo resultados más relevantes y precisos.</p><h3>Desafíos resueltos por la búsqueda semántica</h3><p>Basándonos en el catálogo de productos, exploremos cómo la búsqueda semántica puede transformar la experiencia de búsqueda en supermercados abordando cuestiones de vocabulario y contexto con las que la búsqueda léxica tradicional a menudo tiene dificultades.</p><h4><strong>1. Interpretación de intenciones culinarias</strong></h4><p><strong>Problema 01</strong>: Un cliente puede buscar "marisco para asar", pero un sistema de búsqueda léxica puede no comprender completamente la intención detrás de la consulta. Podría no identificar todos los productos de marisco aptos para asar, devolviendo solo aquellos con el término exacto "marisco" o "parrilla" en el título del producto.</p><p>Primero, realizaremos una búsqueda léxica y analizaremos los resultados. Luego, haremos lo mismo con una búsqueda semántica, comparando los resultados del mismo término de búsqueda.</p><p><strong>Consulta de búsqueda léxica</strong></p> response = client.search(
        index="grocery-catalog",
        size=5,
        source_excludes="description_embedding",
        query={
            "multi_match": {
                "query": "seafood for grilling",
                "fields": [
                    "name",
                    "description"]
            }
        }
    )<p><strong>Resultados:</strong></p><p>Tipo de búsqueda</p><p>Nombre</p><p>Puntaje</p><p>Léxico</p><p>Pescado del Noroeste del Cangrejo de las Nieves Bairdi de Alaska</p><p>10.453125</p><p>Léxico</p><p>Salsa Gourmet original del señor Yoshida.</p><p>7.2289705</p><p>Léxico</p><p>Pack Premium de Mariscos - 20 piezas</p><p>7.1924105</p><p>Léxico</p><p>Pargo rojo americano - entero, de frente, limpiado</p><p>6.998647</p><p>Léxico</p><p>Pinzas y brazos de langosta, capturados en la naturaleza sostenible</p><p>6.438654</p><p>La búsqueda léxica demostró algunos productos de marisco aptos para asar, como el pargo rojo americano y el cangrejo de nieve bairdi de Alaska de pesca del noroeste. Sin embargo, la búsqueda léxica devolvía productos menos relevantes en la parte superior de la lista, como la salsa Mr. Yoshida, que no es un producto de marisco sino una salsa de carne, lo que sugiere que el algoritmo léxico tuvo dificultades para comprender completamente el contexto de "para asar".</p><p><strong>Solución de búsqueda semántica</strong></p><p>Empleamos una consulta que combina el término "marisco" con contextos de preparación como "asar" para devolver una lista completa de opciones, como filetes de pescado, gambas y vieiras, que son ideales para asar a la parrilla, aunque las palabras "parrilla" o "marisco" no aparezcan directamente en el nombre del producto. Esto cerciora que los resultados de búsqueda se alineen más estrechamente con la intención del cliente.</p><p><strong>Consulta búsqueda semántica:</strong></p>es_client.search(
   index="grocery-catalog-elser",
   size=size,
   source_excludes="description_embedding",
   query={
       "semantic": {
           "field": "description_embedding",
           "query": "seafood for grilling"

       }
   })<p>Tipo de búsqueda</p><p>Nombre</p><p>Puntaje</p><p>Semántica</p><p>Pescado branzino completamente de cabeza</p><p>16.175909</p><p>Semántica</p><p>Bacalao negro de Alaska (pez sable)</p><p>15.855331</p><p>Semántica</p><p>Pargo rojo americano - entero, de frente</p><p>15.454779</p><p>Semántica</p><p>Pescado del Noroeste del Cangrejo de las Nieves Bairdi de Alaska</p><p>15.855331</p><p>Semántica</p><p>Pargo rojo americano - entero, de frente</p><p>15.3892355</p><p>La búsqueda semántica no solo devolvía productos directamente relacionados con el término "marisco", sino que también entendía el contexto de "asar", sacando pescado entero y filetes adecuados para asar. La clave aquí es la precisión de los resultados, que incluían opciones de pescado entero como branzino y bacalao negro de Alaska, ambos comúnmente usados para asar a la parrilla.</p><p><strong>Problema 02 </strong>: Muchos clientes buscan soluciones rápidas y fáciles para cenar tras un largo día de trabajo, usando términos como "comidas fáciles entre semana". La búsqueda léxica tradicional puede no captar completamente el concepto de comidas rápidas, ya que a menudo se centra solo en productos que incluyen la palabra "easy" en su nombre.</p><p>Como hicimos en el problema anterior, comenzaremos realizando una búsqueda léxica. Luego de eso, aplicaremos una solución usando búsqueda semántica.</p><p><strong>Consulta de búsqueda léxica</strong></p> response = client.search(
        index="grocery-catalog",
        size=5,   
        source_excludes="description_embedding",
        query={
            "multi_match": {
                "query": "easy weeknight meals",
                "fields": [
                    "name",
                    "description"]
            }
        }
    )<p><strong>Resultados:</strong></p><p>Tipo de búsqueda</p><p>Nombre</p><p>Puntaje</p><p>Léxico</p><p>Etiquetas de dirección Avery Easy Peel, 4200</p><p>8.017723</p><p>Léxico</p><p>Omeals Comidas de Emergencia/Portátiles con Autocalentamiento 32</p><p>6.592727</p><p>Léxico</p><p>Pesquero costero atún amarillo en cubos</p><p>5.836883</p><p>Léxico</p><p>Espuma de 12 oz de súper peso</p><p>5.8116536</p><p>Léxico</p><p>Servilleta de Vanity Fair para el día a día, 2 capas, 110</p><p>5.752989</p><p>La búsqueda léxica devolvió resultados mucho menos relevantes, incluyendo elementos completamente ajenos a las comidas, como las etiquetas de dirección Avery Easy Peel y las servilletas cotidianas de Vanity Fair. Estos productos no satisfacen la necesidad del usuario de comidas rápidas. Aunque la búsqueda léxica sí devolvió un producto útil (Omeals Self Heating Emergency Meals), otros resultados, como servilletas y etiquetas, solo coincidían con las palabras "fácil" o "noche de semana" en sus descripciones, sin abordar realmente la intención del usuario de una solución de comida rápida.</p><p><strong>Solución de búsqueda semántica</strong></p><p>Implementamos una consulta que entiende la intención detrás de comidas rápidas y sencillas. Asocia productos que pueden preparar rápidamente, como carnes precocinadas, pasta congelada o kits de comida, aunque no incluyan explícitamente la palabra "fácil" en el nombre. Este enfoque garantiza que los clientes encuentren las opciones más adecuadas para cenas rápidas entre semana, atendiendo la necesidad de comodidad.</p><p><strong>Consulta a la búsqueda semántica</strong></p>es_client.search(
   index="grocery-catalog-elser",
   size=size,
   source_excludes="description_embedding",
   query={
       "semantic": {
           "field": "description_embedding",
           "query": "easy weeknight meals"

       }
   })<p><strong>Resultados:</strong></p><p>Tipo de búsqueda</p><p>Nombre</p><p>Puntaje</p><p>Semántica</p><p>Omeals Comidas de Emergencia/Portátiles con Autocalentamiento 32</p><p>14.610006</p><p>Semántica</p><p>Nissin, Cup Noodles, Gambas, 2,5 oz</p><p>13.751424</p><p>Semántica</p><p>Mezcla de gofres y panqueques sin gluten de Namaste</p><p>13.73376</p><p>Semántica</p><p>Papa de Idaho, papa hashbrowns Golden Grill</p><p>12.549422</p><p>Semántica</p><p>Nissin, Fideos en Taza, Pollo, 24-Count</p><p>12.034527</p><p>La búsqueda semántica devolvió productos claramente relacionados con comidas rápidas y convenientes, como fideos instantáneos (Cup Noodles), papa precocinadas y mezclas para panqueques, que son opciones típicas para cenas fáciles entre semana. Esto demuestra que la búsqueda semántica puede captar el concepto detrás de la frase "comidas fáciles entre semana", captando la intención del usuario de encontrar comidas rápidas y convenientes. Curiosamente, productos de otras categorías, como "refrescos", también pueden incluir cuando sea relevante en el contexto (por ejemplo, bebidas para acompañar las comidas).</p><h4><strong>2. Términos regionales y variaciones de vocabulario</strong></h4><p><strong>Problema</strong>: Un cliente puede buscar "refresco", mientras que otro cliente podría usar "refresco" para el mismo producto. La búsqueda léxica tradicional no reconoce que ambos términos se refieren al mismo elemento.</p><p><strong>Consulta de búsqueda léxica</strong></p> response = client.search(
        index="grocery-catalog",
        size=5,
        source_excludes="description_embedding",
        query={
            "multi_match": {
                "query": "refreshing pop drink low sugar",
                "fields": [
                    "name",
                    "description"]
            }
        }
    )<p><strong>Resultados:</strong></p><p>Tipo de búsqueda</p><p>Nombre</p><p>Puntaje</p><p>Léxico</p><p>Prime Hydration+ Sticks mezcla de bebidas electrolíticas</p><p>14.492869</p><p>Léxico</p><p>Capri Sun, 100% jugo, paquete variado</p><p>12.340851</p><p>Léxico</p><p>Bebida energética Joyburst, Frose Rose, 12</p><p>11.839179</p><p>Léxico</p><p>Kellogg's Pop-Tarts, canela glaseada con azúcar moreno</p><p>9.97788</p><p>Léxico</p><p>Mini barras Kind, pack variado, 0,7</p><p>9.336912</p><p>La búsqueda léxica se centra en coincidencias exactas de palabras. Aunque devolvió productos como Prime Hydration y Capri Sun, la coincidencia directa con el término "pop" también llevó a resultados irrelevantes, como los Kellogg's Pop-Tarts, que son un tentempié y no una bebida. Esto pone de manifiesto cómo la búsqueda léxica puede ser menos efectiva cuando un término tiene múltiples significados o puede ser ambiguo.</p><p><strong>Solución de búsqueda semántica</strong></p><p>En consultas semánticas, podemos superar el problema de las variaciones de vocabulario que la búsqueda léxica no aborda. Al ampliar los términos de búsqueda, podemos obtener resultados basados en el significado contextual, proporcionando respuestas más relevantes y completas.</p><p><strong>Consulta:</strong></p>es_client.search(
   index="grocery-catalog-elser",
   size=size,
   source_excludes="description_embedding",
   query={
       "semantic": {
           "field": "description_embedding",
           "query": "refreshing pop drink low sugar"

       }
   })<p><strong>Resultados:</strong></p><p>Tipo de búsqueda</p><p>Nombre</p><p>Puntaje</p><p>Semántica</p><p>Variedad de refrescos Prebióticos de 12 oz de Olipop</p><p>14.776867</p><p>Semántica</p><p>Bai Antioxidant Cocofusion, Pack de variedades, 18</p><p>14.663253</p><p>Semántica</p><p>Bebida energética Monster, Zero Ultra, 24</p><p>14.486348</p><p>Semántica</p><p>Joyburst Variedad de Energía, 12 fl oz</p><p>14.007214</p><p>Semántica</p><p>Bebida energética Joyburst, Frose Rose, 12</p><p>13.641038</p><p>La búsqueda semántica devuelve productos que coinciden directamente con el concepto de "pop" como sinónimo de "refresco" (como Olipop Prebiotics Soda), aunque el término exacto "pop" no esté presente en el nombre del producto. La búsqueda entendió la intención del usuario — una bebida refrescante y baja en azúcar — y pudo devolver productos relevantes, incluyendo opciones como refrescos prebióticos (Olipop) y bebidas energéticas sin azúcar (Monster Energy Drink).</p><h2>Conclusión</h2><p>La implementación de la búsqueda semántica en el contexto de supermercados demostró ser muy eficaz para entender consultas complejas como "marisco para asar" y "comidas fáciles entre semana". Este enfoque nos permitió interpretar la intención del usuario con mayor precisión, devolviendo productos altamente relevantes.</p><p>Al usar Elasticsearch y simplificar el proceso con ELSER, pudimos aplicar la búsqueda semántica de forma rápida y eficiente, mejorando significativamente los resultados y proporcionando una experiencia de compra más ágil y dirigida. Esto no solo optimizó el proceso de búsqueda, sino que también aumentó la relevancia de los resultados ofrecidos a los clientes.</p><h2>Referencias</h2><p>Modelo ELSER:</p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/put-inference-api.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/put-inference-api.html</a></p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/infer-service-elser.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/infer-service-elser.html</a></p><p></p><p>Texto semántico:</p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-text.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-text.html</a></p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search.html</a></p><p></p><p>Conjunto de datos:</p><p><a href="https://www.kaggle.com/datasets/bhavikjikadara/grocery-store-dataset?select=GroceryDataset.csv">https://www.kaggle.com/datasets/bhavikjikadara/grocery-store-dataset?select=grocerydataset.csv</a></p><p></p><p>Búsqueda semántica:</p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search.html</a></p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search-semantic-text.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search-semantic-text.html</a></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/semantic-search-elasticsearch-ecommerce</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/semantic-search-elasticsearch-ecommerce</guid>
    <category><![CDATA[Conceptos básicos]]></category>
    <dc:creator><![CDATA[Andre Luiz]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5c545fc80b6d79d6/6a170214839dfad776dcfd6f/d968e646240cd3ef7c79b5124d562a5f951d812b-1440x840.png" length="0" type="image/png"/>
    <pubDate>Thu, 07 Nov 2024 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>