<?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[Les bases - 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[Les bases - Elasticsearch Labs]]></title>
      <url>https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1121c0bf0e8a6e65/6a88da6340a1841030ef456f/search-labs-thumbnail.png</url>
      <link>https://www.elastic.co/fr/search-labs/blog/category/basics</link>
    </image>
    <link>https://www.elastic.co/fr/search-labs/blog/category/basics</link>
    <atom:link href="https://www.elastic.co/fr/search-labs/rss/category/basics.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[fr]]></language>
    <lastBuildDate>Tue, 22 Sep 2026 22:17:50 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Comment déployer Elasticsearch sur Azure AKS Automatic]]></title>
    <description><![CDATA[Découvrez comment déployer Elasticsearch avec Kibana sur Azure en utilisant AKS Automatic et ECK pour une configuration Elasticsearch partiellement gérée.]]></description>
    <content:encoded><![CDATA[<p>Cet article fait partie d'une série où nous apprendrons comment installer Elasticsearch en utilisant différentes infrastructures.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt45071aec499098c0/6a17fe770b0beda3d1dd37f4/0a65ca8b62fd8a42d7751b8f4bf057e33d877304-940x458.png" alt="Efforts de déploiement d'Elasticsearch" /><p>ECK demande nettement plus d'efforts que les solutions Elastic Cloud basées sur la Marketplace, mais il est plus automatisé que le déploiement de VM par vous-même, car l'opérateur Kubernetes s'occupera de l'orchestration du système et de la mise à l'échelle des nœuds.</p><p>Cette fois, nous allons travailler avec le service Azure Kubernetes (AKS), en utilisant Automatic. Dans les autres articles, vous apprendrez à utiliser <a href="https://www.elastic.co/search-labs/blog/azure-elasticsearch-vm-deployment">Azure VM</a> et <a href="https://www.elastic.co/search-labs/blog/deploy-elasticsearch-azure-marketplace">Azure Marketplace</a>.</p><h2>Qu'est-ce qu'AKS Automatic ?</h2><p><a href="https://learn.microsoft.com/en-us/azure/aks/intro-aks-automatic">Azure Kubernetes Service (AKS) </a>gère automatiquement la configuration des clusters, alloue dynamiquement les ressources et intègre les meilleures pratiques de sécurité tout en préservant la flexibilité de Kubernetes, ce qui permet aux développeurs de passer d'une image de conteneur à une application déployée en quelques minutes.</p><p>AKS Automatic supprime la plupart des frais généraux liés à la gestion des clusters et offre un bon équilibre entre simplicité et flexibilité. Le bon choix dépend de votre cas d'utilisation, mais la décision est plus facile à prendre si vous prévoyez de le faire :</p><ul><li><p><strong>Déployer un environnement de test : </strong>Le déploiement est rapide et simple, ce qui le rend idéal pour les expériences rapides ou les clusters de courte durée.</p></li><li><p><strong>Travaillez sans exigences strictes en matière de VM, de stockage ou de réseau : </strong>AKS Automatic fournit des valeurs par défaut prédéfinies, de sorte que si celles-ci correspondent à vos besoins, vous n'avez pas besoin d'une configuration supplémentaire.</p></li><li><p><strong>Commencez avec Kubernetes pour la première fois : </strong>En prenant en charge une grande partie de la configuration du cluster, AKS Automatic réduit la courbe d'apprentissage et permet aux équipes de se concentrer sur leurs applications.</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9e74556cda9b56bd/6a17fe791d1b830cdc93e681/2e4c09b8c5e0ce5e8ea9c369626a373b7030a5ba-854x489.png" alt=" Comment créer un cluster automatique Azure Kubernetes Service (AKS) ?" /><p>Pour Elasticsearch, nous allons utiliser <a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s">Elastic Cloud on Kubernetes </a>(ECK), qui est l'opérateur officiel d'Elastic Kubernetes qui simplifie l'orchestration des déploiements Kubernetes de la pile Elastic.</p><h2>Comment configurer AKS Automatic</h2><p>1. Connectez-vous au <a href="https://azure.microsoft.com/">portail Microsoft Azure</a>.</p><p>2. En <strong>haut à droite, </strong>cliquez sursur le bouton<strong> Cloud Shell</strong> pour accéder à la console et déployer le cluster AKS à partir de là. Vous pouvez également utiliser <a href="https://learn.microsoft.com/en-us/azure/cloud-shell/overview">Azure Cloud Shell</a>.</p><p><em><strong>N'oubliez pas de mettre à jour l'identifiant du projet avec le vôtre pendant le tutoriel.</strong></em></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt06acd165140f9ab5/6a17fe7ae9ea876604a9c849/0aa60605777c0a6e3aef8faa4e54388c2cb582c8-624x495.png" alt="" /><p><em>L'ouverture de l'AKS devrait ressembler à la capture d'écran ci-dessus.</em></p><p>3. Installez l'extension aks-preview Azure CLI. Cette version preview nous permettra de sélectionner <code>--sku automatic</code> lors de la création du cluster, ce qui activera la fonction AKS Automatic.</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 vous voyez ce message, cela signifie que l'extension AKS a été installée correctement.</em></p><p>4. Enregistrer les<a href="https://learn.microsoft.com/en-us/azure/azure-app-configuration/concept-feature-management"> indicateurs de caractéristiques à</a> l'aide de la commande <code>az feature register</code></p>az feature register --namespace Microsoft.ContainerService --name AutomaticSKUPreview<p><em>Vous verrez les détails de l'abonnement de fonctionnalité que nous venons de créer :</em></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt024ca2930c3a02e3/6a17fe7ee9ea87e003a9c84d/3aca710c1f312ba91de461638e518386919ec722-801x138.png" alt="" /><p>Vérifiez l'état de l'enregistrement jusqu'à ce qu'il passe de "<em><strong>En cours d'enregistrement</strong></em>" à "<em><strong>Enregistré</strong></em>". L'enregistrement peut prendre quelques minutes.</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>Exécutez <code>az provider register</code> pour propager les modifications.</p>az provider register --namespace Microsoft.ContainerService<p>5. Créer un groupe de ressources</p><p>Un groupe de ressources est un groupe logique de ressources Azure à gérer et à déployer.</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. Créez un cluster Autopilot. Nous le nommerons <em><strong>myAKSAutomaticCluster </strong></em>et utiliserons le groupe de ressources que nous venons de créer. Assurez-vous d'avoir <em><strong>16 vCPUs</strong></em> disponibles sur l'une des tailles de VM suivantes : <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> pour qu'AKS alloue des ressources.</p>az aks create \
    --resource-group elastic-resource \
    --name myAKSAutomaticCluster \
    --sku automatic \
    --generate-ssh-keys<p>* <em>Si vous obtenez des </em><em> erreurs </em><em><code>MissingSubscriptionRegistration</code></em>, revenez à l'étape 4 avec les abonnements manquants. Par exemple , <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> nécessite l'exécution de </em><em><code>az provider register --namespace Microsoft.Insights.</code></em></p><p>Suivez la connexion interactive :</p><p><em>Un message demandant d'exécuter "az login" s'affiche. Vous devez exécuter cette commande et attendre.</em></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc711a241388cf786/6a17fe83dbb4fff454fb5929/14c0238f755fe6347519e69d3cb28c0fa52ec044-775x203.png" alt="" /><p>7. Attendez qu'il soit prêt. Il faut environ 10 minutes pour le créer.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc389eecd12e3b2c8/6a17fe8425daab0b2408a442/eb00c3ad18f884f47db6645b196808ebec07c1fc-797x177.png" alt="" /><p>8. Configurer l'accès à la ligne de commande 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>Notez que l'extension que nous avons installée active AKS Automatic.</em></p><p>9. Confirmez que les nœuds ont été déployés.</p>kubectl get nodes<p>Vous verrez un message d'erreur interdit ; copiez l'identifiant de l'utilisateur dans le message d'erreur.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4b2bb8558e1a39f4/6a17fe87a292991ce3d02ea8/d6c021fa54f4db00d2d795f5ba9b5a93376d03cd-818x47.png" alt="" /><p>10. Ajoutez votre utilisateur au contrôle d'accès AKS.</p><p>Obtenir l'ID AKS. Copie la sortie de la commande.</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>Créez une attribution de rôle en utilisant l'identifiant AKS et l'identifiant principal de votre utilisateur.</p>az role assignment create --role "Azure Kubernetes Service RBAC Cluster Admin" --assignee &lt;PRINCIPAL_ID&gt; --scope &lt;AKS_ID&gt;<p>11. Essayez de confirmer que les nœuds ont été déployés à nouveau.</p>kubectl get nodes<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltda416366f0e53d49/6a17fe8ab1e113f87c79f4c1/c9b3a5c1cc540ef732c3e7f60b0a973bdbd0b6fd-617x99.png" alt="" /><p>12. Installez l'opérateur Elastic Cloud on the 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. Créons une instance Elasticsearch à nœud unique avec les valeurs par défaut.</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>Nous avons désactivé <code>nmap</code> parce que la machine AKS par défaut a une valeur <code>vm.max_map_count</code> trop faible. Sa désactivation n'est pas recommandée pour la production, mais l'augmentation de la valeur de <code>vm.max_map_count</code>. Pour en savoir plus <a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s/virtual-memory">, cliquez ici.</a></p><p>14. Déployons également un cluster Kibana à nœud unique. Pour Kibana, nous allons ajouter un équilibreur de charge, qui nous donnera une IP externe que nous pouvons utiliser pour atteindre Kibana depuis notre appareil.</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>Par défaut, AKS Automatic configure l'équilibreur de charge comme étant public ; vous pouvez modifier ce comportement en définissant l'annotation des métadonnées :</p><p><code>service.beta.kubernetes.io/azure-load-balancer-internal: "true"</code></p><p>15. Vérifiez que vos pods fonctionnent.</p>kubectl get pods<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltea98380109a7a0b1/6a17fe8c4b055dda6c43241e/213a897176c0af6cea19c7c777cfaf8734e3ee6e-616x84.png" alt="" /><p>16. Vous pouvez également lancer <code>kubectl get elasticsearch</code> et <code>kubectl get kibana</code> pour obtenir des statistiques plus spécifiques comme la version d'Elasticsearch, les nœuds et l'état de santé.</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. Accédez à vos services.</p>kubectl get svc<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfc9c24dc9b78a354/6a17fe900b0beda9f8dd37f8/b2d3e8f368be22b89aa2ed4d4d514f97dd6cbabd-624x115.png" alt="" /><p>Cela vous montrera l'<a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s/accessing-services">URL externe</a> de Kibana sous EXTERNAL-IP. Le provisionnement de l'équilibreur de charge peut prendre quelques minutes. <em><strong>Copier la valeur de EXTERNAL-IP.</strong></em></p><p>18. Obtenez le mot de passe Elasticsearch pour l'utilisateur '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>Accédez à Kibana</strong> via votre navigateur :</p><p>a. URL : https://&lt;EXTERNAL_IP&gt;:5601</p><p>b. Nom d'utilisateur:elastic</p><p>c. Mot de passe:c44A295CaEt44D6xIzN6Zs5m (de l'étape précédente)</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7e8fbd1593bae329/6a17fe937b54f91d7c8b3b1d/a601112527d80721b292328ed8da58386d2837eb-463x503.png" alt="" /><p>20. Lorsque vous accédez à Elastic Cloud à partir de votre navigateur, vous verrez l'écran de bienvenue.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9ad7cd3196eb7dbe/6a17fe95b1e11336a579f4c5/f91e71fa961d215a8d886601d1a9fc5c452ce329-1999x1256.png" alt="" /><p>Si vous souhaitez modifier les spécifications du cluster Elasticsearch, comme changer ou redimensionner les nœuds, vous pouvez appliquer à nouveau le manifeste YML avec les nouveaux paramètres :</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>Dans cet exemple, nous allons ajouter un nœud supplémentaire et modifier la RAM et la CPU. Comme vous pouvez le voir, <code>kubectl get elasticsearch</code> affiche maintenant 2 nœuds :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdfe6ff383e03814e/6a17fe974b055dd514432426/4b139a476b50933d45d99e09479112817964f76a-624x60.png" alt="" /><p>Il en va de même pour 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>Nous pouvons ajuster le CPU/RAM du conteneur ainsi que l'utilisation de la mémoire de <a href="https://nodejs.org/">Node.js </a><a href="https://nodejs.org/api/cli.html#--max-old-space-sizesize-in-mib">(max-old-space-size)</a>.</p><p>N'oubliez pas que les <a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s/volume-claim-templates">créances en volume existantes ne peuvent pas être réduites</a>. Après avoir appliqué la mise à jour, l'opérateur effectuera les changements avec un minimum de temps d'interruption.</p><p>N'oubliez pas de supprimer la grappe lorsque vous avez terminé les tests afin d'éviter des coûts inutiles.</p>az aks delete --name myAKSAutomaticCluster --resource-group elastic-resource<h2>Conclusion</h2><p>L'utilisation d'Azure AKS Automatic avec ECK fournit une solution équilibrée pour le déploiement d'Elasticsearch et de Kibana : elle réduit la complexité opérationnelle, assure une mise à l'échelle et des mises à jour automatisées, et tire parti de la flexibilité de Kubernetes. Cette approche est idéale pour les équipes qui souhaitent un processus de déploiement fiable, reproductible et maintenable sans avoir à gérer manuellement chaque détail de l'infrastructure, ce qui en fait un choix pratique pour les environnements de test et de production.</p><h2>Étapes suivantes</h2><p>Si vous souhaitez en savoir plus sur Kubernetes, vous pouvez consulter la documentation officielle ici :</p><ul><li><p><a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s">Elastic Cloud sur Kubernetes | Elastic Docs</a></p></li><li><p><a href="https://learn.microsoft.com/en-us/azure/aks/intro-aks-automatic">Introduction à Azure Kubernetes Service (AKS) Automatique (preview)</a></p></li><li><p><a href="https://azure.github.io/AKS/2024/05/22/aks-automatic">AKS Automatic - Blog d'AKS Engineering</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[Les bases]]></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[Configurer le découpage récursif pour les documents structurés dans Elasticsearch]]></title>
    <description><![CDATA[Apprenez à configurer le découpage récursif dans Elasticsearch avec la taille des morceaux, les groupes de séparateurs et les listes de séparateurs personnalisées pour une indexation optimale des documents structurés.]]></description>
    <content:encoded><![CDATA[<p>Depuis la version 8.16, les utilisateurs peuvent configurer la stratégie de découpage utilisée lors de l'ingestion de longs documents dans des champs de texte sémantique. Depuis la version 9.1 / 8.19, nous avons introduit une nouvelle stratégie de découpage récursif configurable qui utilise une liste d'expressions régulières pour découper le document. L'objectif du découpage en morceaux est de diviser un long document en sections qui encapsulent un contenu apparenté. Nos stratégies existantes permettent de diviser le texte selon une granularité de mots/phrases, mais les documents écrits dans des formats structurés (ex. Markdown) contiennent souvent des contenus connexes dans des sections définies par des chaînes de séparation (ex. ). Pour ces types de documents, nous introduisons la stratégie de découpage récursif afin d'exploiter le format des documents structurés pour créer de meilleurs morceaux !</p><h2>Qu'est-ce que le découpage récursif ?</h2><p>Le découpage récursif parcourt une liste de sections fournies en séparant les modèles afin de diviser progressivement un document en segments plus petits jusqu'à ce qu'ils atteignent une taille maximale souhaitée.</p><h3>Comment configurer le découpage récursif ?</h3><p>Les valeurs configurables fournies par l'utilisateur pour le découpage récursif sont les suivantes :</p><ul><li><p>(obligatoire) <code>max_chunk_size</code>: Le nombre maximum de mots dans un bloc.</p></li><li><p>L'un ou l'autre :</p><ul><li><p><code>separators</code>: Une liste de motifs de chaînes regex qui seront utilisés pour découper le document en morceaux.</p></li><li><p><code>separator_group</code>: Une chaîne qui correspondra à une liste par défaut de séparateurs définis par Elastic à utiliser pour des types de documents spécifiques. Actuellement, <code>markdown</code> et <code>plaintext</code> sont disponibles.</p></li></ul></li></ul><h3>Comment fonctionne le découpage récursif ?</h3><p>Le processus de découpage récursif d'un document d'entrée, d'un <code>max_chunk_size</code> (mesuré en mots) et d'une liste de chaînes de séparation est le suivant :</p><ol><li><p>Si le document d'entrée est déjà compris dans la taille maximale des morceaux, il renvoie un seul morceau couvrant l'ensemble du document d'entrée.</p></li><li><p>Découper le texte en morceaux potentiels sur la base des occurrences du séparateur. Pour chaque morceau potentiel :</p><ol><li><p>Si le morceau potentiel ne dépasse pas la taille maximale, il est ajouté à la liste des morceaux à renvoyer à l'utilisateur.</p></li><li><p>Sinon, répétez l'étape 2, en utilisant uniquement le texte du morceau potentiel et en le séparant à l'aide du séparateur suivant dans la liste. S'il n'y a plus de séparateurs à essayer, il faut se rabattre sur le découpage en phrases.</p></li></ol></li></ol><h2>Exemples de configuration du découpage récursif</h2><p>Outre la taille des morceaux, la principale configuration du découpage récursif consiste à sélectionner les séparateurs à utiliser pour diviser vos documents. Si vous ne savez pas par où commencer, Elasticsearch propose quelques groupes de séparateurs par défaut qui peuvent être utilisés pour des cas d'utilisation courants.</p><h3>Utilisation de groupes de séparation</h3><p>Pour utiliser un groupe séparateur, il suffit d'indiquer le nom du groupe que vous souhaitez utiliser lors de la configuration des paramètres de regroupement. Par exemple :</p>"chunking_settings": {
    "strategy": "recursive",
    "max_chunk_size": 25,
    "separator_group": "plaintext"
}<p>Vous obtiendrez ainsi une stratégie de découpage récursif qui utilise la liste de séparateurs <code>["(?&lt;!\\n)\\n\\n(?!\\n)", "(?&lt;!\\n)\\n(?!\\n)")]</code>. Cela fonctionne bien pour les applications génériques de texte brut, en séparant deux caractères de retour à la ligne, suivis d'un caractère de retour à la ligne.</p><p>Nous proposons également un groupe de séparateurs <code>markdown</code> qui utilisera la liste des séparateurs :</p>[
"\n# ",
       "\n## ",
       "\n### ",
       "\n#### ",
       "\n##### ",
       "\n###### ",
       "\n^(?!\\s*$).*\\n-{1,}\\n",
       "\n^(?!\\s*$).*\\n={1,}\\n"
]<p>Cette liste de séparateurs fonctionnera bien pour les cas d'utilisation généraux de markdown, en séparant chacun des 6 niveaux d'en-tête et les caractères de coupure de section.</p><p>Lors de la création d'une ressource (point d'inférence/champ textuel sémantique), la liste des séparateurs correspondant au groupe de séparateurs du moment sera stockée dans vos configurations. Si le groupe de séparateurs est mis à jour ultérieurement, cela ne modifiera pas le comportement des ressources déjà créées.</p><h3>Utilisation d'une liste de séparateurs personnalisée</h3><p>Si l'un des groupes de séparateurs prédéfinis ne convient pas à votre cas d'utilisation, vous pouvez définir une liste personnalisée de séparateurs répondant à vos besoins. Notez que des expressions régulières peuvent être fournies dans la liste des séparateurs. Voici un exemple de paramètres de regroupement configurés avec des séparateurs personnalisés :</p>"chunking_settings": {
    "strategy": "recursive",
    "max_chunk_size": 25,
    "separators": ["\n\n", "\n", "&lt;my-custom-separator&gt;"]
}<p>La stratégie de découpage en morceaux découpera 2 caractères de nouvelle ligne, suivis d'un caractère de nouvelle ligne, et enfin une chaîne de caractères <code>“&lt;my-custom-separator&gt;”</code>.</p><h2>Un exemple de découpage récursif en action</h2><p>Voyons un exemple de découpage récursif en action. Pour cet exemple, nous utiliserons les paramètres de découpage suivants avec une liste personnalisée de séparateurs qui découpent un document markdown en utilisant les deux premiers niveaux d'en-tête :</p>"chunking_settings": {
    "strategy": "recursive",
    "max_chunk_size": 25,
    "separators": ["\n# ", "\n## "]
}<p>Examinons un simple document Markdown non tronqué :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdb5f41d1bd43ba50/6a17e831e9ea87c1d8a9c5f3/3a5507f4a1288065097231548e5b18e240508785-1302x1446.png" alt="Un document Markdown non tronqué" /><p>Utilisons maintenant les paramètres de découpage définis ci-dessus pour découper le document en morceaux :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfffda162c7b9c87a/6a17e83296142aefa8eb1b0b/a3313c4c40ff39b8dbcdd7c4878c723f088e6c1a-1600x1187.png" alt="Chunking d'un document dans Elasticsearch" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt96f65346a8e09e3a/6a17e834445de9157b4d015e/79a2921943191ea631df94c9d465818ec8d3e738-1600x1206.png" alt="Splitting on second separator- chunking a document in Elasticsearch" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt28381c8f85aedf07/6a17e836ec0f89801e5a6640/459e695cce7540267422396b9a62ff4ad35f61db-1600x1260.png" alt="Derniers morceaux d'un document après un découpage basé sur les phrases dans Elasticsearch" /><p>Remarque : la nouvelle ligne à la fin de chaque morceau (à l'exception du morceau 3) n'est pas mise en évidence, mais elle est incluse dans les limites du morceau.</p><h3>Commencez dès aujourd'hui à utiliser le découpage récursif !</h3><p>Pour plus d'informations sur l'utilisation de cette fonctionnalité, consultez la documentation sur la configuration des paramètres de regroupement.</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[Les bases]]></category>
    <category><![CDATA[À l'intérieur d'Elastic]]></category>
    <category><![CDATA[IA]]></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[Présentation de l'interface utilisateur des règles de requête Elasticsearch dans Kibana]]></title>
    <description><![CDATA[Découvrez comment utiliser l'interface utilisateur Elasticsearch Query Rules pour ajouter ou exclure des documents des requêtes de recherche à l'aide d'ensembles de règles personnalisables dans Kibana, sans affecter le classement organique.]]></description>
    <content:encoded><![CDATA[<p>Le rôle d'un moteur de recherche est de renvoyer des résultats pertinents. Cependant, certains besoins professionnels vont au-delà, comme la mise en évidence des ventes, la priorité donnée aux produits saisonniers ou la présentation d'articles sponsorisés, et les développeurs ne peuvent pas toujours le faire dans la requête de recherche.</p><p>En outre, ces cas d'utilisation sont généralement sensibles au temps, et passer par les étapes de développement habituelles (créer une branche de code et attendre une nouvelle version) est un processus qui prend beaucoup de temps.</p><p>Et si nous pouvions réaliser l'ensemble de ce processus par un simple appel d'API ou, mieux encore, en quelques clics dans Kibana ?</p><h2>Règles d'interrogation</h2><p>Elasticsearch 8.10 a introduit les <a href="https://www.elastic.co/blog/introducing-query-rules-elasticsearch-8-10"><strong>règles de requête</strong></a> et le <a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/retrievers/rule-retriever"><strong>récupérateur de règles</strong></a>. Il s'agit d'outils conçus pour injecter des <a href="https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-pinned-query"><em>résultats épinglés</em></a> dans les requêtes sans affecter le classement des résultats organiques sur la base de règles. Ils ne font qu'ajouter une logique d'entreprise aux résultats d'une manière simple et déclarative.</p><p>Voici quelques exemples d'utilisation courante des règles de requête :</p><ul><li><p><strong>Mise en évidence des annonces ou des ventes promues</strong>: Afficher les articles en vente ou sponsorisés en haut de la page.</p></li><li><p><strong>Exclusion en fonction du contexte ou de la géolocalisation</strong>: Masquer certains éléments lorsque la réglementation locale ne permet pas de les afficher.</p></li><li><p><strong>Donner la priorité aux résultats clés</strong>: Veiller à ce que les recherches populaires ou fixes soient toujours en tête, quel que soit le classement organique.</p></li></ul><p>Pour accéder à l'interface et interagir avec ces outils, vous devez cliquer sur le menu latéral de Kibana et aller dans <strong>Règles de requête</strong>, sous <strong>Pertinence</strong>:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltac12541cddd58e36/6a170853a29299941cd00fc2/242e33e89d1a07ffa0e76009c46b3a9236722741-458x1010.png" alt="Accès aux règles de requête dans Elasticsearch sous pertinence" /><p>Lorsque le menu des règles de requête s'affiche, cliquez sur <strong>Créer votre premier jeu de règles :</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcc28329c0f3c3aa9/6a17085547d49c67e22d893b/30b3a91bbbf243d314cf38298e01ca5cff784430-1600x945.png" alt="Créer son premier jeu de règles de requête dans Elasticsearch" /><p>Ensuite, vous devez nommer votre jeu de règles.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb37d271297a4f148/6a170856a29299782cd00fc6/26c5462f88678867776f933b5655ca0df0d72a16-708x446.png" alt="Nommer vos règles de requête ruleset dans Elasticsearch" /><p>Le formulaire permettant de définir chaque règle comporte trois éléments clés :</p><ul><li><p><strong>Critères</strong>: Les conditions qui doivent être remplies pour que la règle s'applique. Par exemple, "lorsque le champ query_string contient la valeur <em>Christmas</em>" ou "lorsque le champ country est <em>CO".</em></p></li><li><p><strong>Action</strong>: C'est ce que vous voulez qu'il se passe lorsque les conditions sont remplies. Il peut être épinglé (fixation d'un document dans les premiers résultats) ou exclu (masquage d'un document).</p></li><li><p><strong>Métadonnées</strong>: Il s'agit des champs qui accompagnent la requête lors de son exécution. Elles peuvent inclure des informations sur l'utilisateur (comme la localisation ou la langue) ainsi que des données de recherche (query_string). Il s'agit des valeurs utilisées par les critères pour décider d'appliquer ou non une règle.</p></li></ul><h2>Exemple : articles populaires</h2><p>Imaginons que nous ayons un site de commerce électronique proposant différents articles. En vérifiant les mesures, nous remarquons que l'un des articles les plus vendus dans la catégorie des consoles est la "manette sans fil DualShock 4", en particulier lorsque les utilisateurs recherchent les mots clés "PS4" ou "PlayStation 4". Nous décidons donc de placer ce produit en tête des résultats lorsqu'un utilisateur effectue une recherche avec ces mots-clés.</p><p>Tout d'abord, nous allons indexer les documents pour chaque article à l'aide d'une requête API en bloc :</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 nous n'intervenons pas dans la requête, l'article apparaît généralement en quatrième position. Voici la requête :</p>GET products/_search
{
 "query": {
   "match": {
     "name": "PlayStation 4"
   }
 }
}<p>Et voici les résultats</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>Créons une règle de requête pour modifier cela. Tout d'abord, ajoutons-le au jeu de règles comme suit :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1576d4f4a2e60548/6a170858cdacbfccb07d298d/fdc42646fb3e76a09bca7d19047a76efe343f7a2-1600x650.png" alt="Comment modifier un jeu de règles de requête dans Elasticsearch ?" /><p>Ou <a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-query-rules-put-ruleset">demande d'API</a> équivalente :</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>Pour utiliser l'<strong>ensemble de règles </strong>dans notre requête, nous devons utiliser un type de règle de requête. Ce type de requête se compose de deux parties 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>: Il s'agit des métadonnées utilisées pour la comparaison avec la requête de l'utilisateur. Dans cet exemple, le jeu de règles est activé lorsque le champ query_string a la valeur "PlayStation 4".</p></li><li><p><strong>requête</strong>: la requête réelle qui sera utilisée pour effectuer la recherche et obtenir les résultats organiques.</p></li></ul><p>De cette façon, vous exécutez d'abord la requête organique, puis Elasticsearch applique les règles de votre ensemble de règles :</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>Exemple : métadonnées basées sur l'utilisateur</h2><p>Une autre application intéressante des règles d'interrogation consiste à utiliser les métadonnées pour afficher des documents spécifiques sur la base d'informations contextuelles provenant de l'utilisateur ou de la page web.</p><p>Par exemple, imaginons que nous souhaitions mettre en avant des articles ou des ventes personnalisées en fonction du niveau de fidélité d'un utilisateur, représenté par une valeur numérique.</p><p>Nous pouvons le faire en intégrant ces métadonnées directement dans la requête, de sorte que les règles s'activent lorsque la valeur en question répond à certains critères.</p><p>Tout d'abord, nous allons indexer un document que seuls les utilisateurs ayant un niveau de fidélité élevé peuvent consulter :</p>POST _bulk
{ "index": { "_index": "products", "_id": "6" } }
{ "id": "6", "name": "PlayStation Plus Deluxe Card - 12 months", "category": "membership", "brand": "Sony", "price": 300 }<p>Maintenant, créons une nouvelle règle dans le même jeu de règles pour que lorsque le niveau de fidélité est égal ou supérieur à 80, l'article apparaisse en tête des résultats.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt158578005df8c76d/6a17085aab7f086dc0db9de3/58de12dff93305440608f51465462fcc68653a08-1421x496.png" alt="Comment modifier un jeu de règles de requête dans Elasticsearch ?" /><p>Enregistrez la règle et le jeu de règles.</p><p>Voici la requête REST équivalente :</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>Désormais, lors de l'exécution d'une requête, nous devons inclure le nouveau paramètre <strong>loyalty_level </strong>dans les métadonnées. Si la condition de la règle est remplie, le nouveau document apparaît en tête des résultats.</p><p>Par exemple, lors de l'envoi d'une requête dont le niveau de fidélité est 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>Nous verrons le document de fidélisation en haut des résultats :</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>Dans le cas ci-dessous, le niveau de fidélité étant de 70, la règle n'est pas respectée et l'objet ne doit pas apparaître en haut de la liste :</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>Voici les résultats :</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>Exemple : exclusion immédiate</h2><p>Supposons que notre <strong>manette sans fil DualShock 4 (ID 2)</strong> soit temporairement indisponible et ne puisse être vendue. Ainsi, au lieu de supprimer manuellement le document ou d'attendre qu'un processus de données se mette en place, l'équipe commerciale décide de le supprimer des résultats de recherche en attendant.</p><p>Nous utiliserons un processus similaire à celui que nous venons d'appliquer aux articles populaires, mais cette fois-ci, au lieu de sélectionner <em>Épinglé</em>, nous choisirons <em>Exclure</em>. Cette règle fonctionne comme une sorte de liste noire. Changez les critères en <strong>Toujours</strong> pour que l'exclusion fonctionne à chaque fois que la requête est exécutée.</p><p>La règle devrait ressembler à ceci :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt38564c0b7f4a6ee2/6a17085c1949f78692e7a989/f10971e4f1bc9520105111adfa3a476581a27130-1600x623.png" alt="Exemple d'un jeu de règles d'exclusion immédiate dans Elasticsearch" /><p>Enregistrez la règle et le jeu de règles pour appliquer les modifications. Voici la requête REST équivalente :</p>PUT _query_rules/my-rules
{
  "rules": [
    {
      "rule_id": "rule-6358",
      "type": "pinned",
      "criteria": [
        {
          "type": "always"
        }
      ],
      "actions": {
        "docs": [
          {
            "_index": "products",
            "_id": "2"
          }
        ]
      }
    }
  ]
}<p>Maintenant, lorsque nous exécutons à nouveau la requête, vous verrez que l'élément ne figure plus dans les résultats, bien que la règle préalable soit de l'épingler. En effet, <strong>les exclusions ont la priorité sur les résultats de l'épinglage</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>Conclusion</h2><p>Les <strong>règles de requête</strong> permettent d'ajuster très facilement la pertinence sans modifier le code. La nouvelle interface <strong>utilisateur</strong> <strong>Kibana </strong>vous permetd'effectuer ces modifications en quelques secondes, ce qui vous donne, ainsi qu'à votre équipe commerciale, un meilleur contrôle sur vos résultats de recherche.</p><p>Au-delà du commerce électronique, les règles de requête peuvent servir à de nombreux autres scénarios : mise en évidence des guides de dépannage dans les portails d'assistance, mise en évidence des documents internes clés dans les bases de connaissances, promotion des dernières nouvelles dans les sites d'information ou filtrage des offres d'emploi ou des listes de contenu expirées. Ils peuvent même appliquer des règles de conformité, par exemple en masquant les documents à diffusion restreinte en fonction du rôle de l'utilisateur ou de la région.</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[Les bases]]></category>
    <category><![CDATA[Expérience développeur]]></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[Comment déployer Elasticsearch sur AWS Marketplace]]></title>
    <description><![CDATA[Découvrez comment configurer et exécuter Elasticsearch à l'aide d'Elastic Cloud Service sur AWS Marketplace grâce à ce guide étape par étape.]]></description>
    <content:encoded><![CDATA[<p>Dans cet article, nous allons apprendre comment déployer Elasticsearch sur AWS en utilisant les offres d'AWS Marketplace.</p><p>Nous allons utiliser Elastic Cloud Service sur AWS, qui est le service Elasticsearch géré officiel qui simplifie le déploiement et l'orchestration de tous les composants d'Elastic Stack via l'infrastructure native d'AWS.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6c1107b202d48147/6a16f67d92262a04071cc077/f15814051b53b50bec38f9a9f515a1e6dc08a56c-884x440.png" alt="" /><p>Si vous souhaitez savoir comment installer et configurer Elasticsearch sur AWS EC2, consultez <a href="https://www.elastic.co/search-labs/blog/elasticsearch-on-aws-ec2-deployment-guide">ce blog</a>.
</p><h2>Qu'est-ce qu'AWS Marketplace ?</h2><p><a href="https://aws.amazon.com/marketplace"><strong>Elastic sur AWS Marketplace</strong></a> offre une expérience de recherche et d'analyse entièrement gérée où AWS s'occupe du provisionnement de l'infrastructure, de la sécurité et du scaling, tandis que les développeurs se concentrent sur la création d'applications de recherche. Cela permet aux équipes de déployer des clusters Elasticsearch de niveau entreprise en quelques minutes grâce à des intégrations AWS prédéfinies.</p><h2>Quand utiliser Elastic sur AWS Marketplace ?</h2><p>Elastic sur AWS Marketplace est parfaitement adapté aux organisations disposant d'une infrastructure AWS existante et souhaitant déployer Elasticsearch avec des services gérés, une sécurité intégrée et des intégrations AWS transparentes sans frais opérationnels supplémentaires.</p><h2>Comment configurer Elastic Cloud sur AWS Marketplace</h2><h3>Étape 1 : Accédez à AWS Marketplace</h3><p>1. Connectez-vous à <a href="https://console.aws.com/">AWS</a></p><ul><li><p>Dans la barre de recherche, recherchez AWS Marketplace</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd7b4a64a97929ca0/6a16f67e60084b1ee43c4333/fc9928f79482c2c01e33978c88d390a2bfa2a3bf-1600x340.png" alt="" /><p>2. Dans le panneau de navigation de gauche, cliquez sur <strong>Discover products</strong> (Découvrir les produits), puis recherchez Elasticsearch</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta3efc233beb103ab/6a16f680b0367d681572babd/ca4232271cb13ebfe33de406ecaec085033ec8a0-1454x760.png" alt="" /><p>3. Cliquez sur <strong>Elastic Cloud (Elasticsearch Service)</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd7fe524f5d0cc84e/6a16f682cdacbfabdf7d27c4/e59aa276e55532f2ac3461d0ca983af4d41ad7a6-1600x611.png" alt="" /><h3>Étape 2 : abonnez-vous au service</h3><p>1. Sélectionnez <strong>purchase options</strong> (options d'achat) ou cliquez sur <strong>Try for free</strong> (Essayer gratuitement)</p><p>2. Examinez les <strong>détails des tarifs</strong>, les <strong>conditions générales</strong> et les <strong>détails d'achat</strong>.</p><p>3. Cliquez sur le bouton <strong>Subscribe </strong>(S'abonner)</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt027c8adb6bfa2b73/6a16f683a292995855d00de4/1c30d12b6b1061e76771d518011e522285f939f1-1600x290.png" alt="" /><p>4. Nous devons maintenant configurer le compte Elastic. Suivez les étapes sur AWS</p><p>a. Cliquez sur le bouton Activer l’intégration</p><p>b. Cliquez sur le bouton Sign in (Connexion) ou Create a vendor account (Créer un compte vendeur)</p><p>c. Cliquez sur le bouton Launch template (Lancer le modèle)</p><p>d. Cliquez sur le bouton Launch Software (Lancer le logiciel)</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>Étape 3. Configurez votre nouveau compte dans Elastic</h3><p>1. Créez votre compte Elastic</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2a47e1e23a0be123/6a16f68875879e400ffe15c0/5efeaf0737062a55470b17b67651f220e12183f2-986x905.png" alt="" /><p>2. Validez votre adresse e-mail</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltaad961a0644018b5/6a16f68a0811ae0734e9feb6/e0cfaac278614e317ce278935040bfa5a58edd13-853x894.png" alt="" /><p>3. Saisissez votre nom et les informations de votre entreprise</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt52f4a502993fa5d4/6a16f68b2b835fb4b9f4afc4/d5658fe66c3b1bcced73e822eae006846f0ddd9e-997x903.png" alt="" /><p>4. Répondez à un court questionnaire Elastic</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt375dca1904b2f0c1/6a16f68dcdacbf4f8d7d27c8/a3f53c00dadfd22f7d739a920c87d5f387182833-892x805.png" alt="" /><p>5. Sélectionnez la région dans laquelle vous souhaitez héberger Elastic Cloud. Par défaut, votre région AWS actuelle sera sélectionnée</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0c23f8b8b63af517/6a16f68fb0367d6a6072bac1/c1dcdf3bf91c305821daaa25a60aa03be6454c1c-1207x1032.png" alt="" /><p>6. Attendez qu'Elastic se déploie</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd88a26701fb26db5/6a16f69075879ef0d8fe15cc/50903e57ebea7cc47bdfabf4750b4ba2a7a91148-1370x1266.png" alt="" /><p>7. Votre déploiement est connecté à votre abonnement AWS Marketplace</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt822e8acb553ffac4/6a16f69275879ed57ffe15d0/3bb731e2d5de5053ccecb77e45dbdbcdaf294dba-1600x1288.png" alt="" /><h2>Annuler votre abonnement</h2><p>Pour annuler votre abonnement</p><p>1. Accédez à la <a href="https://console.aws.com/">console AWS</a></p><p>Recherchez AWS Marketplace dans la barre de recherche. Cliquez sur <strong>AWS Marketplace</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7a19e162d4cb818a/6a16f694839dfa21a6dcfc9f/aeed3d1e67b4cef91934de257a6fd6daa9737a12-1600x554.png" alt="" /><p>2. Cliquez sur <strong>Elastic Cloud subscription</strong> (Abonnement Elastic Cloud)</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta189d9ff9b518243/6a16f695a292991b60d00de8/04e6cc41850226df223dbe2d1b0e4b45265f6c39-1600x564.png" alt="" /><p>3. Cliquez sur le bouton <strong>Actions</strong>, puis sur <strong>Cancel subscription</strong> (Annuler l'abonnement)</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt40fc41f3911b8b66/6a16f6971949f70896e7a7a9/e33d334ea6541c637a223de3ebd6209def75a6d3-1600x1039.png" alt="" /><p>4. Confirmez l'annulation, cliquez sur <strong>Yes </strong>puis sur le bouton cancel<strong> subscription</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3eb1839197854313/6a16f699ab7f08469fdb9c31/b73b3187168adc7aefdd46f95be33c1bce3da1e4-1103x698.png" alt="" /><p>5. Un message de confirmation apparaîtra en haut de la page</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt513bdb916a3bff8e/6a16f69a1949f74c5de7a7ad/c5ba66a23d535e866a8b458e5aca82c5f0b93037-1600x639.png" alt="" /><h2>Étapes suivantes</h2><p>Démarrez votre expérience Elastic Cloud avec un essai gratuit de 7 jours comprenant un déploiement unique et trois projets<a href="https://aws.amazon.com/marketplace/pp/prodview-voru33wi6xs7k"> Elastic Cloud (Elasticsearch Service)</a>. Connectez-vous simplement à votre compte AWS et cliquez sur "View Purchase Options" (Voir les options d'achat) pour commencer immédiatement à utiliser la plateforme Search AI d'Elastic sur Elastic<a href="https://aws.amazon.com/marketplace/pp/prodview-voru33wi6xs7k"> Cloud (Elasticsearch Service)</a>. L'essai offre un accès complet aux solutions de recherche, de sécurité et d'observabilité sans aucun surcoût lié à la gestion de l'infrastructure.</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[Les bases]]></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[Shards et répliques Elasticsearch : Un guide pratique]]></title>
    <description><![CDATA[Maîtriser les concepts de shards et de réplicas Elasticsearch et apprendre à les optimiser.]]></description>
    <content:encoded><![CDATA[<p>Elasticsearch renforce la puissance de Lucene en construisant un système distribué au-dessus de celui-ci, qui répond aux problèmes d'évolutivité et de tolérance aux pannes. Il expose également une API REST basée sur JSON, ce qui rend l'interopérabilité avec d'autres systèmes très simple.</p><p>Les systèmes distribués comme Elasticsearch peuvent être très complexes, avec de nombreux facteurs qui peuvent affecter leurs performances et leur stabilité. Les <strong>Shards</strong> font partie des concepts les plus fondamentaux d'Elasticsearch, et la compréhension de leur fonctionnement vous permettra de gérer efficacement un cluster Elasticsearch.</p><p>Cet article explique ce qu'est un serveur primaire et un serveur réplique, leur impact sur un cluster Elasticsearch et les outils qui permettent de les adapter à des besoins différents.</p><h2>Comprendre les tessons</h2><p>Les données contenues dans un index Elasticsearch peuvent prendre des proportions considérables. Afin de rester gérable, chaque donnée est conservée dans un index, et les index sont un index divisé en un certain nombre de <strong>morceaux.</strong> Chaque tesson Elasticsearch est un index Apache Lucene, chaque index Lucene individuel contenant un sous-ensemble des documents de l'index Elasticsearch. Le fractionnement des indices de cette manière permet de contrôler l'utilisation des ressources. Un index Apache Lucene a une limite de 2 147 483 519 (2³¹ - 129) documents.</p><p>Parfois, les indices doivent être déplacés d'un nœud à l'autre à des fins de rééquilibrage. Étant donné que ce processus peut être à la fois long et coûteux en ressources, les indices ne doivent pas devenir trop volumineux, ce qui permet de maintenir le temps de récupération à un niveau raisonnable. En outre, comme les indices sont composés de segments Lucene qui doivent être constamment fusionnés, il est important que les segments ne deviennent pas trop grands. Pour ces raisons, Elasticsearch divise les données d'index en morceaux plus petits et plus faciles à gérer, appelés <strong>shards primaires</strong>, qui peuvent être plus facilement distribués sur un certain nombre de machines. Les shards <strong>répliqués</strong> sont simplement une copie exacte d'un shard primaire correspondant et nous verrons leur fonction plus loin dans cet article.</p><p>Il est important de disposer d'un nombre adéquat de fragments pour garantir les performances. Il est donc judicieux de planifier à l'avance. Lorsque les requêtes sont exécutées en parallèle sur différents nuages, elles s'exécutent plus rapidement qu'un index composé d'un seul nuage, mais uniquement si chaque nuage est situé sur un nœud différent et s'il y a suffisamment de nœuds dans la grappe. En même temps, cependant, les ensembles consomment de la mémoire et de l'espace disque, à la fois en termes de données indexées et de métadonnées de grappe. Le fait d'avoir un trop grand nombre de shards (également appelé oversharding) peut ralentir les requêtes, les demandes d'indexation et les opérations de gestion, c'est pourquoi il est essentiel de maintenir un bon équilibre.</p><p>Le nombre de groupes primaires est défini au moment de la création de l'index <strong>pour cette instance d'index spécifique</strong>. Si vous avez besoin ultérieurement d'un nombre différent d'unités primaires, vous pouvez utiliser les<strong> API de redimensionnement :</strong>division(plus d'unités<a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-shrink">primaires),</a> <a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-split">réduction</a> (moins d'unités primaires) ou <a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-clone">clonage</a> (le même nombre d'unités primaires avec de nouveaux paramètres pour les réplicas). Ces opérations copient des segments Lucene et <strong>évitent une réindexation complète de tous les documents</strong>. Lors de la création d'un index, vous pouvez définir le nombre de shards primaires et de shards répliqués comme paramètres de l'index :</p>PUT /sensor
{
   "settings" : {
       "index" : {
           "number_of_shards" : 6,
           "number_of_replicas" : 2
       }
   }
}<p>(Si vous ne spécifiez pas le nombre de shards ou de répliques, la valeur par défaut est 1, à partir d'Elasticsearch 7.0). Le nombre idéal d'unités de stockage doit être déterminé en fonction de la quantité de données contenues dans un index. En règle générale, <a href="https://www.elastic.co/docs/deploy-manage/production-guidance/optimize-performance/size-shards">un fonds optimal doit contenir de 10 à 50 Go de données</a>, avec moins de 200 millions de documents par fonds. Par exemple, si vous prévoyez d'accumuler environ 300 Go de journaux d'application par jour, il serait raisonnable d'avoir environ 10 fichiers dans cet index, à condition que vous disposiez d'un nombre suffisant de nœuds pour les héberger.</p><p>Au cours de leur vie, les tessons peuvent passer par un certain nombre d'états, notamment</p><ul><li><p><strong>Initialisation :</strong> Un état initial avant que le tesson puisse être utilisé.</p></li><li><p><strong>Démarré :</strong> État dans lequel le groupe de stockage est actif et peut recevoir des demandes.</p></li><li><p><strong>Relocalisation :</strong> Un état qui se produit lorsque les shards sont en train d'être déplacés vers un autre nœud. Cela peut s'avérer nécessaire dans certaines conditions, par exemple lorsque le nœud sur lequel ils se trouvent manque d'espace disque.</p></li><li><p><strong>Non assigné :</strong> État d'un tesson qui n'a pas été affecté. Une raison est fournie lorsque cela se produit, par exemple, si le nœud hébergeant le dépôt n'est plus dans le cluster <em>(NODE_LEFT)</em> ou en raison d'une restauration dans un index fermé <em>(EXISTING_INDEX_RESTORED)</em>.</p></li></ul><p>Pour afficher tous les shards, leur état et d'autres métadonnées, vous pouvez utiliser la requête suivante :</p>GET _cat/shards<p>Pour visualiser les dépôts d'un index spécifique, vous pouvez ajouter le nom de l'index à l'URL, par exemple, sensor :</p>GET _cat/shards/sensor<p>Cette commande produit une sortie, comme dans l'exemple suivant. Par défaut, les colonnes affichées comprennent le nom de l'index, le nom (i.e. ) du dépôt, s'il s'agit d'un dépôt primaire ou d'une réplique, son état, le nombre de documents, la taille sur le disque, ainsi que l'adresse IP et l'ID du nœud où se trouve le dépôt.</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>Comprendre les répliques</h2><p>Alors que chaque nuage contient une seule copie des données, un index peut contenir plusieurs copies du nuage. Il y a donc deux types de tessons, le <strong>tesson primaire</strong> et une copie, ou <strong>réplique</strong>. Chaque réplique d'un groupe de données primaire est toujours située sur un nœud différent, ce qui garantit la haute disponibilité de vos données en cas de défaillance d'un nœud. Outre la redondance et leur rôle dans la prévention des pertes de données et des temps d'arrêt, les répliques peuvent également contribuer à améliorer les performances de recherche en permettant aux requêtes d'être traitées en parallèle avec le shard principal, et donc plus rapidement.</p><p>Il existe des différences importantes dans la manière dont se comportent les disques primaires et les disques répliques. Bien qu'ils soient tous deux capables de traiter les requêtes, les demandes d'indexation (c.-à-d. les demandes d'accès à la base de données) ne sont pas traitées. l'ajout de données à l'index) doivent d'abord passer par les disques primaires avant d'être répliqués dans les disques répliques. Comme nous l'avons vu plus haut, si un shard primaire devient indisponible, par exemple en raison d'une déconnexion de nœud ou d'une défaillance matérielle, un réplica est promu pour reprendre son rôle.</p><p>Si les répliques peuvent être utiles en cas de défaillance d'un nœud, il est important de ne pas en avoir trop, car elles consomment de la mémoire, de l'espace disque et de la puissance de calcul lors de l'indexation. Une autre différence entre les shards primaires et les réplicas est que le nombre de shards primaires ne peut pas être modifié après la création de l'index, alors que le nombre de réplicas peut être modifié dynamiquement à tout moment en mettant à jour les paramètres de l'index.</p><p>Un autre facteur à prendre en compte pour les répliques est le nombre de nœuds disponibles. Les répliques sont toujours placées sur des nœuds différents de ceux du groupe principal, car deux copies des mêmes données sur le même nœud n'offriraient aucune protection en cas de défaillance de ce nœud. Par conséquent, pour qu'un système prenne en charge <em>n</em> répliques, il doit y avoir au moins <em>n + 1</em> nœuds dans la grappe. Par exemple, s'il y a deux nœuds dans un cluster et qu'un index est configuré avec six répliques, une seule réplique sera allouée. En revanche, un système à sept nœuds est parfaitement capable de gérer un shard primaire et six répliques.</p><h2>Optimisation des grappes et des répliques</h2><p>Même après la création d'un index avec le bon équilibre entre les unités primaires et les unités répliquées, celles-ci doivent être surveillées, car la dynamique autour d'un index évolue au fil du temps. Par exemple, lorsqu'il s'agit de séries chronologiques, les indices contenant des données récentes sont généralement plus actifs que les indices plus anciens. Sans réglage de ces indices, ils consommeraient tous la même quantité de ressources, malgré leurs exigences très différentes.</p><p>L'API de l'indice de reconduction peut être utilisée pour séparer les indices les plus récents des plus anciens. Il peut être configuré pour créer automatiquement un nouvel index lorsqu'un certain seuil - taille d'un index sur le disque, nombre de documents ou âge - est atteint. Cette API est également utile pour contrôler la taille des fichiers. Étant donné que le nombre de groupes ne peut pas être facilement modifié après la création de l'index, les groupes continueront d'accumuler des données si aucune condition de transfert n'est remplie. Pour les index plus anciens qui ne nécessitent que des accès peu fréquents, le rétrécissement et la fusion forcée d'un index sont deux moyens différents de réduire leur empreinte mémoire et disque. La première permet de réduire le nombre d'unités dans un index, tandis que la seconde réduit le nombre de segments Lucene et libère l'espace utilisé par les documents qui ont été supprimés.</p><h2>Shards primaires et répliques comme base d'Elasticsearch</h2><p>Elasticsearch s'est forgé une solide réputation en tant que plateforme distribuée de stockage, de recherche et d'analyse pour d'énormes volumes de données. Toutefois, à une telle échelle, des problèmes se posent inévitablement. C'est pourquoi il est si important et fondamental pour Elasticsearch de comprendre le fonctionnement des shards primaires et répliqués, car cela permet d'optimiser la fiabilité et les performances de la plateforme.</p><p>Il est essentiel de savoir comment ils fonctionnent et comment les optimiser pour obtenir un cluster Elasticsearch plus robuste et plus performant. Si vous rencontrez régulièrement des réponses lentes aux requêtes ou des pannes, ces connaissances peuvent être la clé pour surmonter ces obstacles.</p><p>Suivez la documentation officielle d'Elasticsearch pour en savoir plus sur les <a href="https://www.elastic.co/docs/deploy-manage/distributed-architecture/clusters-nodes-shards">clusters, les nœuds et les shards</a>, sur <a href="https://www.elastic.co/docs/deploy-manage/production-guidance/optimize-performance/size-shards">la taille des shards</a>, sur l <a href="https://www.elastic.co/docs/deploy-manage/distributed-architecture/shard-allocation-relocation-recovery">'allocation des shards et sur la récupération.</a></p><p>Ce sujet est également disponible sous forme de cours d'introduction sur la <a href="https://youtu.be/sAySPSyL2qE">chaîne YouTube de la communauté Elastic</a>.</p><p>Enfin, si vous ne voulez pas vous préoccuper des nœuds, des unités de stockage ou des répliques, vous pouvez essayer <a href="https://www.elastic.co/docs/deploy-manage/deploy/elastic-cloud/serverless">Elastic Cloud Serverless</a>. Cette offre Elastic Cloud est entièrement gérée par Elastic et automatisée pour évoluer avec votre charge de travail. Un essai gratuit peut vous aider à vous familiariser avec d'autres avantages de l'approche sans serveur.</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[Les bases]]></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[Dévoiler des modèles uniques : Un guide pour l'agrégation de termes significatifs dans Elasticsearch]]></title>
    <description><![CDATA[Apprenez à utiliser l'agrégation de termes significatifs pour découvrir des informations dans vos données.]]></description>
    <content:encoded><![CDATA[<p>Dans Elasticsearch, une <a href="https://www.elastic.co/docs/reference/aggregations/search-aggregations-bucket-significantterms-aggregation">agrégation de termes significatifs</a> va au-delà des <a href="https://www.elastic.co/docs/reference/aggregations/search-aggregations-bucket-terms-aggregation">termes les plus courants</a> pour trouver des valeurs statistiquement inhabituelles dans un ensemble de données. Cela nous permet de découvrir des informations précieuses et des modèles non évidents. Une agrégation de termes significatifs fournit une réponse avec deux paramètres utiles :</p><ul><li><p><strong>bg_count (background count) : </strong>Nombre de documents trouvés dans l'ensemble de données parent.</p></li><li><p><strong>doc_count :</strong> Nombre de documents trouvés dans l'ensemble de données de résultat</p></li></ul><p>Par exemple, dans un ensemble de données sur les ventes de téléphones, nous pouvons rechercher des termes significatifs sur les ventes de l'iPhone 16 comme suit :</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>Ensuite, la réponse nous donne :</p>{
 "aggregations": {
   "significant_cities": {
     "doc_count": 122,
     "bg_count": 424,
     "buckets": [
       {
         "key": "Houston",
         "doc_count": 12,
         "score": 0.1946481360617346,
         "bg_count": 14
       }

     ]
   }
 }
}<p>Houston ne figure pas parmi les 10 premières villes de l'ensemble des données, ni parmi les premières villes pour l'iPhone 16. Toutefois, l'agrégation des termes significatifs a montré que l'<em><strong> iPhone 16 est acheté de manière disproportionnée dans cette ville</strong></em> par rapport au reste des données. Voyons plus en détail les chiffres :</p><ul><li><p><strong>Au niveau supérieur :</strong></p><ul><li><p><strong>doc_count : 122 - </strong>La requête correspond à 122 documents au total</p></li><li><p><strong>bg_count : </strong>424 - Le jeu d'arrière-plan (tous les documents de vente) contient 424 documents.</p></li></ul></li><li><p><strong>Dans le seau de Houston :</strong></p><ul><li><p><strong>doc_count : 12 - </strong>Houston apparaît dans 12 des 122 résultats de la requête</p></li><li><p><strong>bg_count : 14 - </strong>Houston apparaît dans 14 des 424 documents de l'ensemble de données de base.</p></li></ul></li></ul><p>Cela nous indique que sur 424 achats totaux, seuls 14 ont eu lieu à Houston, soit 3,3% de tous les achats. Toutefois, si nous ne prenons en compte que les ventes d'iPhone 16, nous constatons que 12 des 122 ventes ont eu lieu à Houston, soit 9,8%, 3 fois plus que dans l'ensemble de l'ensemble des données ; c'est significatif !</p><p>Voici ce que cela donne en termes de visualisation : Ventes totales par ville_région.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blted1af6606708267e/6a17f5d614800960e1b488d5/f31335b0b7793650025f941820f238dd35bfb09f-1486x1066.png" alt="" /><p>Nous pouvons voir qu'il y a 14 ventes à Houston, ce qui en fait la 14e ville en termes de ventes dans l'ensemble des données.</p><p>Maintenant, si nous appliquons un filtre pour ne regarder que les ventes d'iPhone 16, nous avons 12 ventes à Houston, ce qui en fait la deuxième ville avec le plus grand nombre de ventes pour ce modèle spécifique :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd2882d5e87d02406/6a17f5d71d1b83851e93e5b2/6516040db77e6c62af5541a74c723b18008ad3c6-1472x1038.png" alt="" /><h2>Comprendre l'agrégation des termes significatifs</h2><p>Selon la documentation d'Elastic, les <a href="https://www.elastic.co/docs/reference/aggregations/search-aggregations-bucket-significantterms-aggregation">termes significatifs sont agrégation</a>:</p><p><em>"(Trouve) des termes qui ont subi un changement significatif de popularité mesuré entre un ensemble de premier plan et un ensemble d'arrière-plan."</em></p><p>Cela signifie qu'il utilise des mesures statistiques pour comparer la fréquence d'un terme dans un sous-ensemble de données (l'ensemble de premier plan) à la fréquence du même terme dans l'ensemble de données parent (l'ensemble d'arrière-plan). De cette manière, la notation reflète la signification statistique plutôt que la fréquence d'apparition d'un terme dans les données.</p><p>Les principales différences entre une agrégation de termes significatifs et une agrégation de termes normaux sont les suivantes :</p><ul><li><p>Les termes significatifs comparent un sous-ensemble de données, tandis qu'une agrégation de termes ne fonctionne que sur l'ensemble de données résultant de la requête.</p></li><li><p>Les résultats d'une agrégation de termes sont les termes les plus courants de l'ensemble de données, tandis que les résultats d'une agrégation de termes significatifs ignorent les termes courants pour trouver ce qui rend l'ensemble de données unique.</p></li><li><p>Les termes significatifs peuvent avoir un impact plus important sur les performances, étant donné qu'ils doivent extraire des données du disque plutôt que de la mémoire, comme le fait l'agrégation des termes.</p></li></ul><h2>Application pratique (analyse du comportement du consommateur)</h2><h3>Préparation des données pour l'analyse</h3><p>Pour cette analyse, nous avons généré un ensemble de données synthétiques sur les ventes de téléphones, comprenant le prix, les caractéristiques du téléphone, les données démographiques de l'acheteur et les commentaires. Nous avons également généré des embeddings à partir des commentaires de l'utilisateur afin de pouvoir lancer une requête sémantique ultérieurement. Nous avons utilisé le <a href="https://huggingface.co/intfloat/multilingual-e5-small">modèle multilingue e5 small</a>, disponible prêt à l'emploi sur Elasticsearch.</p><p></p><p>Pour utiliser ce jeu de données sur Elasticsearch :</p><ol><li><p>Téléchargez le fichier CSV (téléchargeable <a href="https://github.com/Alex1795/significant_terms_blog_dataset/blob/main/phone_sales_analysis_dataset.csv">ici)</a> à l'aide de la fonction Kibana <a href="https://www.elastic.co/docs/manage-data/ingest/upload-data-files">Upload data files.</a></p></li><li><p>Créez un champ sémantique, comme indiqué dans <a href="https://www.elastic.co/search-labs/blog/chat-with-pdf-elastic-playground#upload-pdfs-to-kibana">ce blog</a>, appelé "embedding", qui utilise le champ sémantique <code>multilingual-e5-small model</code></p></li><li><p>Terminez l'importation en conservant le type de champ par défaut (mot-clé pour chaque champ à l'exception de <code>purchase_date</code> et <code>user_feedback)</code>). Veillez à ajouter le nom de l'index <code>phone_sales_analysis</code> pour pouvoir exécuter les requêtes présentées ici telles quelles.</p></li></ol><p>L'objectif principal de cette analyse est de découvrir <em><strong>"ce qui différencie les acheteurs de l'iPhone 16 des autres segments de la population</strong></em>et d'obtenir une segmentation des acheteurs à des fins de marketing. </p><p>Il s'agit d'un exemple de document provenant de l'ensemble de données :</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>Comprendre les modèles démographiques</h3><p>Ici, nous allons effectuer une analyse sur la population générale et la comparer aux résultats intéressants des agrégations de termes significatifs pour les utilisateurs de l'iPhone 16.</p><h4>Modèles normaux</h4><p>Pour comprendre les habitudes d'achat, nous pouvons regrouper les données de tous les documents dans différents domaines. Pour simplifier, nous nous concentrerons sur l'étude des professions des personnes qui ont acheté un téléphone. Nous pouvons le faire en envoyant une requête à Elasticsearch.</p>GET phone_sales_analysis/_search
{
 "aggs": {
   "occupation_distribution": {
     "terms": {
       "size": 5,
       "field": "occupation"
     }
   }
 },
 "size": 0
}<p>Cela nous indique que les principales professions de l'ensemble de données (par nombre d'enregistrements) sont les suivantes :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltec11e3ae5b9cb3c0/6a17f5d9505ac3f28aad8cba/99136ddddd7abad5d74481158a04501b6915441b-1518x480.png" alt="" /><h4>Les habitudes des utilisateurs de l'iPhone 16</h4><p>Pour comprendre ce qui différencie les personnes qui ont acheté un iPhone 16, exécutons une agrégation de termes sur le même champ avec un filtre pour trouver ces personnes dans la requête, comme ceci :</p>GET phone_sales_analysis/_search
{
  "query": {
    "term": {
      "phone_model": "iPhone 16"
    }
  },
  "aggs": {
    "occupation_distribution": {
      "terms": {
        "size": 5,
        "field": "occupation"
      }
    }
  },
  "size": 0
}<p>Ainsi, pour les utilisateurs de l'iPhone 16, les principales professions sont les suivantes :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt26a5415e2f30d164/6a17f5da445de9637a4d028a/36ce86475beb03810c6ad81d7c776d1eec736654-1500x484.png" alt="" /><p>Nous pouvons constater que les utilisateurs de l'iPhone 16 ont des habitudes d'occupation différentes de celles des utilisateurs d'autres modèles de téléphone. Utilisons Kibana pour visualiser facilement les résultats :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4e0ddb09fe58e454/6a17f5dce317912cfa2d596b/b70ab05bc962a274e1617b6caf20575c489a62d8-1448x1128.png" alt="" /><p></p><p>Dans ce graphique, nous pouvons voir que la tendance pour l'iPhone 16 est différente de la tendance de la population entière.</p><p>Nous pouvons sauter toute cette analyse pour voir ce qui différencie les utilisateurs de l'iPhone 16 de la population générale en effectuant une agrégation de termes significatifs :</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 résumé, nous obtenons cette réponse :</p><p>Valeurs des professions pour l'iPhone 16</p><p>doc_count</p><p>bg_count</p><p>occupation_distribution (niveau supérieur)</p><p>122</p><p>424</p><p>Médical &amp; Seau pour les soins de santé</p><p>45</p><p>57</p><p>La réponse suggère clairement que les utilisateurs de l'iPhone 16 ont un problème (significatif !) peu commun. le nombre de personnes travaillant dans le domaine médical &amp; par rapport à la population générale. Voyons ce que signifient les chiffres de la réponse :</p><ul><li><p><strong>Au niveau supérieur :</strong></p><ul><li><p><strong>doc_count : 122 - </strong>La requête correspond à 122 documents au total</p></li><li><p><strong>bg_count : </strong>424 - Le jeu d'arrière-plan (tous les documents de vente) contient 424 documents.</p></li></ul></li><li><p><strong>Dans le secteur médical &amp; Soins de santé :</strong></p><ul><li><p><strong>doc_count : 45 - </strong>"Medical &amp; Healthcare" apparaît dans 45 des 122 résultats de la requête</p></li><li><p><strong>bg_count : 57 - </strong>"Medical &amp; Healthcare" apparaît dans 57 des 424 documents totaux de l'ensemble de données d'arrière-plan.</p></li></ul></li></ul><p>Sur les 424 acheteurs, 57 travaillent dans le domaine médical &amp; - soit 13,44%. Mais si l'on considère les acheteurs de l'iPhone 16, 45 sur 122 travaillent dans le domaine médical &amp; - soit 36,88%. Cela signifie que nous avons deux fois plus de chances de trouver une personne travaillant dans le domaine médical &amp; healthcare parmi les utilisateurs de l'iPhone 16 !</p><p>Nous pouvons appliquer cette même analyse à d'autres champs (âge, localisation, tranche de revenus, etc.) pour obtenir plus d'informations sur ce qui rend les utilisateurs de l'iPhone 16 uniques. </p><h3>Segmentation des consommateurs</h3><p>Nous pouvons utiliser l'agrégation des termes significatifs pour extraire des informations sur les relations entre les produits, les catégories et les segments de clientèle. Pour ce faire, nous construisons une agrégation parente pour la catégorie que nous souhaitons explorer. Nous utilisons également une sous-agrégation des termes significatifs et des termes normaux pour trouver des informations intéressantes sur cette catégorie et les comparer à ce qu'utilisent la plupart des personnes dans cette profession.</p><p>Voyons, par exemple, ce que préfèrent les gens dans certains domaines d'activité :</p><ol><li><p>Pour rendre l'analyse plus claire, limitons notre recherche à trois domaines de travail : ["Administratif &amp; Support", "Technologie &amp; Données", "Médical &amp; Soins de santé"]</p></li><li><p>En ce qui concerne les agrégations, nous commençons par une agrégation des termes par profession</p></li><li><p>Ajoutez une sous-agrégation : termes par modèle de téléphone - pour savoir quels modèles les utilisateurs travaillant dans chaque domaine achètent.</p></li><li><p>Ajoutez une deuxième sous-agrégation : les termes significatifs par modèle de téléphone - pour trouver les modèles spéciaux dans chaque domaine de travail.</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>Décortiquons les résultats de l'agrégation :</p><p><strong>Profession</strong>: Soutien administratif &amp;</p><p><strong>Agrégation de termes</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3a325cde37b40504/6a17f5dd4b055dbb68432372/a4ad519c9013867a3f4cee032160eadd8a47804a-1506x398.png" alt="" /><p><strong>Agrégation des termes significatifs</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltef514b8bbb7f429c/6a17f5df3e9e456488ba1612/e5604fa8036667bdfe733576a5e7c6153760dd3a-306x220.png" alt="" /><p>Ce tableau permet de déduire qu'il n'y a pas de différences significatives entre l'évolution de cette profession et celle de l'ensemble de la population.</p><p><strong>Profession</strong>: Technologie &amp; Données</p><p><strong>Agrégation de termes</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt94189446d8f3100e/6a17f5e142022983b029f76e/13b09039bb7d183276451007d2d69dc190b1d3c0-1508x836.png" alt="" /><p></p><p><strong>Agrégation des termes significatifs</strong></p><p>Total des documents : 424</p><p>Documents dans cette profession : 71</p><p>modèle de téléphone</p><p>doc_count (ce modèle dans cette profession)</p><p>bg_count (ce modèle figure dans tous les documents)</p><p>% dans tous les documents</p><p>% dans cette profession</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>Rien Télé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>Profession</strong>: Médical : &amp; Soins de santé</p><p><strong>Agrégation de termes</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt270b0a861a16488a/6a17f5e23e03d76a934f2df0/b008e996742fc0bb48dc6bacff17cfbc56cf0d73-1492x398.png" alt="" /><p><strong>Agrégation des termes significatifs</strong></p><p>Total des documents : 424</p><p>Documents dans cette profession : 57</p><p>modèle de téléphone</p><p>doc_count (ce modèle dans cette profession)</p><p>bg_count (ce modèle figure dans tous les documents)</p><p>% dans tous les documents</p><p>% dans cette profession</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>Voyons ce que ces données nous apprennent :</p><ul><li><p>Medical &amp; Les professionnels de la santé préfèrent l'iPhone 16 et sont très enclins à utiliser les téléphones Apple en général.</p></li><li><p>Technologie &amp; Les professionnels des données préfèrent les téléphones Android haut de gamme, mais n'utilisent pas nécessairement la marque Samsung. Dans cette catégorie, les iPhones ont également le vent en poupe.</p></li><li><p>Les professionnels de l'assistance administrative &amp; préfèrent les téléphones Samsung et Google, mais n'ont pas de tendance forte et unique.</p></li></ul><h3>Agrégation de termes significatifs et recherche hybride</h3><p>La recherche hybride combine la recherche textuelle et les résultats sémantiques pour offrir une meilleure expérience de recherche. Dans ce contexte, une agrégation significative de termes peut fournir des indications sur les résultats d'une recherche contextuelle en répondant à la question suivante : "Qu'est-ce que cet ensemble de données a de particulier par rapport à l'ensemble des documents ? <strong>Qu'est-ce que cet ensemble de données a de particulier par rapport à tous les documents ?</strong>Pour illustrer cette fonctionnalité, voyons quels modèles sont surreprésentés lorsque les utilisateurs parlent de bonnes performances : </p><ul><li><p>Construisons une requête sémantique dans laquelle nous trouvons les meilleurs commentaires d'utilisateurs les plus proches de l'entrée "bonne performance" par rapport à l'intégration des champs.</p></li><li><p>Nous utiliserons également une recherche textuelle avec les mêmes termes sur le champ de texte user_feedback</p></li><li><p>Nous ajouterons également une requête de termes significatifs pour trouver des modèles de téléphone qui peuvent être trouvés plus fréquemment parmi ces résultats que dans l'ensemble des données.
</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>Examinons un exemple de documents correspondants :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1c3dc221896c8832/6a17f5e4445de91eac4d028e/4cb488097a382f0c28c21540db4f593d23633473-1600x162.png" alt="" /><p>Voici la réponse que nous recevons :</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>Cela nous indique que si un iPhone 15 est rencontré 40 fois sur un total de 424 documents (9,4% des documents), il peut être trouvé 5 fois dans les 20 documents qui correspondent à la recherche sémantique "bonne performance" (25% des documents). Nous pouvons donc tirer une conclusion : un iPhone 15 a 2,7 fois plus de chances d'être trouvé lorsqu'on parle de bonnes performances que par hasard.</p><h2>Conclusion</h2><p>L'agrégation des termes significatifs permet de découvrir des détails uniques d'un ensemble de données en le comparant à l'univers des documents. Cela peut révéler des relations inattendues dans nos données, allant au-delà du nombre d'occurrences. Nous pouvons appliquer des termes significatifs dans divers cas d'utilisation qui permettent des fonctionnalités très intéressantes, par exemple :</p><ul><li><p><a href="https://www.elastic.co/blog/significant-terms-aggregation#credit">Trouvez des modèles lorsque vous travaillez sur la détection </a>des fraudes - identifiez les transactions courantes pour les cartes de crédit volées.</p></li><li><p>Informations sur la qualité de la marque à partir des avis des utilisateurs - détectez une marque dont le nombre d'avis négatifs est disproportionné.</p></li><li><p><a href="https://www.elastic.co/docs/reference/aggregations/search-aggregations-bucket-significantterms-aggregation#_use_on_free_text_fields">Repérer </a>les documents mal classés - repérer les documents qui appartiennent à une catégorie (filtre de termes) et qui utilisent des mots peu courants de la catégorie dans une description (agrégation de termes significatifs).</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[Les bases]]></category>
    <category><![CDATA[Query 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[Comment déployer Elasticsearch sur GCP GKE Autopilot]]></title>
    <description><![CDATA[Découvrez comment déployer un cluster Elasticsearch sur GCP en utilisant GKE Autopilot et ECK pour une configuration Elasticsearch partiellement gérée.]]></description>
    <content:encoded><![CDATA[<p>Dans cet article, nous allons découvrir comment déployer Elasticsearch sur Google Cloud Kubernetes (GKE) en utilisant Autopilot.</p><p>Pour Elasticsearch, nous allons utiliser <a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s">Elastic Cloud on Kubernetes </a>(ECK), qui est l’opérateur Kubernetes officiel d’Elasticsearch et qui simplifie l’orchestration des déploiements Kubernetes pour tous les composants Elastic Stack.</p><p>Pour en savoir plus sur la façon de déployer des clusters Elasticsearch sur différentes infrastructures GCP, vous pouvez consulter nos articles de prise en main pour <a href="https://www.elastic.co/search-labs/blog/elasticsearch-gpc-google-compute-engine">Google Cloud Compute</a> et <a href="https://www.elastic.co/search-labs/blog/deploy-elastic-gcp-marketplace">Google Cloud Marketplace</a>.</p><h2>Effort de déploiement d'Elasticsearch</h2><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt61969357430c94f8/6a17f6d125daab024708a3ae/56b54d718dcff9af9050873c41fdf738074851da-1428x582.png" alt="Procédure de déploiement Elasticsearch ECK" /><h3>Qu'est-ce que 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> offre une expérience Kubernetes entièrement gérée où Google prend en charge la configuration du cluster, la gestion des nœuds, la sécurité et la mise à l'échelle, tandis que les développeurs se concentrent sur le déploiement des applications, permettant aux équipes de passer du code à la production en quelques minutes grâce à de bonnes pratiques intégrées.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt91e10f44290aeac4/6a17f6d33e9e451f67ba1638/bbf6de63fa0a199326352f521cb22654818799f6-1600x958.png" alt="Conteneurs GKE Autopilot." /><h2>Quand utiliser l’ECK dans Google Cloud ?</h2><p>Elastic Cloud on Kubernetes (ECK) est parfaitement adapté aux entreprises qui disposent d'une infrastructure Kubernetes existante et souhaitent déployer Elasticsearch avec des fonctionnalités avancées telles que des rôles de nœuds dédiés, la haute disponibilité et l'automatisation.</p><h2>Comment configurer ECK dans Google Cloud ?</h2><p>1. Connectez-vous à la <a href="https://console.cloud.google.com">Google Cloud Console</a>.</p><p>2. <strong>En haut à droite</strong>, cliquezsur le bouton <strong>Cloud Shell</strong> pour accéder à la console, et déployez le cluster GKE à partir de là. Sinon, vous pouvez utiliser la <a href="https://cloud.google.com/cli">CLI gcloud</a>.</p><p><em><strong>N'oubliez pas de remplacer l'identifiant du projet par le vôtre pendant le tutoriel.</strong></em></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc69e47bf97e4be31/6a17f6d5505ac3bbe6ad8cdb/999b03861d4fe44f360ab4c7e2616e1dc10cf182-1558x1248.png" alt="Comment configurer Elasticsearch sur GCP GKE Autopilot." /><p>3. Activez l'<a href="https://console.cloud.google.com/flows/enableapi?apiid=container.googleapis.com">API Google Kubernetes Engine</a>.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1a4d95465f563ece/6a17f6d7e8fbced6393a1af3/03827d3dc0e987c019e7747d33e7c01920047beb-911x246.png" alt="Activation de l'API Google Kubernetes Engine" /><p>Cliquez sur <em><strong>Suivant</strong></em>.</p><p>L'API Kubernetes Engine devrait désormais apparaître comme activée lorsque vous recherchez cette API.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6ba41b82d995347f/6a17f6d8505ac3036bad8cdf/d5cd46f0333086bcb31b80cf9c08a469b449ec0f-640x250.png" alt="API Kubernetes Engine" /><p>4. Dans Cloud Shell, créez un cluster Autopilot. Nous le nommerons autopilot-cluster-1, et remplacerons également autopilot-test par l'identifiant de votre projet.</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. Attendez qu le cluster soit prêt. La création prend environ 10 minutes.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4e821e77d5db5d71/6a17f6da148009381cb48900/81fbc45ba56d0f16ba42724cb8ae45e60b327dbc-1581x258.png" alt="Image d'une configuration de cluster Autopilot" /><p>Un message de confirmation s’affiche après avoir correctement configuré le cluster.</p><p>6. Configurez l'accès à la ligne de commande kubectl.</p>gcloud container clusters get-credentials autopilot-cluster-1 --region us-central1 --project autopilot-test-457216<p>Vous devriez voir :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf1c828e5059c8ec8/6a17f6dcabe0f215e5dfebb7/b0beba1ee00ce9029f586ee32693fc2aa58c7f65-3442x142.png" alt="" /><p><em>Entrée kubeconfig générée pour autopilot-cluster-1</em></p><p>7. Installez l’opérateur <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. Créons une instance Elasticsearch à nœud unique avec les valeurs par défaut.</p><p>Si vous souhaitez consulter quelques recettes pour différentes configurations, suivez <a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s/recipes">ce lien</a>.</p><p>Gardez à l’esprit que si vous ne spécifiez pas de <code>storageClass</code>, ECK utilisera celui défini par défaut, qui, pour GKE, est <code>standard-rwo</code> et qui utilise le <a href="https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/gce-pd-csi-driver?cloudshell=true">disque persistant Compute Engine CSI Driver</a>, et créera un volume de 1 Go avec celui-ci.</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>Nous avons désactivé <code>nmap</code>, car la machine GKE par défaut a une valeur de <code>vm.max_map_count</code> trop basse. Il est recommandé de ne pas la désactiver pour la production, mais d'augmenter la valeur de <code>vm.max_map_count</code>. Vous pouvez en savoir plus sur la façon de <a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s/virtual-memory">procéder ici</a>.</p><p>9. Déployons également un cluster Kibana à nœud unique. Pour Kibana, nous ajouterons un équilibreur de charge qui nous donnera une adresse IP externe que nous pourrons utiliser pour accéder à Kibana depuis notre appareil.</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>Notez l'annotation : </p><p><code>cloud.google.com/l4-rbs: "enabled"</code></p><p><em><strong>Cette adresse est très importante car elle indique à Autopilot de fournir un équilibreur de charge accessible au public. Si l'adresse IP n'est pas définie, l'équilibreur de charge sera interne.</strong></em></p><p>10. Vérifiez que vos pods sont en cours d'exécution.</p>kubectl get pods<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt627dd8f482340bc2/6a17f6de3e03d779a44f2e16/99da1270581a137683770efdb9c6e1577ec9fc01-3150x442.png" alt="" /><p>11. Vous pouvez également <code>run kubectl get elasticsearch</code> et <code>kubectl get kibana</code> pour des statistiques plus spécifiques, telles que la version d'Elasticsearch, les nœuds et l'état d'intégrité.</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. Accédez à vos services.</p>kubectl get svc<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3806ad91791373a2/6a17f6e46df731bc800a10ab/ed1a07314b84a99b4aa1fec3db4b9badeb9587ee-3446x610.png" alt="" /><p>Cela vous indiquera l'URL externe de Kibana sous EXTERNAL-IP. Le provisionnement de l'équilibreur de charge prend quelques minutes. <em><strong>Copiez la valeur de EXTERNAL-IP.</strong></em></p><p>13. Obtenez le mot de passe Elasticsearch pour l’utilisateur "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>Accédez à Kibana</strong> depuis votre navigateur :</p><ul><li><p>URL : https://&lt;EXTERNAL_IP&gt;:5601</p></li><li><p>Nom d'utilisateur:elastic</p></li><li><p>Mot de passe : 28Pao50lr2GpyguX470L2uj5 (de l’étape précédente)</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd86d22f797132c21/6a17f6e7e8fbce62b43a1afb/47cbe88dc14db64db3a256f3f7504cc86a843475-463x503.png" alt="Écran de bienvenue Elastic" /><p>15. En accédant depuis votre navigateur, l'écran de bienvenue apparaît.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6f44dc23e6f1f625/6a17f6e9be6086ea71004948/a75c151c0144b7efe2b730698c0ed0156fa9b16a-1600x1005.png" alt="Page d'accueil d'Elasticsearch" /><p>Si vous souhaitez modifier les spécifications du cluster Elasticsearch, comme modifier ou redimensionner les nœuds, vous pouvez réappliquer le fichier manifeste yml avec les nouveaux paramètres :</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>Dans cet exemple, nous allons ajouter un nœud supplémentaire et modifier la mémoire vive et le processeur. Comme vous pouvez le voir, <code>kubectl get elasticsearch</code> affiche maintenant 2 nœuds :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt33a7ba0be483195a/6a17f6ebe8fbcea7da3a1aff/48b475622cc48890bff8105d151f2cbde28d7021-3418x298.png" alt="" /><p>Il en va de même pour 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>Nous pouvons ajuster le processeur/la RAM du conteneur ainsi que l'utilisation de la mémoire <a href="https://nodejs.org/">Node.js </a>(<a href="https://nodejs.org/api/cli.html#--max-old-space-sizesize-in-mib">max-old-space-size</a>).</p><p>N'oubliez pas que les <a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s/volume-claim-templates">revendications de volume existantes ne peuvent pas être réduites</a>. Après avoir appliqué la mise à jour, l'opérateur effectuera les modifications avec un temps de perturbation minimal.</p><p>N’oubliez pas de supprimer le cluster une fois les tests terminés pour éviter des coûts inutiles.</p>gcloud container clusters delete autopilot-cluster-1<h2>Étapes suivantes</h2><p>Si vous souhaitez en savoir plus sur Kubernetes et Google Kubernetes Engine, consultez ces articles :</p><ul><li><p><a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s">Elastic Cloud sur Kubernetes | Elastic Docs</a></p></li><li><p><a href="https://cloud.google.com/blog/products/containers-kubernetes/introducing-gke-autopilot">Présentation de GKE Autopilot | Blog Google Cloud</a></p></li><li><p><a href="https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-overview">Aperçu d'Autopilot | 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[Les bases]]></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 dans les règles de l'art, partie II]]></title>
    <description><![CDATA[Découvrez les bonnes pratiques en production et comment exécuter le client Elasticsearch Node.js dans des environnements serverless pour réduire les erreurs de codage. ]]></description>
    <content:encoded><![CDATA[<p>Voici la deuxième partie de notre série Elasticsearch en JavaScript. Dans la<a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i"> première partie,</a> nous avons appris à mettre en place notre environnement correctement, à configurer le client Node.js, à indexer les données et à effectuer des recherches. Dans cette deuxième partie, nous allons apprendre à mettre en œuvre les meilleures pratiques de production et à exécuter le client Elasticsearch <a href="http://node.js">Node.js</a> dans des environnements Serverless.</p><p>Nous ferons le point :</p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-ii#production-best-practices">Meilleures pratiques de production</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-ii#error-handling">Gestion des erreurs</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-ii#testing">Tests</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">Environnements sans serveur</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">Exécuter le client sur 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">Exécution du client dans un environnement de services fonctionnels (function-as-a-service)</a></p></li></ul></li></ul><p><em>Vous pouvez consulter le code source avec les exemples </em><a href="https://github.com/Delacrobix/JS-client-best-practices_article"><em><strong>ici</strong></em></a><em><strong>.</strong></em></p><h2>Meilleures pratiques de production</h2><h3>Gestion des erreurs dans Elasticsearch</h3><p>Une caractéristique utile du client Elasticsearch dans Node.js est qu'il expose des objets pour les erreurs possibles dans Elasticsearch afin que vous puissiez les valider et les traiter de différentes manières.</p><p>Pour <a href="https://www.elastic.co/docs/reference/elasticsearch/clients/javascript/connecting#client-error-handling">les voir tous</a>, cliquez ici : </p>const { errors } = require('@elastic/elasticsearch')
console.log(errors)<p>Revenons à l'exemple de la recherche et traitons certaines des erreurs possibles :</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 particulier, se produit lorsque la réponse est <code>4xx</code> ou <code>5xx</code>, ce qui signifie que la demande est incorrecte ou que le serveur n'est pas disponible.</p><p>Nous pouvons tester ce type d'erreur en générant des requêtes erronées, par exemple en essayant d'<strong>effectuer une recherche de terme sur un champ de type texte :</strong></p><p>Erreur par défaut :</p> {
    "success": false,
    "results": null,
    "error": "parsing_exception\n\tRoot causes:\n\t\tparsing_exception: [terms] query does not support [visit_details]"
}<p>Erreur personnalisée : </p>{
    "erroStatus": 400,
    "success": false,
    "results": null,
    "error": "Response error!, query malformed or server down; contact the administrator!"
}<p>Nous pouvons également capturer et traiter chaque type d'erreur d'une certaine manière. Par exemple, nous pouvons ajouter une logique de réessai dans un site <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>Tests</h3><p>Les tests sont essentiels pour garantir la stabilité de l'application. Pour tester le code d'une manière isolée d'Elasticsearch, nous pouvons utiliser la bibliothèque <a href="https://github.com/elastic/elasticsearch-js-mock">elasticsearch-js-mock</a> lors de la création de notre cluster.</p><p>Cette bibliothèque nous permet d'instancier un client qui est très similaire au vrai client mais qui répondra à notre configuration en remplaçant seulement la couche HTTP du client par une couche fictive tout en gardant le reste identique à l'original.</p><p>Nous installerons la bibliothèque mocks et <a href="https://github.com/avajs/ava">AVA</a> pour les tests automatisés.</p><p><code>npm install @elastic/elasticsearch-mock</code></p><p><code>npm install --save-dev ava</code></p><p>Nous allons configurer le fichier <code>package.json</code> pour exécuter les tests. Veillez à ce qu'il en soit ainsi :</p>"type": "module",
	"scripts": {
		"test": "ava"
	},
	"devDependencies": {
		"ava": "^5.0.0"
	}<p>Créons maintenant un fichier <code>test.js</code> et installons notre client fictif :</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>Maintenant, ajoutez un simulacre de recherche sémantique :</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>Nous pouvons maintenant créer un test pour notre code, en nous assurant que la partie Elasticsearch renvoie toujours les mêmes résultats :</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>Exécutons les tests.</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>C'est fait ! Désormais, nous pouvons tester notre application en nous concentrant à 100 % sur le code et non sur des facteurs externes.</p><h2>Environnements sans serveur</h2><h3>Exécution du client avec Elastic Serverless</h3><p>Nous avons abordé l'exécution d'Elasticsearch sur le Cloud ou sur site ; cependant, le client Node.js prend également en charge les connexions à <a href="https://www.elastic.co/guide/en/serverless/current/intro.html">Elastic Cloud Serverless</a>.</p><p>Elastic Cloud Serverless vous permet de créer un projet dans lequel vous n'avez pas besoin de vous préoccuper de l'infrastructure puisqu'Elastic s'en charge en interne, et vous n'avez qu'à vous préoccuper des données que vous souhaitez indexer et de la durée pendant laquelle vous souhaitez y avoir accès.</p><p>Du point de vue de l'utilisation, Serverless découple le calcul du stockage, offrant des fonctionnalités d'autoscaling pour la <a href="https://www.elastic.co/search-labs/blog/elasticsearch-serverless-tier-autoscaling">recherche</a> et l'<a href="https://www.elastic.co/search-labs/blog/elasticsearch-ingest-autoscaling">indexation</a>. Cela vous permet de n'augmenter que les ressources dont vous avez réellement besoin.</p><p>Le client effectue les adaptations suivantes pour se connecter à Serverless :</p><ul><li><p>Désactive le sniffing et ignore toutes les options liées au sniffing.</p></li><li><p>Ignore tous les nœuds passés dans la configuration sauf le premier, et ignore toutes les options de filtrage et de sélection des nœuds.</p></li><li><p>Active la compression et `TLSv1_2_method` (identique à la configuration pour Elastic Cloud)</p></li><li><p>Ajoute un en-tête HTTP `elastic-api-version` à toutes les requêtes</p></li><li><p>Utilise `CloudConnectionPool` par défaut au lieu de `WeightedConnectionPool`.</p></li><li><p>Désactive les en-têtes `content-type` et `accept` en faveur des types MIME standard.</p></li></ul><p>Pour connecter votre projet serverless, vous devez utiliser le paramètre serverMode : serverless.</p>const { Client } = require('@elastic/elasticsearch')
const client = new Client({
  node: 'ELASTICSEARCH_ENDPOINT',
  auth: { apiKey: 'ELASTICSEARCH_API_KEY' },
  serverMode: "serverless",
});<h3>Exécution du client sur une plateforme FaaS (Function-as-a-Service)</h3><p>Dans l'exemple, nous avons utilisé un serveur Node.js, mais vous pouvez également vous connecter en utilisant un environnement de fonction en tant que service avec des fonctions telles que 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>Un autre exemple consiste à se connecter à des services comme Vercel, qui est également sans serveur. Vous pouvez consulter cet <a href="https://github.com/elastic/elasticsearch-js/blob/main/docs/examples/proxy/README.md">exemple complet</a> de la manière de procéder, mais la partie la plus pertinente du <a href="https://github.com/elastic/elasticsearch-js/blob/main/docs/examples/proxy/api/search.js">point de terminaison de la recherche</a> ressemble à ceci :</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>Ce point d'accès se trouve dans le dossier /api et est exécuté du côté du serveur, de sorte que le client ne contrôle que le paramètre "text" qui correspond au terme de la recherche.</p><p>L'utilisation de la fonction en tant que service implique que, contrairement à un serveur fonctionnant 24 heures sur 24 et 7 jours sur 7, les fonctions ne font appel qu'à la machine qui exécute la fonction et, une fois celle-ci terminée, la machine passe en mode repos afin de consommer moins de ressources.</p><p>Cette configuration peut être pratique si l'application ne reçoit pas trop de demandes ; dans le cas contraire, les coûts peuvent être élevés. Vous devez également tenir compte du <a href="https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtime-environment.html">cycle de vie des fonctions</a> et des durées d'exécution (qui ne peuvent être que de quelques secondes dans certains cas).</p><h2>Conclusion</h2><p>Dans cet article, nous avons appris à gérer les erreurs, ce qui est crucial dans les environnements de production. Nous avons également abordé le test de notre application en simulant le service Elasticsearch, ce qui permet d'obtenir des tests fiables quel que soit l'état du cluster et de se concentrer sur notre code.</p><p>Enfin, nous avons montré comment mettre en place une pile entièrement sans serveur en provisionnant à la fois Elastic Cloud Serverless et une application 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[Les bases]]></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[Comment optimiser l'espace disque et l'utilisation d'Elasticsearch ?]]></title>
    <description><![CDATA[Découvrez comment prévenir et gérer les cas où le disque Elasticsearch est trop plein (surutilisation) et ceux où sa capacité est sous-utilisée afin d'optimiser les coûts du cluster.]]></description>
    <content:encoded><![CDATA[<p>La gestion des disques est importante pour toute base de données, et Elasticsearch ne fait pas exception. Si vous n'avez pas assez d'espace disque disponible, Elasticsearch arrêtera d'allouer des shards au nœud. Cela vous empêchera éventuellement d'écrire des données dans le cluster, avec le risque potentiel de perte de données dans votre application. En revanche, si vous disposez de trop d'espace disque, vous payez pour plus de ressources que vous n'en avez besoin.</p><h2>Historique des filigranes</h2><p>Il existe différents seuils "en filigrane" sur votre cluster Elasticsearch qui vous aident à suivre l'espace disque disponible. Lorsque le disque d'un nœud se remplit, le premier seuil à être franchi est le "filigrane de disque faible". Le deuxième seuil sera alors le "seuil de filigrane de disque élevé". Enfin, le "stade de l'inondation du disque" sera atteint. Une fois ce seuil dépassé, le cluster bloque l'écriture dans TOUS les index qui ont un shard (primaire ou réplique) sur le nœud qui a passé le filigrane. Les lectures (recherches) restent possibles.</p><h2>Comment prévenir et gérer les cas où le disque est trop plein (surutilisation) ?</h2><p>Il existe plusieurs méthodes pour gérer les cas où le disque Elasticsearch est trop plein :</p><ol><li><p><strong>Supprimer les</strong> <strong>anciennes données :</strong> En général, les données ne doivent pas être conservées indéfiniment. L'un des moyens de prévenir et de résoudre le problème des disques trop pleins est de veiller à ce que les données atteignant un certain âge soient archivées et supprimées de manière fiable. L'un des moyens d'y parvenir est d'utiliser l'<a href="https://www.elastic.co/docs/manage-data/lifecycle/index-lifecycle-management">ILM</a>.</p></li><li><p><strong>Augmenter la capacité de stockage :</strong> Si vous ne pouvez pas supprimer les données, vous pouvez ajouter des nœuds de données supplémentaires ou augmenter la taille des disques afin de conserver toutes les données sans nuire aux performances. Si vous devez ajouter de la capacité de stockage à la grappe, vous devez déterminer si vous devez ajouter uniquement de la capacité de stockage, ou à la fois de la capacité de stockage et des ressources RAM et CPU en proportion (voir la section sur le <a href="https://www.elastic.co/search-labs/blog/optimize-elasticsearch-disk-space-and-usage#the-relationship-between-disk-size,-ram-and-cpu">rapport entre la taille du disque, la RAM et le CPU</a> ci-dessous).</p></li></ol><h2>Comment ajouter de la capacité de stockage à votre cluster Elasticsearch ?</h2><ol><li><p><strong>Augmentez le nombre de nœuds de données : </strong>N'oubliez pas que les nouveaux nœuds doivent être de la même taille que les nœuds existants et de la même version d'Elasticsearch.</p></li><li><p><strong>Augmenter la taille des nœuds existants : </strong>Dans les environnements en nuage, il est généralement facile d'augmenter la taille du disque et la RAM/CPU sur les nœuds existants.</p></li><li><p><strong>Augmentez uniquement la taille du disque : </strong>Dans les environnements en nuage, il est souvent relativement facile d'augmenter la taille du disque.</p></li><li><p><a href="https://www.elastic.co/docs/deploy-manage/tools/snapshot-and-restore"><strong>Instantané</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>et</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>restauration</strong></a><strong>:</strong> Si vous souhaitez que les anciennes données soient récupérées sur demande dans le cadre d'un processus automatisé à partir des sauvegardes, vous pouvez prendre des clichés des anciens index, les supprimer et restaurer temporairement les données sur demande à partir des clichés. </p></li><li><p><strong>Réduire le nombre de répliques par groupe :</strong> Une autre option pour réduire les données consiste à réduire le nombre de répliques de chaque groupe. Pour des raisons de haute disponibilité, il est préférable d'avoir une réplique par bloc de données, mais lorsque les données vieillissent, il est possible de se passer de répliques. Cela peut généralement fonctionner si les données sont persistantes ou si vous disposez d'une sauvegarde à restaurer en cas de besoin.</p></li><li><p><strong>Créer des alertes :</strong> Afin d'éviter que les disques ne se remplissent à l'avenir et d'agir de manière proactive, vous devriez créer des alertes basées sur l'utilisation du disque qui vous préviendront lorsque le disque commencera à se remplir. </p></li></ol><h2>Comment prévenir et traiter les cas où la capacité du disque est sous-utilisée ?</h2><p>Si la capacité de votre disque est sous-utilisée, il existe plusieurs options pour réduire le volume de stockage de votre cluster.</p><h3>Comment réduire le volume de stockage d'un cluster Elasticsearch ?</h3><p>Il existe plusieurs méthodes pour réduire le volume de stockage d'un cluster.</p><p><strong>1. Réduire le nombre de nœuds de données</strong></p><p>Si vous souhaitez réduire le stockage des données et réduire les ressources RAM et CPU dans la même proportion, il s'agit de la stratégie la plus simple. Le déclassement des nœuds inutiles devrait permettre de réaliser les économies les plus importantes.</p><p>Avant de mettre le nœud hors service, vous devez.. :</p><ul><li><p>Assurez-vous que le nœud à mettre hors service n'est pas nécessaire en tant que nœud MASTER. Vous devez toujours avoir au moins trois nœuds ayant le rôle de nœud MASTER.</p></li><li><p>Migrer les blocs de données hors du nœud à mettre hors service.</p></li></ul><p><strong>2. Remplacer les nœuds existants par des nœuds plus petits</strong></p><p>Si vous ne pouvez pas réduire davantage le nombre de nœuds (en général, 3 est une configuration minimale), vous pouvez alors réduire la taille des nœuds existants. Il est conseillé de veiller à ce que tous les nœuds de données aient la même mémoire RAM et la même taille de disque, étant donné que l'équilibre des ensembles est basé sur le nombre d'ensembles par nœud.</p><p>La procédure serait la suivante :</p><ul><li><p>Ajouter de nouveaux nœuds plus petits à la grappe</p></li><li><p>Faire migrer les shards à l'écart des nœuds à déclasser</p></li><li><p>Arrêter les anciens nœuds</p></li></ul><p><strong>3. Réduire la taille des disques sur les nœuds</strong></p><p>Si vous souhaitez uniquement réduire la taille des disques sur les nœuds sans modifier la mémoire vive ou l'unité centrale de la grappe, vous pouvez réduire la taille des disques pour chaque nœud. La réduction de la taille du disque sur un nœud Elasticsearch n'est pas un processus trivial.</p><p>La manière la plus simple de le faire est généralement d'effectuer les opérations suivantes :</p><ul><li><p>Migrations de shards depuis le nœud</p></li><li><p>Arrêter le nœud</p></li><li><p>Monter un nouveau volume de données sur le nœud avec la taille appropriée</p></li><li><p>Copier toutes les données de l'ancien volume de disque vers le nouveau volume</p></li><li><p>Détacher l'ancien volume A</p></li><li><p>Démarrer le nœud et migrer les unités de stockage vers le nœud</p></li></ul><p>Pour ce faire, vous devez disposer d'une capacité suffisante sur les autres nœuds pour stocker temporairement les fragments supplémentaires du nœud au cours de ce processus. Dans de nombreux cas, le coût de la gestion de ce processus peut dépasser les économies potentielles en termes d'utilisation du disque. Pour cette raison, il peut être plus simple de remplacer le nœud par un nouveau nœud ayant la taille de disque souhaitée (voir "Remplacer les nœuds existants par des nœuds plus petits" ci-dessus).</p><p>Lorsque vous payez pour des ressources inutiles, il est évident que vous pouvez réduire les coûts en optimisant l'utilisation de vos ressources.</p><h2>La relation entre la taille du disque, la mémoire vive et le processeur</h2><p>Le rapport idéal entre la capacité des disques et la mémoire vive dans votre cluster dépend de votre cas d'utilisation particulier. C'est pourquoi, lorsque vous envisagez de modifier votre capacité de stockage, vous devez également vous demander si vos ratios actuels Disque/RAM/CPU sont bien équilibrés et si, par conséquent, vous devez également ajouter/réduire la RAM/CPU dans les mêmes proportions.</p><p>Les besoins en RAM et en CPU dépendent du volume de l'activité d'<a href="https://opster.com/guides/elasticsearch/glossary/elasticsearch-indexing/">indexation</a>, du nombre et du type de requêtes, ainsi que de la quantité de données recherchées et agrégées. Elle est souvent proportionnelle à la quantité de données stockées sur la grappe, et doit donc également être liée à la taille du disque.</p><p>Le rapport entre la capacité du disque et la mémoire vive peut varier en fonction du cas d'utilisation. Voir quelques exemples ici :</p><p></p><p>Activité de l'indice</p><p>Conservation</p><p>Activité de recherche</p><p>Capacité du disque</p><p>RAM</p><p>Application de recherche d'entreprise</p><p>Ingestion modérée de billes</p><p>Longues</p><p>Lumière</p><p>2TB</p><p>32GB</p><p>Surveillance des applications</p><p>Ingestion intensive de bois</p><p>Court</p><p>Lumière</p><p>1TB</p><p>32GB</p><p>Commerce électronique</p><p>Indexation des données légères</p><p>Indéfinie</p><p>Lourd</p><p>500GB</p><p>32GB</p><p><em>N'oubliez pas que la modification de la configuration des machines des nœuds doit être effectuée avec précaution, car elle peut entraîner l'arrêt du nœud et vous devez veiller à ce que les fragments ne commencent pas à migrer vers vos autres nœuds déjà surchargés.</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[Les bases]]></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 dans les règles de l'art, partie I]]></title>
    <description><![CDATA[Expliquer comment créer un backend Elasticsearch prêt pour la production en JavaScript.  

Découvrez comment utiliser Elasticsearch avec JavaScript pour créer un serveur avec différents points de terminaison de recherche afin d’interroger les documents Elasticsearch en suivant les bonnes pratiques client/serveur.]]></description>
    <content:encoded><![CDATA[<p>Cet article est le premier d'une série qui traite de l'utilisation d'Elasticsearch avec JavaScript. Dans cette série, vous apprendrez les bases de l'utilisation d'Elasticsearch dans un environnement JavaScript et passerez en revue les fonctionnalités les plus pertinentes et les meilleures pratiques pour créer une application de recherche. À la fin, vous saurez tout ce dont vous avez besoin pour exécuter Elasticsearch à l'aide de JavaScript.</p><p>Dans cette première partie, nous passerons en revue</p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#environment">Environnement</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 ou 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">Connexion du client</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">Indexation des documents</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#elasticsearch-client">Client 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">Correspondances sémantiques</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#bulk-helper">Aide en vrac</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">Recherche de données</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)">Requête lexicale</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)">Requête sémantique</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)">Requête hybride</a></p></li></ul></li></ul><p><em>Vous pouvez consulter le code source avec les exemples </em><a href="https://github.com/Delacrobix/JS-client-best-practices_article"><em><strong>ici</strong></em></a><em><strong>.</strong></em></p><h3>Qu'est-ce que le client Elasticsearch Node.js ?</h3><p>Le <a href="https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/index.html">client Elasticsearch Node.js</a> est une bibliothèque JavaScript qui transpose les appels HTTP REST de l'API Elasticsearch en JavaScript. Il est ainsi plus facile à manipuler et dispose d'assistants qui simplifient les tâches telles que l'indexation de documents par lots.</p><h2>Environnement</h2><h3>Frontend, backend ou serverless ?</h3><p>Pour créer notre application de recherche à l'aide du client JavaScript, nous avons besoin d'au moins deux composants : un cluster Elasticsearch et un moteur d'exécution JavaScript pour exécuter le client.</p><p>Le client JavaScript prend en charge toutes les solutions Elasticsearch (Cloud, on-prem et Serverless), et il n'y a pas de différences majeures entre elles puisque le client gère toutes les variations en interne, vous n'avez donc pas à vous soucier de savoir laquelle utiliser.</p><p>Le moteur d'exécution JavaScript doit toutefois être exécuté à partir du <strong>serveur</strong> et <strong>non directement à partir du navigateur.</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd3ec469c83e3a71a/6a17e3d5445de91da44d00b6/92ce6cfd923c8008fa44f617a58193642d9d5879-661x410.png" alt="Elasticsearch dans l’environnement JavaScript." /><p>En effet, en appelant Elasticsearch depuis le navigateur, l'utilisateur peut obtenir des informations sensibles telles que la clé API du cluster, l'hôte ou la requête elle-même. Elasticsearch recommande de <strong>ne jamais exposer le cluster directement à l'internet </strong>et d'utiliser une couche intermédiaire qui abstrait toutes ces informations de sorte que l'utilisateur ne puisse voir que les paramètres. Pour en savoir plus sur ce sujet <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/es-security-principles.html#security-protect-cluster-traffic">, cliquez ici.</a></p><p>Nous suggérons d'utiliser un schéma comme celui-ci :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4d7f215f2e70230a/6a17e3d6fbc5f83de6491a13/a08769f08ec73fe57bf2e961cfdfbb1cdd57919d-972x429.png" alt="Configuration du client Elasticsearch Node.js." /><p>Dans ce cas, le client n'envoie que les termes de recherche et une clé d'authentification pour votre serveur, tandis que votre serveur contrôle totalement la requête et la communication avec Elasticsearch.</p><h3>Connexion du client</h3><p>Commencez par créer une clé API en suivant <a href="https://www.elastic.co/search-labs/tutorials/install-elasticsearch/elastic-cloud">ces étapes.</a></p><p>En suivant l'exemple précédent, nous allons créer un simple serveur Express, et nous y connecter en utilisant un client depuis un serveur Node.JS.</p><p>Nous allons initialiser le projet avec NPM et installer le client Elasticsearch et <a href="https://expressjs.com/">Express.</a> Cette dernière est une bibliothèque qui permet d'activer des serveurs dans Node.js. En utilisant Express, nous pouvons interagir avec notre backend via HTTP.</p><p>Initialisons le projet :</p><p><code>npm init -y</code></p><p>Installer les dépendances :</p><p><code>npm install @elastic/elasticsearch express split2 dotenv</code></p><p>Laissez-moi vous expliquer :</p><ul><li><p><a href="https://www.npmjs.com/package/@elastic/elasticsearch"><em><strong>@elastic/elasticsearch</strong></em></a>: C'est le client officiel Node.js</p></li><li><p><a href="https://www.npmjs.com/package/express"><em><strong>express</strong></em></a>: Il nous permettra de faire tourner un serveur nodejs léger pour exposer Elasticsearch.</p></li><li><p><a href="https://www.npmjs.com/package/split2"><em><strong>split2</strong></em></a>: divise les lignes de texte en un flux. Utile pour traiter nos fichiers ndjson une ligne à la fois</p></li><li><p><a href="https://www.npmjs.com/package/dotenv"><em><strong>dotenv</strong></em></a>: Permet de gérer les variables d'environnement à l'aide d'un fichier .env fichier</p></li></ul><p>Créer un fichier .env à la racine du projet et ajoutez les lignes suivantes :</p>ELASTICSEARCH_ENDPOINT="Your Elasticsearch endpoint"
ELASTICSEARCH_API_KEY="Your Elasticssearch API"<p>Ainsi, nous pouvons importer ces variables à l'aide du paquetage <code>dotenv</code>.</p><p>Créer un fichier <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>Ce code met en place un serveur Express.js de base qui écoute sur le port 3000 et se connecte à un cluster Elasticsearch en utilisant une clé API pour l'authentification. Il comprend un point d'extrémité /ping qui, lorsqu'on y accède par une requête GET, interroge le cluster Elasticsearch pour obtenir des informations de base à l'aide de la méthode <code>.info()</code> du client Elasticsearch. </p><p>Si la requête aboutit, elle renvoie les informations sur le cluster au format JSON ; dans le cas contraire, elle renvoie un message d'erreur. Le serveur utilise également un intergiciel d'analyseur de corps pour traiter les corps de requête JSON.</p><p>Exécutez le fichier pour lancer le serveur :</p><p><code>node server.js</code></p><p>La réponse devrait ressembler à ceci :</p>Server running on port 3000<p>Et maintenant, consultons le point de terminaison <code>/ping</code> pour vérifier l'état de notre cluster 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>Indexation des documents</h2><p>Une fois connectés, nous pouvons indexer les documents à l'aide de mappings tels que <a href="https://www.elastic.co/search-labs/blog/semantic-search-simplified-semantic-text">semantic_text</a> pour la recherche sémantique et text pour les requêtes en texte intégral. Avec ces deux types de champs, nous pouvons également effectuer une <a href="https://www.elastic.co/what-is/hybrid-search">recherche hybride</a>.</p><p>Nous allons créer un nouveau fichier <code>load.js</code> pour générer les correspondances et télécharger les documents.</p><h3>Client Elasticsearch</h3><p>Nous devons d'abord instancier et authentifier le client :</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>Correspondances sémantiques</h3><p>Nous allons créer un index contenant des données sur un hôpital vétérinaire. Nous stockons les informations concernant le propriétaire, l'animal et les détails de la visite.</p><p>Les données sur lesquelles nous voulons effectuer une recherche en texte intégral, telles que les noms et les descriptions, seront stockées sous forme de texte. Les données des catégories, telles que l'espèce ou la race de l'animal, seront stockées sous forme de mots-clés.</p><p>En outre, nous copierons les valeurs de tous les champs dans un champ semantic_text afin de pouvoir effectuer une recherche sémantique sur ces informations également.</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>Aide en vrac</h3><p>Un autre avantage du client est qu'il est possible d'utiliser l'<a href="https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/client-helpers.html#bulk-helper">assistant de masse</a> pour indexer par lots. L'assistant de masse nous permet de gérer facilement des choses comme la concurrence, les tentatives, et ce qu'il faut faire avec chaque document qui passe par la fonction et qui réussit ou échoue.</p><p>L'une des caractéristiques intéressantes de cette aide est qu'elle permet de travailler avec des flux. Cette fonction vous permet d'envoyer un fichier ligne par ligne au lieu de stocker le fichier complet dans la mémoire et de l'envoyer à Elasticsearch en une seule fois.</p><p>Pour télécharger les données vers Elasticsearch, créez un fichier appelé data.ndjson à la racine du projet et ajoutez les informations ci-dessous (vous pouvez également télécharger le fichier avec le jeu de données à partir d'<a href="https://github.com/Delacrobix/JS-client-best-practices_article/blob/main/data.ndjson">ici</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>Nous utilisons split2 pour streamer les lignes de fichiers pendant que l'assistant bulk les envoie à 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>Le code ci-dessus lit un fichier .ndjson ligne par ligne et indexe en bloc chaque objet JSON dans un index Elasticsearch spécifié à l'aide de la méthode <code>helpers.bulk</code>. Il diffuse le fichier en utilisant <code>createReadStream</code> et <code>split2</code>, met en place des métadonnées d'indexation pour chaque document et enregistre tous les documents qui ne sont pas traités. Une fois l'opération terminée, il enregistre le nombre d'éléments indexés avec succès.</p><p>En lieu et place de la fonction <code>indexData</code>, vous pouvez télécharger le fichier directement via l'interface utilisateur à l'aide de Kibana et utiliser l'<a href="https://www.elastic.co/docs/manage-data/ingest/upload-data-files">interface utilisateur de téléchargement des fichiers de données.</a></p><p>Nous exécutons le fichier pour télécharger les documents vers notre cluster 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>Recherche de données dans Elasticsearch</h2><p>En revenant à notre fichier <code>server.js</code>, nous allons créer différents points de terminaison pour effectuer une recherche lexicale, sémantique ou hybride.</p><p>En résumé, ces types de recherche ne s'excluent pas mutuellement, mais dépendent du type de question à laquelle vous devez répondre.</p><p>Type de requête</p><p>Cas d'utilisation</p><p>Exemple de question</p><p>Requête lexicale</p><p>Les mots ou racines de mots de la question sont susceptibles d'apparaître dans les documents de l'index. Similitude des jetons entre la question et les documents.</p><p>Je cherche un t-shirt de sport bleu.</p><p>Requête sémantique</p><p>Les mots de la question ne sont pas susceptibles de figurer dans les documents. Similitude conceptuelle entre la question et les documents.</p><p>Je cherche des vêtements pour le froid.</p><p>Recherche hybride</p><p>La question contient des éléments lexicaux et/ou sémantiques. Similitude toxique et sémantique entre les questions et les documents.</p><p>Je cherche une robe taille S pour un mariage sur la plage.</p><p>Les parties <em><strong>lexicales </strong></em>de la question sont susceptibles de faire partie de titres et de descriptions, ou de noms de catégories, tandis que les parties <em><strong>sémantiques </strong></em>sont des concepts liés à ces domaines. Le <em><strong>bleu</strong></em> sera probablement un nom de catégorie ou une partie de la description, et le <em><strong>mariage à la plage</strong></em> ne le sera probablement pas, mais il peut être sémantiquement lié aux vêtements en lin.</p><h3>Requête lexicale (/search/lexic?q=&lt;query_term&gt;)</h3><p>La recherche lexicale, également appelée recherche en texte intégral, consiste à effectuer une recherche basée sur la similarité des mots-clés, c'est-à-dire qu'après une analyse, les documents qui contiennent les mots-clés de la recherche seront renvoyés.</p><p>Vous pouvez consulter notre tutoriel pratique sur la recherche lexicale <a href="https://www.elastic.co/demo-gallery/lexical-search">ici.</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>Nous testons avec : <em><strong>coupe-ongles</strong></em></p>curl http://localhost:3000/search/lexic?q=nail%20trimming<p>Réponse :</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>Requête sémantique (/search/semantic?q=&lt;query_term&gt;)</h3><p>La recherche sémantique, contrairement à la recherche lexicale, permet de trouver des résultats similaires à la signification des termes de recherche par le biais d'une recherche vectorielle.</p><p>Vous pouvez consulter notre tutoriel pratique sur la recherche sémantique <a href="https://www.elastic.co/demo-gallery/semantic-search">ici.</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>Nous testons avec : <em><strong>Qui s'est fait faire une pédicure ?</strong></em></p>curl http://localhost:3000/search/semantic?q=Who%20got%20a%20pedicure?<p>Réponse :</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>Requête hybride (/search/hybrid?q=&lt;query_term&gt;)</h3><p>La recherche hybride nous permet de combiner la recherche sémantique et la recherche lexicale, et d'obtenir ainsi le meilleur des deux mondes : vous bénéficiez de la précision de la recherche par jeton, ainsi que de la proximité de sens de la recherche sémantique.</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>Nous testons avec "<em><strong>Qui a reçu une pédicure ou un traitement dentaire ?"</strong></em></p>curl http://localhost:3000/search/hybrid?q=who%20got%20a%20pedicure%20or%20dental%20treatment<p>Réponse :</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>Conclusion</h2><p>Dans cette première partie de notre série, nous avons expliqué comment configurer notre environnement et créer un serveur avec différents points de terminaison de recherche pour interroger les documents Elasticsearch en suivant les meilleures pratiques client/serveur. Consultez la <a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i">deuxième partie</a> de notre série, dans laquelle vous découvrirez les meilleures pratiques de production et comment exécuter le client Elasticsearch Node.js dans des environnements sans serveur.</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[Les bases]]></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[Comment configurer le nombre de réplicas dans un index Elasticsearch]]></title>
    <description><![CDATA[Apprenez à configurer le number_of_replicas dans un index Elasticsearch afin d'améliorer les performances de rechercher et de renforcer la résilience en cas de panne de node. 
]]></description>
    <content:encoded><![CDATA[<p>Elasticsearch est conçu pour être un système distribué capable de gérer un grand nombre de données et d'assurer une haute disponibilité. L'une des fonctions clés qui permet cela est le concept de réplication d'index, qui est contrôlé par le paramètre <code>number_of_replicas</code>. Cet article aborde les détails de ce paramètre, ses implications et la manière de le configurer correctement.</p><h2>Le rôle des répliques dans Elasticsearch</h2><p>Dans Elasticsearch, un index est une collection de documents qui sont répartis sur plusieurs shards primaires. Chaque groupe primaire est un index Apache Lucene autonome, et les documents d'un index sont répartis entre tous les groupes primaires. Pour garantir la haute disponibilité et la redondance des données, Elasticsearch permet à chaque nuage d'avoir une ou plusieurs copies, appelées répliques.

Le paramètre <code>number_of_replicas</code> contrôle le nombre de répliques (copies) qu'Elasticsearch crée pour chaque réplique primaire d'un index. Par défaut, Elasticsearch crée une réplique pour chaque shard primaire, mais cela peut être modifié en fonction des besoins de votre système.</p><h2>Configuration du nombre de répliques (number_of_replicas)</h2><p>Le paramètre <code>number_of_replicas</code> peut être configuré au moment de la création de l'index ou mis à jour ultérieurement. Voici comment vous pouvez le définir lors de la création de l'index :</p>PUT /my_index
{
  "settings": {
    "number_of_replicas": 2
  }
}<p>Dans cet exemple, Elasticsearch créera deux réplicas pour chaque fichier primaire de l'index <code>my_index</code>.</p><p>Pour mettre à jour le paramètre <code>number_of_replicas</code> d'un index existant, vous pouvez utiliser l'API <code>_settings</code>:</p>PUT /my_index/_settings
{
  "number_of_replicas": 3
}<p>Cette commande mettra à jour l'index <code>my_index</code> pour qu'il y ait trois réplicas pour chaque groupe primaire.</p><h2>Implications du paramètre number_of_replicas (nombre de répliques)</h2><p>Le paramètre <code>number_of_replicas</code> a un impact significatif sur les performances et la résilience de votre <a href="https://opster.com/guides/elasticsearch/glossary/elasticsearch-cluster/">cluster</a> Elasticsearch. Voici quelques points clés à prendre en considération :</p><ol><li><p><strong>Redondance et disponibilité des données :</strong> L'augmentation du site <code>number_of_replicas</code> améliore la disponibilité de vos données en créant davantage de copies de chaque groupe de données. Si un nœud tombe en panne, Elasticsearch peut toujours servir des données à partir des répliques sur les <a href="https://opster.com/guides/elasticsearch/glossary/elasticsearch-node/">nœuds</a> restants.</p></li><li><p><strong>Performances de recherche :</strong> Les répliques peuvent répondre à des demandes de lecture. Le fait de disposer d'un plus grand nombre de répliques peut donc améliorer les performances en matière de recherche en répartissant la charge sur un plus grand nombre de répliques.</p></li><li><p><strong>Performance d'écriture :</strong> Cependant, chaque opération d'écriture doit être exécutée sur chaque copie d'un groupe de données. Par conséquent, une adresse <code>number_of_replicas</code> plus élevée peut ralentir les performances d'<a href="https://opster.com/guides/elasticsearch/glossary/elasticsearch-indexing/">indexation</a> car elle augmente le nombre d'opérations à effectuer pour chaque écriture.</p></li><li><p><strong>Exigences en matière de stockage :</strong> Plus il y a de répliques, plus il y a d'espace de stockage. Vous devez vous assurer que votre cluster dispose d'une capacité suffisante pour stocker les répliques supplémentaires.</p></li><li><p><strong>Résilience en cas de défaillance d'un nœud :</strong> Le site <code>number_of_replicas</code> doit être défini en fonction du nombre de nœuds de votre cluster. Si le site <code>number_of_replicas</code> est égal ou supérieur au nombre de nœuds, votre cluster peut tolérer la défaillance de plusieurs nœuds sans perte de données.</p></li></ol><h2>Bonnes pratiques pour définir le nombre de répliques (number_of_replicas)</h2><p>Le réglage optimal de <code>number_of_replicas</code> dépend des exigences spécifiques de votre système. Toutefois, voici quelques bonnes pratiques générales :</p><ul><li><p>Pour un cluster à un seul nœud, <code>number_of_replicas</code> doit être fixé à 0, car il n'y a pas d'autres nœuds pour contenir des répliques.</p></li><li><p>Pour un cluster à plusieurs nœuds, <code>number_of_replicas</code> doit être réglé sur au moins 1 pour assurer la redondance des données et la haute disponibilité.</p></li><li><p>Si la performance de la recherche est une priorité, envisagez d'augmenter le site <code>number_of_replicas</code>. Toutefois, il convient de garder à l'esprit le compromis entre les performances d'écriture et les exigences en matière de stockage.</p></li><li><p>Assurez-vous toujours que votre cluster dispose d'une capacité suffisante pour stocker les répliques supplémentaires.</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[Les bases]]></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[Suppression d'un champ d'un document dans Elasticsearch]]></title>
    <description><![CDATA[Apprenez à supprimer des champs de documents Elasticsearch à l'aide de l'API de mise à jour, de scripts ou de la réindexation pour des suppressions uniques ou en masse.]]></description>
    <content:encoded><![CDATA[<p>Dans Elasticsearch, il est fréquent de devoir supprimer un champ d'un document. Cela peut s'avérer utile lorsque vous souhaitez supprimer des informations inutiles ou obsolètes de votre index. Dans cet article, nous aborderons différentes méthodes pour supprimer un champ d'un document dans Elasticsearch, avec des exemples et des instructions pas à pas. </p><h2>Méthode 1 : Utilisation de l'API de mise à jour</h2><p><a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/update-document">API Update</a> vous permet de mettre à jour un document en fournissant un script qui modifie la source du document. Vous pouvez utiliser cette API pour supprimer un champ d'un document en lui attribuant la valeur null. Voici un guide étape par étape pour y parvenir :</p><p>1. Identifiez l'index, le type de document (si vous utilisez Elasticsearch 6.x ou une version antérieure) et l'ID du document que vous souhaitez mettre à jour.</p><p>2. Utilisez l'API de mise à jour avec un script qui définit le champ comme nul ou, mieux encore, le supprime du document source. L'exemple suivant montre comment supprimer le champ "field_to_delete" d'un document dont l'ID est "1" dans l'index "my_index" :</p>POST /my_index/_update/1
{
  "script": "ctx._source.remove('field_to_delete')"
}<p>3. Exécuter la demande. En cas de succès, Elasticsearch renvoie une réponse indiquant que le document a été mis à jour.</p><p>Note : Cette méthode ne supprime le champ que du document spécifié. Le champ existera toujours dans la cartographie et dans les autres documents de l'index.</p><h2>Méthode 2 : Réindexation avec une source modifiée</h2><p>Si vous souhaitez supprimer un champ de tous les documents d’un index, vous pouvez utiliser l’<a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-reindex">API Reindex</a> pour créer un nouvel index avec la source modifiée. Voici comment procéder :</p><p>1. Créez un nouvel index avec les mêmes paramètres et mappages que l'index original. Vous pouvez utiliser l'API Get Index pour récupérer les paramètres et les mappages de l'index original.</p><p>2. Utilisez l'API Reindex pour copier les documents de l'index original vers le nouvel index, tout en supprimant le champ de la source. L'exemple suivant montre comment supprimer le champ "field_to_delete" de tous les documents de l'index "my_index" :</p>POST /_reindex
{
  "source": {
    "index": "my_index"
  },
  "dest": {
    "index": "new_index"
  },
  "script": {
    "source": "ctx._source.remove('field_to_delete')"
  }
}<p>
3. Vérifier que le nouvel index contient les documents corrects avec le champ supprimé.</p><p>4. Si tout semble correct, vous pouvez supprimer l'index original et, si nécessaire, ajouter un alias au nouvel index portant le nom de l'index original.</p><h2>Méthode 3 : Mise à jour du mapping et réindexation</h2><p>Si vous souhaitez supprimer un champ du mappage et de tous les documents d'un index, vous pouvez mettre à jour le mappage, puis réindexer les documents. Voici comment procéder :</p><p>1. Créez un nouvel index avec les mêmes paramètres que l'index original.</p><p>2. Récupérer les mappings de l'index original à l'aide de l'API "Get Mapping".</p><p>3. Modifiez les correspondances en supprimant le champ que vous souhaitez supprimer.</p><p>4. Appliquez les mappages modifiés au nouvel index à l'aide de l'API Put Mapping.</p><p>5. Utilisez l'API de réindexation pour copier les documents de l'index d'origine vers le nouvel index, comme décrit dans la méthode 2.</p><p>6. Vérifiez que le nouvel index contient les documents corrects avec le champ supprimé et que le champ n'est pas présent dans le mappage.</p><p>7. Si tout semble en ordre, vous pouvez supprimer l’index original et, si nécessaire, ajouter un alias au nouvel index avec le nom de l’index original.</p><h2>Conclusion</h2><p>Dans cet article, nous avons abordé trois méthodes pour supprimer un champ d'un document dans Elasticsearch : l'utilisation de l'API de mise à jour, la réindexation avec une source modifiée et la mise à jour du mappage et la réindexation. Chaque méthode a ses propres cas d'utilisation et ses propres compromis, choisissez donc celle qui répond le mieux à vos besoins. N'oubliez jamais de tester vos modifications et de vérifier les résultats avant de les appliquer aux environnements de production.</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[Les bases]]></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[Comment joindre deux index dans Elasticsearch]]></title>
    <description><![CDATA[Explication de l'utilisation des termes query, Logstash elasticsearch filter, the enrich processor et ES|QL pour joindre deux index dans Elasticsearch.]]></description>
    <content:encoded><![CDATA[<p>Dans Elasticsearch, joindre deux index n'est pas aussi simple que dans les bases de données relationnelles SQL traditionnelles. Cependant, il est possible d'obtenir des résultats similaires en utilisant certaines techniques et fonctionnalités fournies par Elasticsearch.</p><p>Historiquement, de nombreuses personnes ont utilisé le <a href="https://www.elastic.co/fr/docs/reference/elasticsearch/mapping-reference/nested"><code>nested</code></a><a href="https://www.elastic.co/fr/docs/reference/elasticsearch/mapping-reference/nested"> type de</a> champ comme un mécanisme permettant de relier différents indices entre eux. Cependant, elle a été limitée par des requêtes coûteuses et une prise en charge incomplète dans Kibana, en particulier pour les visualisations de Lens.</p><p>Cet article se penche sur le processus de jonction de deux index dans Elasticsearch, en se concentrant sur les approches suivantes : </p><ol><li><p>Utilisation de la requête <code>terms</code></p></li><li><p>Utilisation du processeur <code>enrich</code> dans les pipelines d'ingestion</p></li><li><p>Logstash <code>elasticsearch</code> filter plugin</p></li><li><p>ES|QL <code>ENRICH</code></p></li><li><p>ES|QL <code>LOOKUP JOIN</code></p></li></ol><h2>Utilisation des termes de la requête</h2><p>La <a href="https://www.elastic.co/fr/docs/reference/query-languages/query-dsl/query-dsl-terms-query">requête terms</a> est l'un des moyens les plus efficaces de joindre deux index dans Elasticsearch. Cette requête permet de retrouver des documents contenant un ou plusieurs termes exacts dans un champ spécifique. Nous verrons ici comment l'utiliser pour joindre deux indices.</p><p>Tout d'abord, vous devez extraire les données requises du premier index. Cela peut être fait en utilisant une simple requête GET et en extrayant les valeurs de l'attribut <code>_source</code>.</p># Simple GET request
GET first_index/_search<p>Une fois que vous avez les données du premier index, vous pouvez les utiliser pour interroger le deuxième index. Cette opération s'effectue à l'aide de la requête <code>terms</code>, dans laquelle vous indiquez le champ et les valeurs que vous souhaitez faire correspondre.</p><p>En voici un exemple :</p>GET second_index/_search
{
  "query": {
    "terms": {
      "field_in_second_index": ["value1_from_first_index", "value2_from_first_index"]
    }
  }
}<p>
Dans cet exemple, <code>field_in_second_index</code> est le champ du deuxième index que vous souhaitez faire correspondre aux valeurs du premier index. <code>value1_from_first_index</code> et <code>value2_from_first_index</code> sont les valeurs du premier index que vous voulez faire correspondre au deuxième index.</p><p>La recherche de termes permet également d'effectuer les deux étapes ci-dessus en une seule fois à l'aide d'une technique appelée " <a href="https://www.elastic.co/fr/docs/reference/query-languages/query-dsl/query-dsl-terms-query#query-dsl-terms-lookup">recherche de termes".</a> Elasticsearch se chargera de récupérer de manière transparente les valeurs à faire correspondre à partir d'un autre index. Par exemple, si vous disposez d'un index des équipes contenant une liste de joueurs :</p>PUT teams/_doc/team1
{
  "players":   ["john", "bill", "michael"]
}
PUT teams/_doc/team2
{
  "players":   ["aaron", "joe", "donald"]
}<p>Il est possible d'interroger un index de personnes pour connaître toutes les personnes jouant dans l'équipe 1, comme indiqué ci-dessous :</p>GET people/_search?pretty
{
  "query": {
    "terms": {
        "name" : {
            "index" : "teams",
            "id" : "team1",
            "path" : "players"
        }
    }
  }
}<p>Dans l'exemple ci-dessus, Elasticsearch récupère de manière transparente les noms des joueurs à partir du document avec l'identifiant team1 dans l'index teams (c'est-à-dire "john", "bill" et "michael") et trouver tous les documents de l'index des personnes contenant l'une de ces valeurs dans le champ "nom".</p><p>Pour les curieux, la requête SQL équivalente serait la suivante :</p><h2>Utilisation du processeur d'enrichissement</h2><p>Le <a href="https://www.elastic.co/fr/docs/reference/enrich-processor/enrich-processor"><code>enrich</code></a><a href="https://www.elastic.co/fr/docs/reference/enrich-processor/enrich-processor"> processeur</a> est un autre outil puissant qui peut être utilisé pour joindre deux index dans Elasticsearch. Ce processeur enrichit les données des documents entrants en ajoutant des données provenant d'un index d'enrichissement prédéfini.</p><p>Voici comment utiliser le processeur d'enrichissement pour joindre deux indices :</p><p>1. Tout d'abord, vous devez créer une politique d'enrichissement. Cette politique définit l'index à utiliser pour l'enrichissement, le champ à utiliser et le(s) champ(s) à utiliser pour enrichir les documents entrants.</p><p>En voici un exemple :</p>PUT _enrich/policy/my_enrich_policy
{
  "match": {
    "indices": "first_index",
    "match_field": "field_in_first_index",
    "enrich_fields": ["field_to_enrich"]
  }
}<p>2. Une fois la politique créée, vous devez l'exécuter pour créer l'index d'enrichissement à partir de votre nouvelle politique :</p>PUT _enrich/policy/my_enrich_policy/_execute<p>Cela permet de créer un nouvel index caché enrichi qui sera utilisé lors de l'enrichissement. Selon la taille de l'index source, cette opération peut prendre un certain temps. Assurez-vous que la politique d'enrichissement est entièrement construite avant de passer à l'étape suivante.</p><p>3. Une fois la politique d'enrichissement élaborée, vous pouvez utiliser le processeur d'enrichissement dans un pipeline d'acquisition pour enrichir les données des documents entrants :</p>PUT _ingest/pipeline/my_pipeline
{
  "processors": [
    {
      "enrich": {
        "policy_name": "my_enrich_policy",
        "field": "field_in_second_index",
        "target_field": "enriched_field"
      }
    }
  ]
}<p>Dans cet exemple, <code>field_in_second_index</code> est le champ du deuxième index qui doit correspondre au champ <code>match_field</code> du premier index. <code>enriched_field</code> est le nouveau champ du deuxième index qui contiendra les données enrichies de <code>enrich_fields</code> dans le premier index.</p><p>L'un des inconvénients de cette approche est que si les données changent sur <code>first_index</code>, la politique d'enrichissement doit être réexécutée. L'index enrichi n'est pas mis à jour ou synchronisé automatiquement à partir de l'index source à partir duquel il a été construit. Cependant, si <code>first_index</code> est relativement stable, cette approche fonctionne bien.</p><h2>Plugin de filtre Logstash elasticsearch</h2><p>Si vous utilisez Logstash, une autre option similaire au processeur <code>enrich</code> décrit ci-dessus consiste à utiliser le plugin de filtre <code>elasticsearch</code> pour ajouter des champs pertinents à l'événement sur la base d'une requête spécifiée. La configuration de notre pipeline Logstash se trouve dans un fichier <code>.conf</code>, tel que <code>my-pipeline.conf</code>.</p><p>Imaginons que notre pipeline extrait des logs d'Elasticsearch à l'aide du <a href="https://www.elastic.co/fr/docs/reference/logstash/plugins/plugins-inputs-elasticsearch"><code>elasticsearch</code></a><a href="https://www.elastic.co/fr/docs/reference/logstash/plugins/plugins-inputs-elasticsearch"> plugin</a> d'entrée, avec une requête pour réduire la sélection :</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 nous voulons enrichir ces messages avec des informations provenant d'un index donné, nous pouvons utiliser le <a href="https://www.elastic.co/fr/docs/reference/logstash/plugins/plugins-filters-elasticsearch"><code>elasticsearch</code></a><a href="https://www.elastic.co/fr/docs/reference/logstash/plugins/plugins-filters-elasticsearch"> plugin de filtre</a> dans la <code>filter</code> section pour enrichir nos journaux :</p>filter {
   elasticsearch {
      hosts =&gt; ["localhost"]
      index =&gt; "index_name"
      query =&gt; "type:start AND operation:%{[opid]}"
      fields =&gt; { "@timestamp" =&gt; "started" }
   }
}<p>Le code ci-dessus trouvera les documents de l'index <code>index_name</code> où <code>type</code> est le début et le champ opération correspond au champ spécifié <code>opid</code>, puis copiera la valeur du champ <code>@timestamp</code> dans un nouveau champ nommé <code>started</code>.</p><p>Les documents enrichis sont ensuite envoyés à la source de sortie appropriée, en l'occurrence Elasticsearch à l'aide du <a href="https://www.elastic.co/fr/docs/reference/logstash/plugins/plugins-outputs-elasticsearch"><code>elasticsearch</code></a><a href="https://www.elastic.co/fr/docs/reference/logstash/plugins/plugins-outputs-elasticsearch"> plugin de</a> sortie:</p>output {
    elasticsearch {
        hosts =&gt; "localhost"
        data_stream =&gt; "true"
    }
}<p>Si vous utilisez déjà Logstash, cette option peut être utile pour consolider votre logique d'enrichissement en un seul endroit et la traiter au fur et à mesure de l'arrivée de nouveaux événements. Cependant, si vous ne l'êtes pas, cela ajoute de la complexité à votre solution, et un autre composant que vous devez gérer et entretenir.</p><h2>ES|QL ENRICH</h2><p>L'introduction d'<a href="https://www.elastic.co/fr/docs/explore-analyze/query-filter/languages/esql">ES|QL</a>, qui a été généralisée dans la version 8.14, est un langage de requête en ligne pris en charge par Elasticsearch qui permet le filtrage, la transformation et l'analyse des données. La commande de traitement ENRICH permet d'ajouter des données à partir d'indices existants à l'aide d'une politique d'enrichissement.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbeb8992bde773461/6a17f6b663baff00c9741dd4/03aadddc08afffff3f6526c9c052999c97fa09dd-1600x989.png" alt="enrichissement esql" /><p>En reprenant la même politique <code>my_enrich_policy</code> que dans l'exemple original du processeur d'enrichissement, l'exemple ES|QL ressemblerait à ce qui suit :</p><p>Il est également possible de remplacer les champs de correspondance et d'enrichissement qui, dans notre exemple, sont respectivement <code>field_in_first_index</code> et <code>field_to_enrich</code>:</p><p>Bien que la limitation évidente soit que vous devez d'abord spécifier une politique d'enrichissement, ES|QL offre la flexibilité de modifier les champs selon les besoins.</p><h2>ES|QL LOOKUP JOIN</h2><p>Elasticsearch 8.18 introduit une nouvelle façon de joindre des index dans Elasticsearch, à savoir la commande <code>LOOKUP JOIN</code>. Cette commande fonctionne comme une jointure gauche-externe de type SQL en utilisant le nouveau <a href="https://www.elastic.co/fr/docs/reference/elasticsearch/index-settings/index-modules#index-mode-setting">mode d'indexation du</a> côté droit de la jointure.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt783ffb3f9802f92d/6a17f6b8e9ea870608a9c788/1d73495979c4d6bb675c4c966ea86d9a72dc1c48-510x605.png" alt="ES|QL LOOKUP JOIN" /><p>Si l'on reprend l'exemple précédent, la nouvelle requête est la suivante, où <code>match_field</code> doit être présent à la fois dans <code>first_index</code> et <code>second_index</code>:</p><p>L'avantage de LOOKUP JOIN par rapport aux autres approches est qu'il ne nécessite pas de politique <code>enrich</code>, et donc le traitement supplémentaire associé à la mise en place de la politique. Elle est utile lorsque l'on travaille avec des données d'enrichissement qui changent fréquemment, contrairement aux autres approches abordées dans cet article.</p><h2>Conclusion</h2><p>En conclusion, bien qu'Elasticsearch ne prenne pas en charge les opérations de jointure traditionnelles, il offre diverses fonctionnalités qui peuvent être utilisées pour obtenir des résultats similaires. Plus précisément, nous avons vu comment réaliser des opérations de jointure à l'aide de :</p><ol><li><p>La requête <code>terms</code></p></li><li><p>Le processeur <code>enrich</code> dans les pipelines d'acquisition</p></li><li><p>Logstash <code>elasticsearch</code> filter plugin</p></li><li><p>ES|QL <code>ENRICH</code></p></li><li><p>ES|QL <code>LOOKUP JOIN</code></p></li></ol><p>Il est important de noter que ces méthodes ont leurs limites et doivent être utilisées judicieusement en fonction des besoins spécifiques et de la nature des données.</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[Les bases]]></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[Comprendre la notation Elasticsearch et l'API Explain]]></title>
    <description><![CDATA[Découvrez les mécanismes de notation d’Elasticsearch et la fonction pratique de notation pour réaliser un audit de la pertinence de la recherche et améliorer le classement des documents grâce à l’API Explain.]]></description>
    <content:encoded><![CDATA[<p>Elasticsearch est un moteur de recherche puissant qui fournit des résultats de recherche rapides et pertinents en calculant un score pour chaque document dans l'index. Ce score est un facteur crucial pour déterminer l'ordre des résultats de la recherche. Dans cet article, nous allons nous plonger dans le mécanisme de notation d'Elasticsearch et explorer l'API Explain, qui aide à comprendre le processus de notation.</p><h2>Mécanismes de notation dans Elasticsearch</h2><p>Elasticsearch utilise par défaut un modèle de notation appelé Practical Scoring Function (BM25). Ce modèle est basé sur la théorie probabiliste de la recherche d'informations et prend en compte des facteurs tels que la fréquence des termes, la fréquence inverse des documents et la normalisation de la longueur des champs. Examinons brièvement ces facteurs :</p><ol><li><p><strong>Fréquence des termes (TF) :</strong> Elle représente le nombre de fois qu'un terme apparaît dans un document. Une fréquence de terme plus élevée indique une relation plus forte entre le terme et le document.</p></li><li><p><strong>Fréquence inverse des documents (IDF) :</strong> Ce facteur mesure l'importance d'un terme dans l'ensemble de la collection de documents. Un terme qui apparaît dans de nombreux documents est considéré comme moins important, tandis qu'un terme qui apparaît dans moins de documents est considéré comme plus important.</p></li><li><p><strong>Normalisation de la longueur du champ</strong>: Ce facteur tient compte de la longueur du champ dans lequel le terme apparaît. Les champs plus courts ont plus de poids, car le terme est considéré comme plus significatif dans un champ plus court.</p></li></ol><h2>Utiliser l'API Expliciter</h2><p>L'API Explain d'Elasticsearch est un outil précieux pour comprendre le processus de notation. Il fournit une explication détaillée de la manière dont la note d'un document spécifique a été calculée. Pour utiliser l'API Expliciter, vous devez envoyer une requête GET au point de terminaison suivant :</p>GET /&lt;index&gt;/_explain/&lt;document_id&gt;<p>Dans le corps de la demande, vous devez indiquer la requête pour laquelle vous voulez comprendre la notation. En voici un exemple :</p>{
  "query": {
    "match": {
      "title": "elasticsearch"
    }
  }
}<p>La réponse de l'API Expliciter comprendra une ventilation détaillée du processus de notation, y compris les facteurs individuels (TF, IDF et normalisation de la longueur de champ) et leurs contributions à la note finale. Voici un exemple de réponse :</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>Dans cet exemple, la réponse montre que le score de 1,2 est un produit de la valeur IDF (2,2) et de la valeur tfNorm (0,5). L'explication détaillée permet de comprendre les facteurs contribuant à la note et peut être utile pour affiner la pertinence de la recherche.</p><h2>Conclusion</h2><p>La notation Elasticsearch est un aspect essentiel de la fourniture de résultats de recherche pertinents. En comprenant les mécanismes de notation et en utilisant l'API Explain, vous pouvez obtenir des informations sur les facteurs affectant les résultats de recherche et optimiser vos requêtes de recherche pour une meilleure pertinence et de meilleures performances.</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[Les bases]]></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[Recherche Elasticsearch par deux champs]]></title>
    <description><![CDATA[Explorez les techniques de recherche par deux champs, y compris les requêtes multi-match, les requêtes booléennes et le renforcement de champ au moment de la requête.]]></description>
    <content:encoded><![CDATA[<p>La recherche sur plusieurs champs dans Elasticsearch est une exigence courante dans de nombreuses applications. Dans cet article, nous allons explorer des techniques avancées permettant d'effectuer des recherches sur deux champs, notamment les requêtes à correspondances multiples, les requêtes bool et l'augmentation du nombre de champs au moment de la requête. Ces techniques vous aideront à créer des résultats de recherche plus précis et plus pertinents pour vos utilisateurs.</p><h2>Techniques avancées pour effectuer des recherches sur deux champs</h2><h3>1. Requête multiple</h3><p>Une requête multiple vous permet de rechercher une seule chaîne de caractères dans plusieurs champs. Ceci est utile lorsque vous souhaitez trouver des documents qui contiennent la chaîne de requête donnée dans l'un ou l'autre des deux champs. Voici un exemple de requête multi-correspondance recherchant le terme "exemple" dans les champs "titre" ou "description" :</p>{
  "query": {
    "multi_match": {
      "query": "example",
      "fields": ["title", "description"]
    }
  }
}<h3>2. Requête Bool</h3><p>Une requête bool vous permet de combiner plusieurs requêtes en utilisant la logique booléenne. Vous pouvez utiliser la clause "devrait" pour rechercher les documents qui correspondent à la requête dans l'un ou l'autre des deux champs. Voici un exemple de requête bool recherchant le terme "exemple" dans les champs "titre" et "description" :</p>{
  "query": {
    "bool": {
      "should": [
        {"match": {"title": "example"}},
        {"match": {"description": "example"}}
      ]
    }
  }
}<h3>3. Renforcement des champs au moment de la requête</h3><p>Il peut arriver que vous souhaitiez accorder plus d'importance à un champ qu'à un autre lors de la recherche. Vous pouvez y parvenir en appliquant un facteur d'amplification au champ au moment de la requête. Une valeur de boost plus élevée donne plus de poids au champ, ce qui le rend plus susceptible d'influencer le résultat final de la recherche. Voici un exemple de requête à correspondances multiples avec un facteur d'amplification appliqué au champ "titre" :</p>{
  "query": {
    "multi_match": {
      "query": "example",
      "fields": ["title^3", "description"]
    }
  }
}<p>Dans cet exemple, le champ "titre" a un facteur d'amplification de 3, ce qui signifie qu'il est trois fois plus important que le champ "description" pour déterminer le score de recherche.</p><h3>4. Combinaison de requêtes avec différents facteurs d'amplification</h3><p>Vous pouvez également combiner plusieurs requêtes avec différents facteurs d'augmentation à l'aide d'une requête bool. Cela vous permet d'affiner l'importance de chaque champ dans les résultats de la recherche. Voici un exemple de requête bool avec différents facteurs de boost appliqués aux champs "titre" et "description" :</p>{
  "query": {
    "bool": {
      "should": [
        {"match": {"title": {"query": "example", "boost": 3}}},
        {"match": {"description": {"query": "example", "boost": 1}}}
      ]
    }
  }
}<p>Dans cet exemple, le champ "titre" a un facteur d'amplification de 3, tandis que le champ "description" a un facteur d'amplification de 1.</p><h2>Conclusion</h2><p>La recherche par deux champs dans Elasticsearch peut être réalisée à l'aide de techniques avancées telles que les requêtes à correspondances multiples, les requêtes bool et l'augmentation du nombre de champs au moment de la requête. En combinant ces techniques, vous pouvez créer des résultats de recherche plus précis et plus pertinents pour vos utilisateurs. Expérimentez différentes combinaisons de requêtes et de facteurs de stimulation pour trouver la configuration de recherche optimale pour votre cas d'utilisation spécifique.</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[Les bases]]></category>
    <category><![CDATA[Query 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[Comment mettre en œuvre une meilleure quantification binaire (BBQ) dans votre cas d'utilisation ?]]></title>
    <description><![CDATA[Expliquez pourquoi vous devriez mettre en œuvre une meilleure quantification binaire (BBQ) dans votre cas d'utilisation et comment le faire.]]></description>
    <content:encoded><![CDATA[<p>La recherche vectorielle constitue la base de la mise en œuvre d'une recherche sémantique pour le texte ou d'une recherche de similarité pour les images, les vidéos ou les fichiers audio. Dans le cas de la recherche vectorielle, les vecteurs sont des représentations mathématiques de données qui peuvent être énormes et parfois lentes. La meilleure quantification binaire (ci-après dénommée BBQ) est une méthode de compression pour les vecteurs. Il vous permet de trouver les bonnes correspondances tout en réduisant les vecteurs pour les rendre plus rapides à rechercher et à traiter. Cet article traite de BBQ et de rescore_vector, un champ disponible uniquement pour les indices quantifiés et qui permet de rescorer automatiquement les vecteurs.</p><p>Toutes les requêtes complètes et les résultats mentionnés dans cet article peuvent être trouvés dans notre <a href="https://github.com/elastic/elasticsearch-labs/tree/main/supporting-blog-content/how-and-why-bbq">dépôt de code Elasticsearch Labs</a>.</p><h2>Pourquoi mettre en œuvre une meilleure quantification binaire (BBQ) dans votre cas d'utilisation ?</h2>Remarque : pour une compréhension approfondie du fonctionnement mathématique du BBQ, veuillez consulter la <a href="https://www.elastic.co/fr/search-labs/blog/bbq-implementation-into-use-case#further-learning">section "Apprentissage complémentaire"</a> ci-dessous. Dans le cadre de ce blog, l'accent est mis sur la mise en œuvre.<p>Bien que les mathématiques soient intrigantes, elles sont essentielles si vous voulez comprendre pourquoi vos recherches vectorielles restent précises. En fin de compte, il s'agit d'une question de compression, car il s'avère qu'avec les algorithmes actuels de recherche vectorielle, vous êtes limité par la vitesse de lecture des données. Par conséquent, si vous pouvez placer toutes ces données dans la mémoire, vous bénéficiez d'un gain de vitesse significatif par rapport à la lecture à partir du stockage<a href="https://sre.google/static/pdf/rule-of-thumb-latency-numbers-letter.pdf">(la mémoire est environ 200 fois plus rapide que les disques SSD</a>).</p><p>Il y a quelques points à garder à l'esprit :</p><ul><li><p>Les indices basés sur les graphes, tels que <a href="https://arxiv.org/pdf/1603.09320">HNSW</a> (Hierarchical Navigable Small World), sont les plus rapides pour la recherche vectorielle.</p><ul><li><p>HNSW : un algorithme de recherche approximative du plus proche voisin qui construit une structure de graphe multicouche pour permettre des recherches de similarité efficaces en haute dimension.</p></li></ul></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt760bd95c206bfa8f/6a17e2ad505ac393f7ad8a95/590f3b3c72a76023a38a0436cd9ff90a9f80e936-1964x1262.png" alt="HNSW : un algorithme de recherche approximative du plus proche voisin qui construit une structure de graphe multicouche pour permettre des recherches de similarité efficaces en haute dimension." /><ul><li><p>La vitesse de HNSW est fondamentalement limitée par la vitesse de lecture des données à partir de la mémoire ou, dans le pire des cas, à partir du stockage.</p><ul><li><p>L'idéal est de pouvoir charger tous les vecteurs stockés dans la mémoire.</p></li></ul></li><li><p>Les modèles d'intégration produisent généralement des vecteurs avec une précision float32, soit 4 octets par nombre à virgule flottante.</p></li><li><p>Enfin, selon le nombre de vecteurs et/ou de dimensions que vous avez, vous pouvez très rapidement manquer de mémoire pour conserver tous vos vecteurs.</p></li></ul><p>Si l'on prend cela pour acquis, on constate qu'un problème se pose rapidement dès que l'on commence à ingérer des millions, voire des milliards de vecteurs, chacun ayant potentiellement des centaines, voire des milliers de dimensions. La section intitulée "<a href="https://www.elastic.co/fr/search-labs/blog/bbq-implementation-into-use-case#approximate-numbers-on-the-compression-ratios">Chiffres approximatifs sur les taux de compression</a>" fournit quelques chiffres approximatifs.</p><h2>De quoi avez-vous besoin pour commencer ?</h2><p>Pour commencer, vous aurez besoin des éléments suivants :</p><ul><li><p>Si vous utilisez Elastic Cloud ou on-prem, vous aurez besoin d'une version d'Elasticsearch supérieure à 8.18. Alors que BBQ a été introduit dans la version 8.16, dans cet article, vous utiliserez <code>vector_rescore</code>, qui a été introduit dans la version 8.18.</p></li><li><p>En outre, vous devrez également vous assurer qu'il existe un <a href="https://www.elastic.co/fr/guide/en/elasticsearch/reference/8.18/ml-settings.html">nœud d'apprentissage automatique (ML)</a> dans votre cluster. (Remarque : un nœud ML doté d'un minimum de 4 Go est nécessaire pour charger le modèle, mais vous aurez probablement besoin de nœuds beaucoup plus grands pour des charges de travail de production complètes).</p></li><li><p>Si vous utilisez Serverless, vous devrez sélectionner une instance optimisée pour les vecteurs.</p></li><li><p>Vous aurez également besoin d'une connaissance de base des bases de données vectorielles. Si vous n'êtes pas encore familiarisé avec les concepts de recherche vectorielle dans Elastic, vous pouvez consulter les ressources suivantes :</p><ul><li><p><a href="https://www.elastic.co/fr/search-labs/blog/elastic-vector-database-practical-example">Naviguer dans une base de données vectorielle élastique</a></p></li><li><p><a href="https://www.elastic.co/fr/blog/retrieval-augmented-generation-explained">Les grandes idées derrière la génération augmentée de recherche</a></p></li></ul></li></ul><h2>Meilleure implémentation de la quantification binaire (BBQ)</h2><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt18df00df95ff2ca7/6a17e2af414c6411989450df/4d388078495566f0527e931e0c2e38facdce83c6-1503x748.png" alt="Mise en œuvre d'Elasticsearch bbq." /><p>Pour que ce blog reste simple, vous utiliserez les fonctions intégrées lorsqu'elles sont disponibles. Dans ce cas, vous disposez du modèle d'intégration vectorielle <a href="https://www.elastic.co/fr/guide/en/machine-learning/8.17/ml-nlp-e5.html"><code>.multilingual-e5-small</code></a> qui s'exécutera directement dans Elasticsearch sur un nœud d'apprentissage automatique. Notez que vous pouvez remplacer le modèle <code>text_embedding</code> par l'intégrateur de votre choix<a href="https://www.elastic.co/fr/guide/en/elasticsearch/reference/8.18/infer-service-openai.html">(OpenAI</a>, <a href="https://www.elastic.co/fr/guide/en/elasticsearch/reference/8.18/infer-service-google-ai-studio.html">Google AI Studio</a>, <a href="https://www.elastic.co/fr/guide/en/elasticsearch/reference/8.18/infer-service-cohere.html">Cohere</a> et bien d'autres). Si le modèle que vous préférez n'est pas encore intégré, vous pouvez également <a href="https://www.elastic.co/fr/guide/en/elasticsearch/reference/8.18/bring-your-own-vectors.html">apporter vos propres encastrements vectoriels denses</a>).</p><p>Tout d'abord, vous devrez créer un point final d'inférence pour générer des vecteurs pour un morceau de texte donné. Vous exécuterez toutes ces commandes à partir de la console Kibana <a href="https://www.elastic.co/fr/guide/en/kibana/8.18/console-kibana.html">Dev</a> Tools. Cette commande permet de télécharger le site <code>.multilingual-e5-small</code>. S'il n'existe pas encore, il configurera votre point d'accès ; cette opération peut prendre une minute. Vous pouvez voir le résultat attendu dans le fichier <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">01-create-an-inference-endpoint-output.json</a> dans le dossier Outputs. </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>Une fois qu'il est revenu, votre modèle est configuré et vous pouvez tester que le modèle fonctionne comme prévu à l'aide de la commande suivante. Vous pouvez voir le résultat attendu dans le fichier <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/02-embed-text-output.json">02-embed-text-output.json</a> dans le dossier Outputs.</p>POST _inference/text_embedding/my_e5_model
{
  "input": "my awesome piece of text"
}<p>Si vous rencontrez des problèmes liés au fait que votre modèle formé n'est affecté à aucun nœud, il se peut que vous deviez démarrer votre modèle manuellement.</p>POST _ml/trained_models/.multilingual-e5-small/deployment/_start<p>Créons maintenant un nouveau mappage avec deux propriétés, un champ de texte standard (<code>my_field</code>) et un champ vectoriel dense (<code>my_vector</code>) avec 384 dimensions pour correspondre à la sortie du modèle d'intégration. Vous pouvez également passer outre l'adresse <code>index_options.type to bbq_hnsw</code>. Vous pouvez voir le résultat attendu dans le fichier <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">03-create-byte-qauntized-index-output.json</a> dans le dossier Outputs.</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>Pour s'assurer qu'Elasticsearch génère vos vecteurs, vous pouvez utiliser un <a href="https://www.elastic.co/fr/guide/en/elasticsearch/reference/8.18/ingest.html">pipeline d'ingestion</a>. Ce pipeline nécessite trois éléments : le point final (<code>model_id</code>), le site <code>input_field</code> pour lequel vous souhaitez créer des vecteurs et le site <code>output_field</code> dans lequel vous souhaitez stocker ces vecteurs. La première commande ci-dessous crée un pipeline d'ingestion d'inférence, qui utilise le <a href="https://www.elastic.co/fr/guide/en/elasticsearch/reference/current/inference-apis.html">service d'inférence </a>sous le capot, et la seconde teste le bon fonctionnement du pipeline. Vous pouvez voir le résultat attendu dans le fichier <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">04-create-and-simulate-ingest-pipeline-output.json</a> dans le dossier Outputs. </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>Vous êtes maintenant prêt à ajouter des documents à l'aide des deux premières commandes ci-dessous et à tester le fonctionnement de vos recherches à l'aide de la troisième commande. Vous pouvez vérifier le résultat attendu dans le fichier <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/05-bbq-index-output.json">05-bbq-index-output.json</a> dans le dossier Outputs. </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>Comme nous l'avons recommandé dans <a href="https://www.elastic.co/fr/search-labs/blog/better-binary-quantization-lucene-elasticsearch#lucene-benchmarking">cet article</a>, le recalage et le suréchantillonnage sont conseillés lorsque vous passez à des quantités de données non triviales, car ils permettent de maintenir une précision de rappel élevée tout en bénéficiant des avantages de la compression. À partir de la version 8.18 d'Elasticsearch, vous pouvez le faire de cette façon en utilisant <a href="https://www.elastic.co/fr/guide/en/elasticsearch/reference/8.18/knn-search.html#dense-vector-knn-search-rescoring">rescore_vector.</a> Le résultat attendu se trouve dans le fichier <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">06-bbq-search-8-18-output.json</a> dans le dossier 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>Comment ces résultats se comparent-ils à ceux que vous obtiendriez avec des données brutes ? Si vous refaites tout ce qui précède mais avec <code>index_options.type: hnsw</code>, vous verrez que les scores sont très comparables. Vous pouvez voir le résultat attendu dans le fichier <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/07-raw-vector-output.json">07-raw-vector-output.json</a> dans le dossier Outputs.</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>Chiffres approximatifs sur les taux de compression</h2><p>Les exigences en matière de stockage et de mémoire peuvent rapidement devenir un défi important lorsque l'on travaille avec la recherche vectorielle. La décomposition suivante illustre comment les différentes techniques de quantification réduisent considérablement l'empreinte mémoire des données vectorielles.</p><p>Vecteurs (V)</p><p>Dimensions (D)</p><p>brut (V x D x 4)</p><p>int8 (V x (D x 1 + 4))</p><p>int4 (V x (D x 0,5 + 4))</p><p>bbq (V x (D x 0,125 + 4))</p><p>10,000,000</p><p>384</p><p>14.31GB</p><p>3.61GB</p><p>1.83GB</p><p>0.58GB</p><p>50,000,000</p><p>384</p><p>71.53GB</p><p>18.07GB</p><p>9.13GB</p><p>2.89GB</p><p>100,000,000</p><p>384</p><p>143.05GB</p><p>36.14GB</p><p>18.25GB</p><p>5.77GB</p><h2>Conclusion</h2><p>BBQ est une optimisation que vous pouvez appliquer à vos données vectorielles pour les compresser sans sacrifier la précision. Il convertit les vecteurs en bits, ce qui vous permet d'effectuer des recherches efficaces dans les données et de faire évoluer vos flux de travail d'IA pour accélérer les recherches et optimiser le stockage des données.</p><h2>Poursuite de l'apprentissage</h2><p>Si vous souhaitez en savoir plus sur le barbecue, n'hésitez pas à consulter les ressources suivantes :</p><ul><li><p><a href="https://www.elastic.co/fr/search-labs/blog/better-binary-quantization-lucene-elasticsearch">Quantification binaire (BBQ) dans Lucene et Elasticsearch</a></p></li><li><p><a href="https://www.elastic.co/fr/search-labs/blog/bit-vectors-elasticsearch-bbq-vs-pq">Meilleure quantification binaire (BBQ) vs quantification par produit</a></p></li><li><p><a href="https://www.elastic.co/fr/search-labs/blog/optimized-scalar-quantization-elasticsearch">Quantification scalaire optimisée : Une quantification binaire encore meilleure</a></p></li><li><p><a href="https://www.youtube.com/watch?v=04NzMt2Nigc">Meilleure quantification binaire (BBQ) : De l'octet au BBQ, le secret d'une meilleure recherche vectorielle par 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 vectorielle]]></category>
    <category><![CDATA[Les bases]]></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[Utilisation de la taille du tas d'Elasticsearch et collecte des déchets de la JVM]]></title>
    <description><![CDATA[Exploration de l'utilisation de la taille du tas d'Elasticsearch et de la collecte des déchets de la JVM, y compris les meilleures pratiques et la manière de résoudre les problèmes lorsque l'utilisation de la mémoire du tas est trop élevée ou lorsque les performances de la JVM ne sont pas optimales.]]></description>
    <content:encoded><![CDATA[<p>La taille du tas est la quantité de RAM allouée à la machine virtuelle Java d'un nœud Elasticsearch.</p><p>Depuis la version 7.11, Elasticsearch définit par défaut automatiquement la taille du tas de la JVM en fonction des rôles et de la mémoire totale d'un nœud. L'utilisation du dimensionnement par défaut est recommandée pour la plupart des environnements de production. Toutefois, si vous souhaitez définir manuellement la taille du tas de votre JVM, vous devez en règle générale définir -Xms et -Xmx sur la MÊME valeur, soit 50% de votre RAM totale disponible, avec un maximum (approximatif) de 31 Go.</p><p>Une taille de tas plus importante permet à votre nœud de disposer de plus de mémoire pour les opérations d'indexation et de recherche. Cependant, votre nœud a également besoin de mémoire pour la mise en cache, de sorte que l'utilisation de 50% maintient un équilibre sain entre les deux. Pour cette même raison, en production, vous devez éviter d'utiliser d'autres processus gourmands en mémoire sur le même nœud qu'Elasticsearch.</p><p>En règle générale, l'utilisation du tas suit un schéma en dents de scie, oscillant entre 30 et 70% du tas maximum utilisé. En effet, la JVM augmente régulièrement le pourcentage d'utilisation du tas jusqu'à ce que le processus de ramassage des ordures libère à nouveau de la mémoire. Une forte utilisation du tas se produit lorsque le processus de ramassage des ordures n'arrive pas à suivre. Un indicateur d'une utilisation élevée du tas est lorsque le ramasse-miettes est incapable de réduire l'utilisation du tas à environ 30%.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt03908d8eea824755/6a17dbe63e03d71e314f2b3e/0a17a67cc589a3c1fbf9e918eadc119df7bd7619-858x278.png" alt="" /><p>Dans l'image ci-dessus, vous pouvez voir une dent de scie normale du tas de la JVM.</p><p>Vous verrez également qu'il existe deux types de ramassage d'ordures, le jeune et l'ancien GC.</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>Dans une JVM en bonne santé, le ramassage des ordures devrait idéalement répondre aux conditions suivantes :</p><ul><li><p>Le jeune GC est traité rapidement (dans les 50 ms).</p></li><li><p>Le jeune GC n'est pas exécuté fréquemment (environ 10 secondes).</p></li><li><p>L'ancienne CG est traitée rapidement (en moins d'une seconde).</p></li><li><p>L'ancienne CG n'est pas exécutée fréquemment (une fois toutes les 10 minutes ou plus).</p></li></ul><h3><strong>Comment résoudre le problème d'une utilisation trop importante de la mémoire du tas ou d'une performance non optimale de la JVM ?</strong></h3><p>Plusieurs raisons peuvent expliquer l'augmentation de l'utilisation de la mémoire du tas :</p><h4><strong>La surexploitation</strong></h4><p>Veuillez consulter le document sur le surdimensionnement <a href="https://www.elastic.co/docs/deploy-manage/production-guidance/optimize-performance/size-shards#sizing-shard-guidelines">ici.</a></p><h4><strong>Grandes tailles d'agrégation</strong></h4><p>Afin d'éviter des agrégations trop importantes, limitez au maximum le nombre d'agrégats (taille) dans vos requêtes.</p>GET /_search
{
   "aggs" : {
       "products" : {
           "terms" : {
               "field" : "product",
               "size" : 5
                          }
       }
   }
}<p>Vous pouvez utiliser la journalisation lente des requêtes (slow logs) et la mettre en œuvre sur un index spécifique en procédant comme suit.</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>Les requêtes qui prennent beaucoup de temps pour donner des résultats sont probablement celles qui consomment beaucoup de ressources.</p><h4><strong>Taille excessive de l'index en vrac</strong></h4><p>Si vous envoyez des requêtes volumineuses, cela peut être la cause d'une consommation élevée de la mémoire vive. Essayez de réduire la taille des demandes d'index en vrac.</p><h4><strong>Questions de cartographie</strong></h4><p>En particulier, si vous utilisez "fielddata : true", cela peut être un utilisateur majeur de la mémoire vive de votre JVM.</p><h4><strong>La taille du tas n'est pas correctement définie</strong></h4><p>La taille du tas peut être définie manuellement par :</p><p>Définition de la variable d'environnement :</p>ES_JAVA_OPTS="-Xms2g -Xmx2g"<p>Édition du fichier jvm.options dans le répertoire de configuration d'Elasticsearch :</p>-Xms2g
-Xmx2g<p>Le paramètre de la variable d'environnement est prioritaire sur le paramètre du fichier.</p><p>Il est nécessaire de redémarrer le nœud pour que le réglage soit pris en compte.</p><h4><strong>Le nouveau ratio de la JVM n'est pas correctement défini</strong></h4><p>Il n'est généralement PAS nécessaire de définir cette valeur, car Elasticsearch le fait par défaut. Ce paramètre définit le ratio de l'espace disponible pour les objets de "nouvelle génération" et d'"ancienne génération" dans la JVM.</p><p>Si vous constatez que les anciens GC deviennent très fréquents, vous pouvez essayer de définir spécifiquement cette valeur dans le fichier jvm.options de votre répertoire de configuration Elasticsearch.</p>-XX:NewRatio=3<h3><strong>Quelles sont les meilleures pratiques pour gérer l'utilisation de la taille du tas et la collecte des déchets de la JVM dans un grand cluster Elasticsearch ?</strong></h3><p>Les meilleures pratiques pour gérer l'utilisation de la taille du tas et le ramassage des ordures de la JVM dans un grand cluster Elasticsearch consistent à s'assurer que la taille du tas est fixée à un maximum de 50% de la RAM disponible et que les paramètres du ramassage des ordures de la JVM sont optimisés pour le cas d'utilisation spécifique. Il est important de surveiller la taille du tas et les mesures du ramassage des ordures pour s'assurer que le cluster fonctionne de manière optimale. Plus précisément, il est important de surveiller la taille du tas de la JVM, le temps de ramassage des ordures et les pauses de ramassage des ordures. En outre, il est important de surveiller le nombre de cycles de ramassage des ordures et le temps passé à les effectuer. En surveillant ces mesures, il est possible d'identifier tout problème potentiel lié à la taille du tas ou aux paramètres du ramassage des ordures et de prendre des mesures correctives si nécessaire.</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[Les bases]]></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[Comment augmenter le nombre de shards primaires dans Elasticsearch ?]]></title>
    <description><![CDATA[Apprenez à augmenter le nombre de partitions primaires dans Elasticsearch à l’aide des API split et reindex pour un dimensionnement optimal des partitions.]]></description>
    <content:encoded><![CDATA[<p>Il n'est pas possible d'augmenter le nombre de shards primaires d'un index existant, ce qui signifie qu'un index doit être recréé si vous souhaitez augmenter le nombre de shards primaires. Deux méthodes sont généralement utilisées dans ces situations : l'API _reindex et l'API _split.</p><p>L'API _split est souvent plus rapide que l'API _reindex. L<strong>'indexation</strong> <strong>doit être arrêtée</strong> avant les deux opérations, sinon les comptes des documents source_index et cible_index seront différents.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt46dd6abe0e6fe1eb/6a17e368148009d6a7b486d3/aa0ae010c2f5691ca00440fb453ed6b47bacd24f-1200x628.png" alt="Augmenter le nombre de partitions dans Elasticsearch en recréant un index" /><h2>Méthode 1 - utilisation de l'API fractionnée</h2><p>L'API de fractionnement est utilisée pour créer un nouvel index avec le nombre souhaité d'unités primaires en copiant les paramètres et en mappant un index existant. Le nombre désiré de fragments primaires peut être défini lors de la création. Les paramètres suivants doivent être vérifiés avant de mettre en œuvre l'API fractionnée :</p><ol><li><p>L'index source doit être en lecture seule. Cela signifie que le processus d'indexation doit être arrêté.</p></li><li><p>Le nombre de groupes primaires dans l'index cible doit être un multiple du nombre de groupes primaires dans l'index source. Par exemple, si l'index source dispose de 5 groupes primaires, les groupes primaires de l'index cible peuvent être définis comme suit : 10, 15, 20, et ainsi de suite.</p></li></ol><p>Remarque : si seul le numéro du fonds primaire doit être modifié, il est préférable d'utiliser l'API de fractionnement, qui est beaucoup plus rapide que l'API de réindexation.</p><h3>Mise en œuvre de l'API fractionnée</h3><p>Créer un index de test :</p>POST test_split_source/_doc
{
  "test": "test"
}<p>L'index source doit être en lecture seule pour pouvoir être scindé :</p>PUT test_split_source/_settings
{
  "index.blocks.write": true
}<p>Les paramètres et les correspondances seront copiés automatiquement à partir de l'index source :</p>POST /test_split_source/_split/test_split_target
{
  "settings": {
    "index.number_of_shards": 3
  }
}<p>Vous pouvez vérifier l'état d'avancement avec :</p>GET _cat/recovery/test_split_target?v&amp;h=index,shard,time,stage,files_percent,files_total<p>Étant donné que les paramètres et les mappages sont copiés à partir des index source, l'index cible est en lecture seule. Activons l'opération d'écriture pour l'index cible :</p>PUT test_split_target/_settings
{
    "index.blocks.write": null
}<p>Vérifier les index source et cible docs.count avant de supprimer l'index original :</p>GET _cat/indices/test_split*?v&amp;h=index,pri,rep,docs.count<p>Le nom de l'index et le nom de l'alias ne peuvent pas être identiques. Vous devez supprimer l'index source et ajouter le nom de l'index source comme alias à l'index cible :</p>DELETE test_split_source
PUT /test_split_target/_alias/test_split_source<p>Après avoir ajouté l'alias <strong>test_split_source</strong> à l'index <strong>test_split_target</strong>, vous devez le tester avec :</p>GET test_split_source
POST test_split_source/_doc
{
  "test": "test"
}<h2>Méthode 2 - utilisation de l'API de réindexation</h2><p>En créant un nouvel index à l'aide de l'API Reindex, il est possible d'indiquer n'importe quel nombre de comptes de tessons primaires. Après la création d'un nouvel index avec le nombre prévu de groupes primaires, toutes les données de l'index source peuvent être réindexées sur ce nouvel index.</p><p>Outre les fonctionnalités de l'API fractionnée, les données peuvent être manipulées à l'aide de la ligne de conduite ingest_pipeline dans l'API de réindexation. Avec le pipeline d'ingestion, seuls les champs spécifiés qui correspondent au filtre seront indexés dans l'index cible à l'aide de la requête. Le contenu des données peut être modifié à l'aide d'un script simple, et plusieurs index peuvent être fusionnés en un seul.</p><h3>Mise en œuvre de l'API de réindexation</h3><p>Créer un test de réindexation :</p>POST test_reindex_source/_doc
{
    "test": "test"
}<p>Copier les paramètres et les mappages de l'index source :</p>GET test_reindex_source<p>Créez un index cible avec des paramètres, des mappings et le nombre de tiroirs souhaité :</p>PUT test_reindex_target
{
  "mappings" : {},
  "settings": {
    "number_of_shards": 10,
    "number_of_replicas": 0,
    "refresh_interval": -1
  }
}<p>*Remarque : les paramètres number_of_replicas : 0 et refresh_interval : -1 augmentera la vitesse de réindexation.</p><p>Lancer le processus de réindexation. Les paramètres requests_per_second=-1 et slices=auto permettent d'ajuster la vitesse de réindexation.</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>Vous verrez l'identifiant de la tâche lorsque vous exécuterez l'API de réindexation. Copiez-le et vérifiez avec l'API _tasks :</p>GET _tasks/&lt;task_id&gt;<p>Mettre à jour les paramètres une fois la réindexation terminée :</p>PUT test_reindex_target/_settings
{
  "number_of_replicas": 1,
  "refresh_interval": "1s"
}<p>Vérifiez les index source et cible docs.count avant de supprimer l'index original, ils doivent être identiques :</p>GET _cat/indices/test_reindex_*?v&amp;h=index,pri,rep,docs.count<p>Le nom de l'index et le nom de l'alias ne peuvent pas être identiques. Supprimer l'index source et ajouter le nom de l'index source comme alias à l'index cible :</p>DELETE test_reindex_source
PUT /test_reindex_target/_alias/test_reindex_source<p>Après avoir ajouté l'alias test_split_source à l'index test_split_target, testez-le en utilisant :</p>GET test_reindex_source<h2>Résumé</h2><p>Si vous souhaitez augmenter le nombre de tessons primaires d'un index existant, vous devez recréer les paramètres et les correspondances avec un nouvel index. Il existe deux méthodes principales pour ce faire : l'API de réindexation et l'API de scission. L'indexation active doit être arrêtée avant d'utiliser l'une ou l'autre méthode.</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[Les bases]]></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[Comment migrer des données entre différentes versions d'Elasticsearch & entre clusters]]></title>
    <description><![CDATA[Exploration des méthodes de transfert de données entre les versions et les clusters d'Elasticsearch.]]></description>
    <content:encoded><![CDATA[<p>Lorsque vous souhaitez mettre à niveau un cluster Elasticsearch, il est parfois plus facile de créer un nouveau cluster séparé et de transférer les données de l'ancien cluster vers le nouveau. Les utilisateurs ont ainsi l'avantage de pouvoir tester toutes leurs données et configurations sur le nouveau cluster avec toutes leurs applications sans risque d'interruption ou de perte de données.</p><p>Les inconvénients de cette approche sont qu'elle nécessite une certaine duplication du matériel et qu'elle peut créer des difficultés lors du transfert et de la synchronisation de toutes les données.</p><p>Il peut également être nécessaire d'effectuer une procédure similaire si vous devez migrer des applications d'un centre de données à un autre.</p><p>Dans cet article, nous allons discuter et détailler trois façons de transférer des données entre les clusters Elasticsearch.</p><p><strong>Comment migrer des données entre clusters Elasticsearch ?</strong></p><p>Il existe trois façons de transférer des données entre les clusters Elasticsearch :</p><ol><li><p><a href="https://www.elastic.co/fr/search-labs/blog/elasticsearch-migrate-data-versions-clusters#1.-reindexing-data-from-a-remote-cluster">Réindexation à partir d'un cluster distant</a></p></li><li><p><a href="https://www.elastic.co/fr/search-labs/blog/elasticsearch-migrate-data-versions-clusters#2.-transferring-data-using-snapshots">Transfert de données à l'aide d'instantanés</a></p></li><li><p><a href="https://www.elastic.co/fr/search-labs/blog/elasticsearch-migrate-data-versions-clusters#3.-transferring-data-using-logstash">Transférer des données avec Logstash</a></p></li></ol><p>L'utilisation d'instantanés est généralement le moyen le plus rapide et le plus fiable de transférer des données. Toutefois, n'oubliez pas que vous ne pouvez restaurer un instantané que sur un cluster de version égale ou supérieure et jamais avec une différence de plus d'une version majeure. Cela signifie que vous pouvez restaurer un snapshot 6.x sur un cluster 7.x mais pas sur un cluster 8.x.</p><p>Si vous avez besoin d'augmenter de plus d'une version majeure, vous devrez réindexer ou utiliser Logstash.</p><p>Examinons maintenant en détail chacune des trois options de transfert de données entre clusters Elasticsearch.</p><h2>1. Réindexation des données d'un cluster distant</h2><p>Avant de commencer à réindexer, n'oubliez pas que vous devrez configurer les mappages appropriés pour tous les index sur le nouveau cluster. Pour ce faire, vous devez soit créer les index directement avec les mappings appropriés, soit utiliser des modèles d'index.</p><h3>Réindexation à distance - configuration requise</h3><p>Pour réindexer à distance, vous devez ajouter la configuration ci-dessous au fichier elasticseearch.yml pour le cluster qui reçoit les données, qui, dans les systèmes Linux, est généralement situé ici : /etc/elasticsearch/elasticsearch.yml. La configuration à ajouter est la suivante :</p>reindex.remote.whitelist: "192.168.1.11:9200"<p>Si vous utilisez SSL, vous devez ajouter le certificat CA à chaque nœud et inclure ce qui suit dans la commande pour chaque nœud dans elasticsearch.yml :</p>reindex.ssl.certificate_authorities: “/path/to/ca.pem”<p>Vous pouvez également ajouter la ligne ci-dessous à tous les nœuds Elasticsearch afin de désactiver la vérification SSL. Toutefois, cette approche est moins recommandée car elle n'est pas aussi sûre que l'option précédente :</p>reindex.remote.whitelist: "192.168.1.11:9200"
reindex.ssl.verification_mode: none
systemctl restart elasticsearch service <p>Vous devrez effectuer ces modifications sur chaque nœud et procéder à un redémarrage progressif. Pour plus d'informations sur la manière de procéder, veuillez consulter <a href="https://www.elastic.co/fr/guide/en/elasticsearch/reference/8.17/restart-cluster.html#restart-cluster-rolling">notre guide.</a></p><h3>Commande de réindexation</h3><p>Après avoir défini l'hôte distant dans le fichier elasticsearch.yml et ajouté les certificats SSL si nécessaire, vous pouvez commencer à réindexer les données avec la commande ci-dessous :</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>Il peut donc être utile de fixer des valeurs généreuses pour les délais d'attente plutôt que de se fier aux valeurs par défaut.</p><p>Examinons maintenant d'autres erreurs courantes que vous pouvez rencontrer lors d'une réindexation à distance.</p><h3>Erreurs courantes lors de la réindexation à distance</h3><h4>1. La réindexation ne figure pas sur la liste blanche</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 vous rencontrez cette erreur, cela signifie que vous n'avez pas défini l'adresse IP de l'hôte distant ou le nom du nœud DNS dans Elasticsearch comme décrit ci-dessus ou que vous avez oublié de redémarrer les services Elasticsearch.</p><p>Pour résoudre ce problème dans le cluster Elasticsearch, vous devez ajouter l'hôte distant à tous les nœuds Elasticsearch et redémarrer les services Elasticsearch.</p><h4>2. Exception relative au handshake 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>Cette erreur signifie que vous avez oublié d'ajouter le certificat reindex.ssl.certificate_authorities à elasticsearch.yml comme décrit ci-dessus. Pour l'ajouter :</p>#elasticsearch.yml
reindex.ssl.certificate_authorities: "/path/to/ca.pem"<h2>2. Transfert de données à l'aide d'instantanés</h2><p>N'oubliez pas, comme indiqué ci-dessus, que vous ne pouvez restaurer un instantané que sur un cluster de version égale ou supérieure et jamais avec une différence de plus d'une version majeure.</p><p>Si vous avez besoin d'augmenter de plus d'une version majeure, vous devrez réindexer ou utiliser Logstash.</p><p>Les étapes suivantes sont nécessaires pour transférer des données par le biais d'instantanés :</p><p>Étape 1. Ajouter le plugin de référentiel au premier cluster Elasticsearch - Afin de transférer des données entre clusters via des snapshots, vous devez vous assurer que le référentiel est accessible à la fois depuis le nouveau et l'ancien cluster. Les référentiels de stockage en nuage tels que AWS, Google et Azure sont généralement idéaux pour cela. Pour prendre des instantanés, veuillez consulter <a href="https://www.elastic.co/fr/guide/en/elasticsearch/reference/current/snapshot-restore.html">notre guide</a> et suivre les étapes qu'il décrit.</p><p>Étape 2. Redémarrer le service Elasticsearch (rolling restart).</p><p>Étape 3. Créez un référentiel pour le premier cluster Elasticsearch.</p><p>Étape 4 - Ajouter le plugin de référentiel au deuxième cluster Elasticsearch.</p><p>Étape 5- Ajouter un référentiel en lecture seule au deuxième cluster Elasticsearch - Vous devrez ajouter un référentiel en répétant les mêmes étapes que celles que vous avez suivies pour créer le premier cluster Elasticsearch.</p><p>Remarque importante : lorsque vous connectez le deuxième cluster Elasticsearch au même référentiel AWS S3, vous devez définir le référentiel comme un référentiel en lecture seule :</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>C'est important parce que vous voulez éviter le risque de mélanger les versions d'Elasticsearch dans le même dépôt d'instantanés.</p><p>Étape 6 - Restauration des données vers le deuxième cluster Elasticsearch - Après avoir suivi les étapes ci-dessus, vous pouvez restaurer les données et les transférer vers le nouveau cluster. Veuillez suivre les étapes décrites dans <a href="https://www.elastic.co/fr/guide/en/elasticsearch/reference/current/snapshot-restore.html">cet article</a> pour restaurer les données dans le nouveau cluster. </p><h2>3. Transfert de données à l'aide de Logstash</h2><p>Avant de commencer à transférer les données avec logstash, n'oubliez pas que vous devrez configurer les mappings appropriés pour tous les index sur le nouveau cluster. Pour ce faire, vous devrez soit créer les index directement, soit utiliser des modèles d'index.</p><p>Pour transférer des données entre deux clusters Elasticsearch, vous pouvez configurer un serveur Logstash temporaire et l'utiliser pour transférer vos données entre les deux clusters. Pour les petits clusters, une instance de 2 Go de mémoire vive devrait suffire. Pour les clusters plus importants, vous pouvez utiliser des CPU à quatre cœurs avec 8 Go de RAM.</p><p>Pour des conseils sur l'installation de Logstash, <a href="https://www.elastic.co/fr/guide/en/logstash/current/installing-logstash.html">voir ici.</a></p><h3>Configuration de Logstash pour le transfert de données d'un cluster à l'autre</h3><p>La configuration de base pour copier un index unique du cluster A vers le cluster B est la suivante :</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>Pour sécuriser elasticsearch, vous pouvez utiliser la configuration ci-dessous :</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>Métadonnées de l'index</h3><p>Les commandes ci-dessus écrivent dans un seul index nommé. Si vous souhaitez transférer plusieurs index et préserver les noms d'index, vous devez ajouter la ligne suivante à la sortie de Logstash :</p>index =&gt; "%{[@metadata][_index]}"<p>De même, si vous souhaitez conserver l'identifiant original du document, vous devrez ajouter :</p>document_id =&gt; "%{[@metadata][_id]}"<p>Gardez à l'esprit que la définition de l'ID du document ralentira considérablement le transfert des données, aussi ne conservez-vous l'ID d'origine que si vous en avez besoin.</p><h2>Synchronisation des mises à jour</h2><p>Toutes les méthodes décrites ci-dessus prennent un temps relativement long, et il se peut que des données aient été mises à jour dans le cluster d'origine en attendant la fin du processus.</p><p>Il existe plusieurs stratégies pour permettre la synchronisation des mises à jour qui ont pu avoir lieu pendant le processus de transfert des données, et vous devriez réfléchir à ces questions avant d'entamer ce processus. Vous devez notamment réfléchir aux points suivants :</p><ul><li><p>Quelle méthode utilisez-vous pour identifier les données qui ont été mises à jour/ajoutées depuis le début du processus de transfert de données (par exemple, un champ "last_update_time" dans les données) ?</p></li><li><p>Quelle méthode pouvez-vous utiliser pour transférer le dernier élément de données ?</p></li><li><p>Existe-t-il un risque de duplication des documents ? En général, c'est le cas, à moins que la méthode que vous utilisez ne fixe l'ID du document à une valeur connue lors de la réindexation).</p></li></ul><p>Les différentes méthodes permettant la synchronisation des mises à jour sont décrites ci-dessous.</p><h3>1. Utilisation des systèmes de file d'attente</h3><p>Certains systèmes d'ingestion/mise à jour utilisent des files d'attente qui vous permettent de "rejouer" les modifications de données reçues au cours des x derniers jours. Cela peut permettre de synchroniser les modifications effectuées. </p><h3>2. Réindexation à distance</h3><p>Répétez le processus de réindexation pour tous les éléments pour lesquels "last_update_time" &gt; a été effectué il y a x jours. Vous pouvez le faire en ajoutant un paramètre "query" à la requête de réindexation.</p><h3>3. Logstash</h3><p>Dans l'entrée Logstash, vous pouvez ajouter une requête pour filtrer tous les éléments pour lesquels "last_update_time" &gt; x jours ago. Toutefois, ce processus entraînera des doublons dans les données non chronologiques, à moins que vous n'ayez défini l'identifiant du document.</p><h3>4. Instantanés</h3><p>Il n'est pas possible de restaurer une partie seulement d'un index. Vous devez donc utiliser l'une des autres méthodes de transfert de données décrites ci-dessus (ou un script) pour mettre à jour toutes les modifications qui ont eu lieu depuis le processus de transfert de données.</p><p>Cependant, la restauration des instantanés est un processus beaucoup plus rapide que la réindexation/Logstash, il est donc possible de suspendre les mises à jour pendant une courte période de temps pendant que les instantanés sont transférés afin d'éviter le problème.</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[Les bases]]></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[Comment automatiser les synonymes et le téléchargement à l'aide de notre API Synonymes ?]]></title>
    <description><![CDATA[Découvrez comment les LLM peuvent être utilisés pour identifier et générer automatiquement des synonymes, permettant ainsi aux termes d'être chargés de manière programmatique dans l'API de synonymes d'Elasticsearch.]]></description>
    <content:encoded><![CDATA[<p>L'amélioration de la qualité des résultats de recherche est essentielle pour offrir une expérience efficace aux utilisateurs. L'un des moyens d'optimiser les recherches consiste à étendre automatiquement les termes recherchés au moyen de synonymes. Cela permet d'interpréter les requêtes de manière plus large, de couvrir les variations linguistiques et donc d'améliorer la concordance des résultats.</p><p>Ce blog explore la manière dont les grands modèles de langage (LLM) peuvent être utilisés pour identifier et générer automatiquement des synonymes, ce qui permet de charger ces termes de manière programmatique dans l'API de synonymes d'Elasticsearch.</p><h2>Quand utiliser des synonymes ?</h2><p>L'utilisation de synonymes peut être une solution plus rapide et plus rentable que la recherche vectorielle. Sa mise en œuvre est plus simple car elle ne nécessite pas de connaissances approfondies en matière d'encastrements ni de processus complexe d'ingestion de vecteurs.</p><p>En outre, la consommation de ressources est plus faible, car la recherche vectorielle nécessite une plus grande capacité de stockage et de mémoire pour l'indexation de l'incorporation et la recherche.</p><p>Un autre aspect important est la régionalisation de la recherche. Grâce aux synonymes, il est possible d'adapter les termes à la langue et aux coutumes locales. Ceci est utile dans les situations où les embeddings peuvent ne pas correspondre à des expressions régionales ou à des termes spécifiques à un pays. Par exemple, certains mots ou acronymes peuvent avoir des significations différentes selon la région, mais sont naturellement traités comme des synonymes par les utilisateurs locaux. Au Brésil, cette situation est assez courante. "Abacaxi" et "ananás" sont le même fruit (ananas), mais le second terme est plus couramment utilisé dans certaines régions du nord-est. "De même, le pão francês", bien connu dans le Sud-Est, peut être appelé "pão careca" dans le Nord-Est.</p><h2>Comment utiliser les LLM pour générer des synonymes ?</h2><p>Pour obtenir automatiquement des synonymes, on peut utiliser des LLM, qui analysent le contexte d'un terme et suggèrent des variations appropriées. Cette approche permet d'étendre dynamiquement les synonymes, ce qui garantit une recherche plus large et plus précise sans dépendre d'un dictionnaire fixe.</p><p>Dans cette démonstration, nous utiliserons un LLM pour générer des synonymes pour des produits de commerce électronique. De nombreuses recherches ne donnent que peu ou pas de résultats en raison de variations dans les termes recherchés. Les synonymes permettent de résoudre ce problème. Par exemple, une recherche sur "smartphone" peut englober différents modèles de téléphones mobiles, ce qui permet aux utilisateurs de trouver les produits qu'ils recherchent.</p><h3>Produits requis</h3><p>Avant de commencer, nous devons configurer l'environnement et définir les dépendances nécessaires. Nous utiliserons la solution fournie par Elastic pour <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/run-elasticsearch-locally.html">exécuter Elasticsearch et Kibana localement dans Docker</a>. Le code sera écrit en Python, v3.9.6, avec les dépendances suivantes :</p>pip install openai==1.59.8 elasticsearch==8.15.1<h3>Création de l'index des produits</h3><p>Dans un premier temps, nous créerons un index des produits sans support de synonymes. Cela nous permettra de valider les requêtes et de les comparer à un index comprenant des synonymes.</p><p>Pour créer l'index, nous chargeons en masse un jeu de données de produits à l'aide de la commande suivante dans 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>Générer des synonymes avec LLM</h3><p>Dans cette étape, nous utiliserons un LLM pour générer dynamiquement des synonymes. Pour ce faire, nous intégrerons l'API OpenAI, en définissant un modèle et une invite appropriés. Le LLM recevra la catégorie et le nom du produit, en veillant à ce que les synonymes soient pertinents du point de vue contextuel.</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>À partir de l'index des produits créé, nous récupérerons tous les articles de la catégorie "Electronics" et enverrons leurs noms au LLM. Le résultat attendu sera quelque chose comme :</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>Avec les synonymes générés, nous pouvons les enregistrer dans Elasticsearch à l'aide de l'API Synonyms.</p><h3>Gestion des synonymes avec l'API Synonyms</h3><p>L'API Synonymes offre un moyen efficace de gérer les ensembles de synonymes directement dans le système. Chaque ensemble de synonymes se compose de règles de synonymie, selon lesquelles un groupe de mots est traité comme équivalent dans les recherches.</p><p><strong>Exemple de création d'un jeu de synonymes</strong></p>PUT _synonyms/my-synonyms-set
{
  "synonyms_set": [
    {
      "id": "rule-1",
      "synonyms": "hello, hi"
    },
    {
      "synonyms": "bye, goodbye"
    }
  ]
}<p>
Cela crée un ensemble appelé "my-synonyms-set," où "hello" et "hi" sont traités comme des équivalents, ainsi que "bye" et "goodbye."</p><h2>Mise en œuvre de la création de synonymes pour le catalogue de produits</h2><p>Vous trouverez ci-dessous la méthode permettant de construire un ensemble de synonymes et de l'insérer dans Elasticsearch. Les règles de synonymie sont générées sur la base du mappage des synonymes suggérés par le LLM. Chaque règle possède un identifiant, correspondant au nom du produit au format "slug", et la liste des synonymes calculée par le 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>Vous trouverez ci-dessous la demande de création d'un ensemble de synonymes :</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>Une fois l'ensemble de synonymes créé dans le cluster, nous pouvons passer à l'étape suivante, qui consiste à créer un nouvel index avec prise en charge des synonymes à l'aide de l'ensemble défini.</p><p>Le code Python complet avec les synonymes générés par LLM et la création d'ensembles de synonymes définie par l'API Synonyms est ci-dessous :</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>Création d'un index avec prise en charge des synonymes</h3><p>Un nouvel index sera créé dans lequel toutes les données de l'index <code>products</code> seront réindexées. Cet index utilisera le <code>synonyms_filter</code>, qui applique le <code>products-synonyms-set</code> créé précédemment.</p><p>Vous trouverez ci-dessous le mappage de l'index configuré pour utiliser les synonymes :</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>Réindexation de l'index <code>products</code></h3><p>Nous allons maintenant utiliser l'<strong>API Reindex</strong> pour migrer les données de l'index <code>products</code> vers le nouvel index <code>products_02</code>, qui prend en charge les synonymes. Le code suivant a été exécuté dans Kibana DevTools :
</p>POST _reindex
{
  "source": {
    "index": "products"
  },
  "dest": {
    "index": "products_02"
  }
}<p>Après la migration, l'index <code>products_02</code> sera alimenté et prêt à valider les recherches à l'aide du jeu de synonymes configuré.</p><h3>Valider la recherche avec des synonymes</h3><p>Comparons les résultats de recherche entre les deux index. Nous allons exécuter la même requête sur les deux index et vérifier si les synonymes sont utilisés pour récupérer les résultats.</p><h4>Recherche dans l'index <code>products</code> (sans synonymes)</h4><p>Nous utiliserons Kibana pour effectuer des recherches et analyser les résultats. Dans le menu Analytics &gt; Discovery, nous allons créer une vue de données pour visualiser les données des index que nous avons créés.</p><p>Dans Discovery, cliquez sur Data View et définissez un nom et un modèle d'index. Pour l'index "<strong>products</strong>", nous utiliserons le modèle "<strong>products</strong>". Ensuite, nous répéterons le processus pour créer une nouvelle vue de données pour l'index "<strong>products_02</strong>", en utilisant le modèle "<strong>products_02".</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte826fd932cfeb9df/6a17fdffec0f8912aa5a6841/3ad4a6891a3905e96532a312932fdf3a8216aec2-1600x599.png" alt="" /><p>Une fois les vues de données configurées, nous pouvons retourner sur Analytics &gt; Discovery et commencer les validations.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltba3729c60068e8a0/6a17fe01e9ea87ba2aa9c82a/422c4b2b51abae6580cad25085d1b8a365fc6b9e-1294x850.png" alt="" /><p>Ici, après avoir sélectionné les produits DataView et effectué une recherche pour le terme "tablet", nous n'obtenons aucun résultat, même si nous savons qu'il existe des produits tels que "Kindle Paperwhite" et "Apple iPad Air".</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2c6a383dd4cb0157/6a17fe02577262671d1bce0c/e4ae3a785fdd93f48d7c7d204185ded149126f2c-1600x862.png" alt="" /><h4>Recherche dans l'index <code>products_02</code> (support des synonymes)</h4><p>Lors de l'exécution de la même requête sur la vue de données "<strong>products_synonyms</strong>", qui prend en charge les synonymes, les produits ont été récupérés avec succès. Cela prouve que le jeu de synonymes configuré fonctionne correctement, en garantissant que les différentes variations des termes recherchés renvoient les résultats escomptés.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt986b4706e2f70014/6a17fe043e9e454edbba16d3/e609749c39e90d5c82fa846af6124679dd62bcb8-1600x526.png" alt="" /><p>Nous pouvons obtenir le même résultat en exécutant la même requête directement dans Kibana DevTools. Il suffit d'effectuer une recherche dans l'index products_02 à l'aide de l'API de recherche Elasticsearch :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbe829a3c4d7aac60/6a17fe05e8fbce03d73a1bd7/504d0d1f96dcfbceb309063dc0716bcee64ad2f8-1600x870.png" alt="" /><h2>Conclusion</h2><p>La mise en œuvre de synonymes dans Elasticsearch a permis d'améliorer la précision et la couverture des recherches dans les catalogues de produits. Le principal facteur de différenciation était l'utilisation d'un <strong>LLM</strong>, qui générait des synonymes automatiquement et en fonction du contexte, éliminant ainsi le besoin de listes prédéfinies. Le modèle a analysé les noms et les catégories de produits, en veillant à ce que les synonymes soient pertinents pour le commerce électronique.</p><p>En outre, l'<strong>API Synonymes</strong> a simplifié la gestion des dictionnaires, en permettant de modifier dynamiquement les ensembles de synonymes. Grâce à cette approche, la recherche est devenue plus souple et plus adaptable aux différents types de requêtes des utilisateurs.</p><p>Ce processus peut être continuellement amélioré grâce à de nouvelles données et à des ajustements de modèles, ce qui garantit une expérience de recherche de plus en plus efficace.</p><h2>Références</h2><p><strong>Exécuter Elasticsearch localement</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>Synonymes 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[Pertinence]]></category>
    <category><![CDATA[Les bases]]></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[Vivre et prospérer avec les logs : nouveau mode d'indexation Elasticsearch logsdb]]></title>
    <description><![CDATA[La dernière innovation d'Elasticsearch en matière de gestion des journaux, logsdb, réduit l'empreinte de stockage des données de journaux jusqu'à 65%, ce qui permet aux équipes chargées de l'observabilité et de la sécurité d'accroître la visibilité sans dépasser leur budget, tout en conservant l'accessibilité et la possibilité de recherche de toutes les données.]]></description>
    <content:encoded><![CDATA[<h2>Le nouveau mode d'indexation Elasticsearch logsdb réduit le stockage des logs jusqu'à 65 %</h2><p>Aujourd'hui, nous annonçons la disponibilité générale du nouveau mode d'indexation d'Elasticsearch, logsdb, qui <strong>réduit l'empreinte de stockage des données de log jusqu'à 65%</strong> par rapport aux versions récentes d'Elasticsearch sans logsdb. Cette amélioration spectaculaire permet aux équipes chargées de l'observabilité et de la sécurité d'accroître la visibilité sans dépasser leur budget, tout en conservant l'accès immédiat à toutes les données à des fins d'analyse.</p><p>Logsdb optimise l'ordre des données, élimine les doublons en reconstruisant à la volée les valeurs des champs non stockés grâce à la fonctionnalité <code>synthetic _source</code> et améliore la compression au moyen d'algorithmes et codecs avancés, tout en utilisant le stockage en colonnes dans Elasticsearch pour un stockage et une récupération efficaces des logs.</p><h2>Améliorez les analyses et réduisez les coûts en améliorant l'efficacité du stockage avec le mode d'indexation logsdb</h2><p>Les logs fournissent des signaux critiques pour détecter et résoudre les problèmes d'observabilité et de sécurité, et leur utilité ne fait que croître à mesure que les avancées de l'IA facilitent l'analyse des données textuelles. Un stockage efficace et un accès performant sont donc plus importants que jamais.</p><p>Malheureusement, le volume croissant de logs généré par l'infrastructure et les applications augmente les coûts, contraignant les entreprises à faire des compromis qui entravent l'analyse : limiter la collecte, réduire la conservation ou reléguer les données récentes à des niveaux d'archivage cloisonnés.</p><p>Logsdb répond directement à ces défis. Grâce à une meilleure efficacité de stockage, vous pouvez collecter davantage de données et éviter les tracas liés à un filtrage des données compliqué. Vous pouvez conserver les logs plus longtemps pour favoriser la détection des menaces, la réponse aux incidents et la conformité. Et parce que toutes les données sont toujours consultables, vous pouvez obtenir rapidement des informations, quelle que soit la taille de votre ensemble de données.</p><h2>Innovation technique associée au mode d'indexation logsdb</h2><p>Le mode d'indexation Logsdb réduit considérablement l'empreinte de stockage des données de log grâce à un index trié intelligent, synthetic _source et une compression avancée. La mise en œuvre de cette solution peut réduire les besoins en stockage des logs jusqu'à 65 %, par rapport aux versions récentes d'Elasticsearch sans logsdb. Bien que logsdb utilise actuellement plus de processeur lors de l'indexation, son stockage efficace réduit les coûts globaux pour la majorité des clients. Pour les clients qui nécessitent une conservation à long terme, nous anticipons des réductions du coût total de possession pouvant atteindre 50 %.</p><p>Le <strong>tri intelligent des index</strong> améliore l'efficacité du stockage jusqu'à 30% et réduit la latence des requêtes sur certains ensembles de données de journalisation en localisant les données similaires à proximité les unes des autres. Par défaut, il trie les indices par host.name et @timestamp. Si vos données comportent des champs plus appropriés, vous pouvez les spécifier à la place.</p><p>La <strong>compression avancée</strong> réduit considérablement les besoins en stockage pour les données à forte teneur en texte, comme les journaux, grâce à la compression Zstandard (Zstd), à l'encodage delta, à l'encodage run-length et à d'autres codecs intelligents qui sont automatiquement sélectionnés. Les valeurs-documents, qui sont stockées dans un format en colonnes optimisé pour la compression et les performances, permettent de stocker et d'extraire efficacement les valeurs des champs pour le tri, l'agrégation et l'écriture de scripts.</p><p>La <strong>_source synthétique</strong> permet aux entreprises de réduire leurs besoins en stockage de 20 à 40% supplémentaires en supprimant le champ _source et en le reconstruisant entièrement ou partiellement à la demande. Bien que cette fonction nécessite parfois davantage de calculs pour l'indexation et la recherche, les tests montrent qu'elle apporte des améliorations nettes mesurables en termes d'efficacité. Synthetic _source s'appuie sur près de deux ans d'utilisation en production avec les métriques, avec de nombreuses améliorations pour les journaux, y compris la prise en charge de presque tous les types de champs.</p><p>Les économies de stockage résultantes sont répercutées à travers les différentes phases du cycle de vie des index. Une réduction du stockage de 65 % dans le niveau hot entraînera la même réduction dans les niveaux warm, cold et frozen, ainsi qu'une baisse de l'empreinte de stockage des snapshots avec un stockage en buckets.</p><h2>Aucun compromis sur la visibilité : conservez tous vos logs pour l'observabilité et la sécurité</h2><p>Les logs sont essentiels pour garantir la visibilité sur l'infrastructure et les applications. Ils fournissent le signal le plus simple et le plus critique pour le suivi et le dépannage. Cependant, les coûts augmentent proportionnellement aux volumes de logging. Cela contraint les clients à mettre en œuvre des politiques de filtrage et de gestion complexes, à supprimer des données prématurément et à reléguer les logs pertinents dans des magasins qui nécessitent un jour ou plus pour être réhydratés avant leur analyse. Sans un ensemble de données complet, facilement interrogeable et accessible, il est beaucoup plus difficile d'identifier et de résoudre les problèmes.</p><p>Le mode index de Logsdb s'appuie sur les fonctionnalités révolutionnaires d'Elasticsearch, telles que les <a href="https://www.elastic.co/fr/elasticsearch/elasticsearch-searchable-snapshots">instantanés consultables</a> et l'<a href="https://www.elastic.co/fr/blog/automatic-import-ai-data-integration-builder">importation automatique</a>, pour résoudre ces problèmes pour les équipes chargées des opérations et de la sécurité :</p><p><strong>Réduire les coûts : </strong>Logsdb réduit l'empreinte de stockage des journaux jusqu'à 65%, ce qui permet aux entreprises de réduire leurs dépenses de stockage tout en conservant davantage de données. Cela se traduit par des économies sur tous les niveaux de stockage - de l'état chaud à l'état gelé - et par une productivité accrue pour les équipes chargées de l'observabilité et de la sécurité qui utilisent ces données.</p><p><strong>Préservez vos données précieuses : </strong>Logsdb conserve toutes les données de vos journaux et améliore l'efficacité opérationnelle sans avoir recours à des outils supplémentaires ou à des filtres compliqués. Grâce à des fonctionnalités telles que la _source synthétique, la valeur des données est préservée sans que l'intégralité du document source ne soit stockée.</p><p><strong>Élargir la visibilité :</strong> Logsdb offre un accès efficace à toutes les données sur une seule plateforme, sans silos séparés pour l'observabilité, la sécurité et les données historiques. Pour les ingénieurs de fiabilité des sites (SRE), il accélère la résolution des problèmes en permettant l'analyse des journaux avec les métriques, les traces et les données commerciales. De même, pour les équipes des centres d'opérations de sécurité (SOC), il accélère les enquêtes et les mesures correctives en éliminant les angles morts.</p><p><strong>Rationaliser l'accès aux données :</strong> Logsdb permet aux équipes SRE de conserver efficacement les données exploitables pour le dépannage, les tendances et l'analyse. De même, les équipes SOC peuvent rapidement rechercher toutes leurs données à des fins d'investigation et de chasse aux menaces sans encourir de coûts exorbitants.</p><h2>Logsdb est prêt pour votre environnement</h2><p>Le mode d'indexation Elasticsearch logsdb est généralement disponible pour les clients Elastic Cloud Hosted et Self-Managed à partir de la version 8.17 et est activé par défaut pour les logs dans <a href="https://www.elastic.co/fr/elasticsearch/serverless">Elastic Cloud Serverless</a>.</p><p>Les fonctionnalités de base de logsdb (y compris l'index trié intelligent et la compression avancée) sont disponibles pour les entreprises disposant de licences Standard, Or et Platinum. Les capacités complètes de logsdb, qui réduisent encore les besoins en stockage (y compris synthetic _source), sont disponibles pour les clients Serverless et les entreprises avec une licence Entreprise.</p><h2>Elasticsearch logsdb en action</h2><p>Logsdb vous permet de conserver toutes vos données de logs et d'améliorer l'efficacité opérationnelle sans restreindre la collecte ni supprimer ou cloisonner vos données. Avec des fonctionnalités telles que l'index trié intelligent, la compression avancée et synthetic _source, conservez et analysez les données dont vous avez besoin avec le budget qui vous convient.</p><p>Vous voulez en faire l'expérience ? <a href="https://cloud.elastic.co/registration">Essayez Elastic gratuitement</a>.</p><p><em>La publication et la date de publication de toute fonctionnalité ou fonction décrite dans le présent article restent à la seule discrétion d'Elastic. Toute fonctionnalité ou fonction qui n'est actuellement pas disponible peut ne pas être livrée à temps ou ne pas être livrée du tout.</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[Les bases]]></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[Mise en œuvre de la recherche sémantique : Construire une recherche de recettes avec Elasticsearch]]></title>
    <description><![CDATA[Mise en œuvre de la recherche sémantique dans le contexte des sites de commerce électronique.]]></description>
    <content:encoded><![CDATA[<h2>Introduction</h2><p>De nombreux sites de commerce électronique souhaitent améliorer leur expérience en matière de recherche de recettes. La recherche sémantique, lorsqu'elle est appliquée correctement, permet aux clients de trouver rapidement les ingrédients nécessaires sur la base de requêtes plus naturelles, telles que "quelque chose pour la Saint-Valentin" ou "les repas de Thanksgiving."</p><p>Dans cet article, nous allons montrer comment utiliser Elasticsearch pour mettre en œuvre une recherche sémantique qui prend en charge de telles requêtes. Nous configurerons un index pour stocker le catalogue des ingrédients et des produits d'un supermarché et nous montrerons comment cet index peut être utilisé pour améliorer les recherches de recettes. Tout au long de cet article, nous expliquerons comment créer cette structure de données et appliquer des techniques de traitement du langage naturel pour fournir des résultats pertinents correspondant à l'intention du client.</p><p>Tout le code présenté dans cet article a été développé en Python et est disponible sur <a href="https://github.com/elastic/elasticsearch-labs/tree/main/supporting-blog-content/building-a-recipe-search-with-elasticsearch">GitHub</a>. Vous pouvez accéder au référentiel pour examiner le code source, faire les ajustements nécessaires et mettre en œuvre les solutions directement dans votre environnement de développement.</p><h2>Démarrer la mise en œuvre de la recherche sémantique</h2><p>Pour commencer à mettre en œuvre la recherche sémantique, nous devons d'abord définir le modèle de langage naturel. Elastic fournit son propre modèle, <a href="https://www.elastic.co/guide/en/machine-learning/8.15/ml-nlp-elser.html"><strong>ELSER</strong></a>, mais offre également un support pour l'intégration de modèles NLP provenant de divers fournisseurs, tels que Hugging Face. Cette flexibilité vous permet de choisir l'option qui répond le mieux à vos besoins.</p><p>Dans cet article, nous utiliserons <strong>ELSER</strong>, qui réduit la complexité du déploiement et de la gestion des modèles NLP. En outre, Elastic propose la fonction <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search-semantic-text.html"><strong>semantic_text</strong></a>, qui simplifie grandement le processus. Avec <strong>semantic_text</strong>, l'ensemble du processus de génération d'encarts devient simple et automatisé. Il vous suffit de définir un point d'inférence et de spécifier le champ qui recevra les embeddings dans votre mappage d'index. Lors de l'indexation des documents, des embeddings seront générés et automatiquement associés au champ spécifié.</p><h3>Étapes de la configuration</h3><p>Voici les étapes à suivre pour créer un index prenant en charge la recherche sémantique. En suivant ces instructions, vous aurez un index configuré et prêt pour les recherches sémantiques :</p><ol><li><p><strong>Créer le </strong><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/infer-service-elser.html"><strong>point d'inférence</strong></a>.</p></li><li><p><a href="https://github.com/andreluiz1987/semantic-search-market/blob/main/infra.py"><strong>Créer l'index</strong></a>, en définissant le champ description comme semantic_text afin qu'il puisse recevoir les embeddings.</p></li><li><p><a href="https://github.com/andreluiz1987/semantic-search-market/blob/main/ingestion.py"><strong>Indexer les données</strong></a> dans l'index "grocery-catalog", qui stockera un catalogue de produits. Ce catalogue a été obtenu à partir d'un ensemble de données disponible <a href="https://www.kaggle.com/datasets/bhavikjikadara/grocery-store-dataset?select=GroceryDataset.csv">ici.</a></p></li></ol><h2>Application de la recherche sémantique dans les supermarchés</h2><p>Maintenant que l'index est alimenté par les données sur les produits de l'épicerie, nous testons et validons les requêtes afin d'améliorer les résultats de recherche à l'aide de la recherche sémantique. Notre objectif est de fournir une expérience de recherche plus intelligente qui comprend le contexte et l'intention de l'utilisateur, en fournissant des résultats plus pertinents et plus précis.</p><h3>Défis résolus par la recherche sémantique</h3><p>Sur la base du catalogue de produits, examinons comment la recherche sémantique peut transformer l'expérience de recherche dans les magasins d'alimentation en abordant les questions de vocabulaire et de contexte avec lesquelles la recherche lexicale traditionnelle a souvent du mal à composer.</p><h4><strong>1. Interprétation des intentions culinaires</strong></h4><p><strong>Problème 01</strong>: Un client peut rechercher "seafood for grilling", mais un système de recherche lexicale peut ne pas comprendre entièrement l'intention qui sous-tend la requête. Il se peut qu'il ne parvienne pas à identifier tous les produits de la mer adaptés aux grillades et qu'il ne renvoie que les produits dont le titre contient le terme exact "seafood" ou "grill".</p><p>Dans un premier temps, nous effectuerons une recherche lexicale et analyserons les résultats. Ensuite, nous ferons la même chose avec une recherche sémantique, en comparant les résultats pour le même terme de recherche.</p><p><strong>Recherche lexicale</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>Résultats :</strong></p><p>Type de recherche</p><p>Nom</p><p>Score</p><p>Lexique</p><p>Crabe des neiges Bairdi d'Alaska de Northwest Fish</p><p>10.453125</p><p>Lexique</p><p>M. Yoshida's, Sauce Original Gourmet</p><p>7.2289705</p><p>Lexique</p><p>Premium Seafood Variety Pack - 20 pièces</p><p>7.1924105</p><p>Lexique</p><p>Vivaneau rouge américain - entier, étêté, nettoyé</p><p>6.998647</p><p>Lexique</p><p>Pinces de homard &amp; Arms, Sustainable Wild Caught</p><p>6.438654</p><p>La recherche lexicale a permis de trouver des produits de la mer adaptés à la cuisson au gril, tels que le vivaneau rouge américain et le crabe des neiges Bairdi de Northwest Fish Alaskan. Yoshida, qui n'est pas un produit de la mer mais une sauce pour la viande, ce qui suggère que l'algorithme lexical a eu du mal à comprendre le contexte de "pour les grillades."</p><p><strong>Solution de recherche sémantique</strong></p><p>Nous utilisons une requête qui combine le terme "seafood" avec des contextes de préparation tels que "grilling" pour obtenir une liste complète d'options, telles que les filets de poisson, les crevettes et les coquilles Saint-Jacques, qui sont idéales pour les grillades, même si les mots "grill" ou "seafood" n'apparaissent pas directement dans le nom du produit. Cela garantit que les résultats de la recherche correspondent mieux à l'intention du client.</p><p><strong>Recherche sémantique de requêtes :</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>Type de recherche</p><p>Nom</p><p>Score</p><p>Sémantique</p><p>Branzino entier étêté et nettoyé</p><p>16.175909</p><p>Sémantique</p><p>Morue noire d'Alaska (morue charbonnière)</p><p>15.855331</p><p>Sémantique</p><p>Vivaneau rouge américain - entier, avec tête</p><p>15.454779</p><p>Sémantique</p><p>Crabe des neiges Bairdi d'Alaska de Northwest Fish</p><p>15.855331</p><p>Sémantique</p><p>Vivaneau rouge américain - entier, avec tête</p><p>15.3892355</p><p>La recherche sémantique a permis non seulement de trouver des produits directement liés au terme "seafood,", mais aussi de comprendre le contexte de "grilling," et de trouver des poissons entiers et des filets adaptés à la cuisson sur le gril. L'essentiel ici est la précision des résultats, qui incluent des poissons entiers tels que le branzino et le cabillaud noir d'Alaska, tous deux couramment utilisés pour les grillades.</p><p><strong>Problème 02 </strong>: De nombreux clients recherchent des solutions rapides et faciles pour dîner après une longue journée de travail, en utilisant des termes tels que "easy weeknight meals." La recherche lexicale traditionnelle peut ne pas saisir pleinement le concept de repas rapide, en se concentrant souvent sur les produits dont le nom contient le mot "easy".</p><p>Comme dans le problème précédent, nous commencerons par effectuer une recherche lexicale. Ensuite, nous appliquerons une solution utilisant la recherche sémantique.</p><p><strong>Recherche lexicale</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>Résultats :</strong></p><p>Type de recherche</p><p>Nom</p><p>Score</p><p>Lexique</p><p>Étiquettes d'adresse Avery Easy Peel, 4200 pièces</p><p>8.017723</p><p>Lexique</p><p>Repas autochauffés d'urgence/portables 32</p><p>6.592727</p><p>Lexique</p><p>Poke de thon à nageoires jaunes en cubes de Coastal Seafood</p><p>5.836883</p><p>Lexique</p><p>Hefty Super Weight 12 oz Foam</p><p>5.8116536</p><p>Lexique</p><p>Serviette de table Vanity Fair Everyday, 2 plis, 110 unités</p><p>5.752989</p><p>La recherche lexicale a donné des résultats beaucoup moins pertinents, notamment des articles n'ayant aucun rapport avec les repas, tels que les étiquettes d'adresse Avery Easy Peel et les serviettes Vanity Fair Everyday Napkins. Ces produits ne répondent pas aux besoins des utilisateurs en matière de repas rapides. Si la recherche lexicale a permis de trouver un produit utile (Omeals Self Heating Emergency Meals), d'autres résultats, comme les serviettes et les étiquettes, ne correspondaient qu'aux mots "easy" ou "weeknight" dans leurs descriptions, sans vraiment répondre à l'intention de l'utilisateur de trouver une solution de repas rapide.</p><p><strong>Solution de recherche sémantique</strong></p><p>Nous avons mis en œuvre une requête qui comprend l'intention derrière les repas rapides et faciles. Il associe les produits qui peuvent être préparés rapidement, tels que les viandes précuites, les pâtes surgelées ou les kits repas, même s'ils ne comportent pas explicitement le mot "easy" dans leur nom. Cette approche permet aux clients de trouver les options les plus appropriées pour des dîners rapides en semaine, répondant ainsi à leur besoin de commodité.</p><p><strong>Recherche sémantique</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>Résultats :</strong></p><p>Type de recherche</p><p>Nom</p><p>Score</p><p>Sémantique</p><p>Repas autochauffés d'urgence/portables 32</p><p>14.610006</p><p>Sémantique</p><p>Nissin, Cup Noodles, Crevettes, 2.5 oz</p><p>13.751424</p><p>Sémantique</p><p>Mélange pour gaufres sans gluten Namaste &amp; Mélange pour crêpes</p><p>13.73376</p><p>Sémantique</p><p>Idaho Spuds, pommes de terre rissolées Golden Grill</p><p>12.549422</p><p>Sémantique</p><p>Nissin, nouilles en coupe, poulet, 24 pièces</p><p>12.034527</p><p>La recherche sémantique a permis de trouver des produits clairement liés à des repas rapides et pratiques, tels que des nouilles instantanées (Cup Noodles), des pommes de terre précuites et des préparations pour crêpes, qui sont des choix typiques pour les dîners faciles en semaine. Cela démontre que la recherche sémantique peut saisir le concept derrière l'expression "easy weeknight meals," capturant l'intention de l'utilisateur de trouver des repas rapides et pratiques. Il est intéressant de noter que des produits appartenant à d'autres catégories, telles que "soda," peuvent également être inclus lorsqu'ils sont pertinents dans le contexte (par exemple, les boissons accompagnant les repas).</p><h4><strong>2. Termes régionaux et variations de vocabulaire</strong></h4><p><strong>Problème</strong>: un client peut rechercher "soda," alors qu'un autre client peut utiliser "pop" pour le même produit. La recherche lexicale traditionnelle ne tient pas compte du fait que les deux termes renvoient au même élément.</p><p><strong>Recherche lexicale</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>Résultats :</strong></p><p>Type de recherche</p><p>Nom</p><p>Score</p><p>Lexique</p><p>Prime Hydration+ Sticks Mélange pour boisson à base d'électrolytes</p><p>14.492869</p><p>Lexique</p><p>Capri Sun, 100% Jus, Variety Pack</p><p>12.340851</p><p>Lexique</p><p>Boisson énergétique Joyburst, Frose Rose, 12</p><p>11.839179</p><p>Lexique</p><p>Pop-Tarts de Kellogg, givrés sucre brun cannelle</p><p>9.97788</p><p>Lexique</p><p>Mini barres Kind, emballage varié, 0.7</p><p>9.336912</p><p>La recherche lexicale se concentre sur les correspondances exactes entre les mots. Si des produits comme Prime Hydration et Capri Sun sont apparus, la correspondance directe avec le terme "pop" a également donné lieu à des résultats non pertinents, tels que Kellogg's Pop-Tarts, qui est un en-cas et non une boisson. Cela montre que la recherche lexicale peut être moins efficace lorsqu'un terme a plusieurs significations ou peut être ambigu.</p><p><strong>Solution de recherche sémantique</strong></p><p>Les requêtes sémantiques permettent de résoudre le problème des variations de vocabulaire que la recherche lexicale ne parvient pas à résoudre. En élargissant les termes de recherche, nous sommes en mesure d'obtenir des résultats basés sur la signification contextuelle, ce qui permet de fournir des réponses plus pertinentes et plus complètes.</p><p><strong>Requête :</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>Résultats :</strong></p><p>Type de recherche</p><p>Nom</p><p>Score</p><p>Sémantique</p><p>Olipop 12 oz Soda Prébiotique Variété</p><p>14.776867</p><p>Sémantique</p><p>Cocofusion antioxydante Bai, paquet de variétés, 18</p><p>14.663253</p><p>Sémantique</p><p>Boisson énergétique Monster, Zéro Ultra, 24</p><p>14.486348</p><p>Sémantique</p><p>Joyburst Energy Variété, 12 fl oz</p><p>14.007214</p><p>Sémantique</p><p>Boisson énergétique Joyburst, Frose Rose, 12</p><p>13.641038</p><p>La recherche sémantique renvoie des produits qui correspondent directement au concept de "pop" en tant que synonyme de "soda" (comme Olipop Prebiotics Soda), même si le terme exact "pop" n'est pas présent dans le nom du produit. La recherche a compris l'intention de l'utilisateur - une boisson rafraîchissante à faible teneur en sucre - et a pu renvoyer des produits pertinents, y compris des options telles que des sodas prébiotiques (Olipop) et des boissons énergisantes sans sucre (Monster Energy Drink).</p><h2>Conclusion</h2><p>La mise en œuvre de la recherche sémantique dans le contexte des magasins d'alimentation s'est avérée très efficace pour comprendre des requêtes complexes telles que "fruits de mer à griller" et "repas faciles à préparer en semaine." Cette approche nous a permis d'interpréter plus précisément les intentions des utilisateurs et de leur renvoyer des produits très pertinents.</p><p>En utilisant Elasticsearch et en simplifiant le processus avec ELSER, nous avons pu appliquer la recherche sémantique rapidement et efficacement, ce qui a permis d'améliorer considérablement les résultats de recherche et d'offrir une expérience d'achat plus souple et plus ciblée. Cela a permis non seulement d'optimiser le processus de recherche, mais aussi d'accroître la pertinence des résultats proposés aux clients.</p><h2>Références</h2><p>Modèle 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>Texte sémantique :</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>Ensemble de données :</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>Recherche sémantique :</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[Les bases]]></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>