<?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[Opérations - 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[Opérations - 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/operations</link>
    </image>
    <link>https://www.elastic.co/fr/search-labs/blog/category/operations</link>
    <atom:link href="https://www.elastic.co/fr/search-labs/rss/category/operations.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[fr]]></language>
    <lastBuildDate>Mon, 28 Sep 2026 15:07:28 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Recherche par IA agentique avec garde-fous déterministes dans Elasticsearch pour une exécution sécurisée des requêtes]]></title>
    <description><![CDATA[Les systèmes de recherche par IA agentique échouent souvent lorsque les LLM génèrent des requêtes directement. Découvrez comment des garde-fous déterministes et une architecture de plan de contrôle permettent une exécution de requêtes sûre, fiable et contrôlée avec Elasticsearch.]]></description>
    <content:encoded><![CDATA[<p>Les <a href="https://www.elastic.co/search-labs/blog/agentic-ai-search-deterministic-guardrail-query-execution">parties 1 à 7</a> de cette série décrivent un plan de contrôle gouverné pour la recherche e-commerce. Un utilisateur saisit une requête. Le plan de contrôle classe l'intention, applique les contraintes métier, résout les conflits de politiques et oriente vers la stratégie de récupération appropriée, le tout avant même que le catalogue produit ne soit interrogé. Toute l'architecture part du principe que l'entrée est une chaîne de recherche saisie par un acheteur humain.</p><p>Ce dernier article pose la question suivante : qu'est-ce qui change lorsque l'entrée provient d'un agent IA ?</p><p>La réponse est que l'architecture ne change pas, mais les enjeux, oui. Toutes les propriétés du plan de contrôle gouverné qui sont importantes pour les requêtes rédigées par des humains sont <em>encore plus</em> importantes lorsque le décideur en amont est un grand modèle de langage (LLM). Le déterminisme, l'auditabilité, la résolution des conflits et l'application des contraintes deviennent des garde-fous critiques plutôt que des commodités opérationnelles, car le système qui produit l'entrée est par nature probabiliste.</p><h2>Le problème de la recherche agentique</h2><p>L'approche la plus courante de la recherche pilotée par l'IA est simple : donner au LLM le schéma de la base de données, fournir des règles métier dans le prompt et laisser l'agent générer la requête directement.</p><p>Pour un chatbot e-commerce, cela signifie injecter le mapping d'index Elasticsearch, les types de champs, les taxonomies de catégories, la logique de tarification et les contraintes métier dans la fenêtre de contexte de l'agent, puis demander au LLM de traduire le langage naturel en DSL de requêtes Elasticsearch valide. Le LLM devient ainsi l'auteur de la requête.</p><p>Cette approche fonctionne lors des démonstrations. Elle échoue en production pour quatre raisons.</p><h3>Gonflement du contexte</h3><p>Le mapping d'un système e-commerce d'entreprise est un document complexe. Les définitions de champs, les objets imbriqués, les configurations multichamps et les paramètres d'analyse peuvent représenter des milliers d'éléments avant même l'ajout de la logique métier. Outre ce mapping, l'agent a besoin des taxonomies de catégories (qui, dans le contexte de l'e-commerce d'entreprise, peuvent contenir des dizaines de milliers de valeurs), des règles de tarification, des hiérarchies de marques, des critères d'éligibilité et de la logique de campagne.</p><p>Le résultat est une fenêtre de contexte dominée par les métadonnées structurelles plutôt que par l'intention réelle de l'utilisateur. Cela augmente la latence, augmente le coût des tokens et dégrade la capacité du LLM à suivre les instructions à mesure que le contexte s'agrandit. Il s'agit d'un phénomène bien documenté, parfois appelé <a href="https://www.trychroma.com/research/context-rot"><em>pourriture contextuelle</em></a> : à mesure que le prompt s'allonge, l'attention portée par le modèle à une instruction particulière diminue.</p><h3>Hallucination probabiliste</h3><p>Les LLM génèrent des requêtes à partir de schémas présents dans leurs données d'entraînement et du contexte fourni. Lorsqu'on leur demande de produire du DSL de requêtes Elasticsearch, le modèle peut halluciner des noms de champs inexistants, construire des clauses de requête syntaxiquement invalides, appliquer incorrectement des types de filtres à des types de champs inappropriés, ou produire des requêtes syntaxiquement valides mais sémantiquement incorrectes, renvoyant des résultats qui ne correspondent pas à l'intention de l'utilisateur.</p><p>Le <a href="https://cloud.google.com/blog/products/databases/how-to-get-gemini-to-deeply-understand-your-database">benchmark BIRD de conversion texte vers SQL</a> de Google Cloud illustre les limites de cette approche. Le résultat de pointe de Google, basé sur un modèle unique, a atteint une précision de 70 à 80 %, c'est-à-dire que près d'une requête générée sur quatre était incorrecte. Ce résultat concerne le SQL, bien plus standardisé que le DSL de requêtes Elasticsearch. Le taux d'erreur des requêtes Elasticsearch générées par LLM dans un environnement de production réel, avec des mappings complexes et une sémantique spécifique au métier, serait probablement plus élevé.</p><p>Pour un système e-commerce critique en termes de revenus, un taux d'erreur de requête sur quatre n'est pas un problème de réglage à résoudre de façon itérative. C'est une limite architecturale de l'approche.</p><h3>La faille de sécurité</h3><p>Lorsque le LLM a accès au schéma de la base de données et agit en tant qu'auteur de la requête, le système est vulnérable à l'injection indirecte de prompts. Un utilisateur qui interagit avec un chatbot e-commerce peut créer des entrées conçues pour inciter l'agent à générer des requêtes involontaires.</p><p>Ce n'est pas un risque théorique. L'<a href="https://www.elastic.co/blog/owasp-top-10-for-llms-guide">injection de prompts</a> est l'une des surfaces d'attaque les plus activement étudiées dans les systèmes LLM déployés. Le problème fondamental est que lorsque l'agent rédige la requête, il n'y a pas de limite structurelle entre l'intention de l'utilisateur et l'exécution de la requête. Le LLM interprète simultanément la demande de l'utilisateur et construit l'opération de base de données. Toute manipulation du premier élément affecte directement le second.</p><h3>Échec du scaling à haute cardinalité</h3><p>Certains champs e-commerce présentent une cardinalité extrême. Un catalogue de produits peut comporter 17 000 valeurs de catégorie, des milliers de noms de marques et des centaines de combinaisons d'attributs. Les workflows agentiques standard nécessitent l'injection de ces valeurs dans le contexte afin que le LLM puisse sélectionner la valeur correcte lors de la construction d'une requête.</p><p>Cela crée un compromis impossible : soit injecter toutes les valeurs possibles (consommant un contexte énorme et dégradant les performances), injecter un sous-ensemble (et accepter que l'agent ne puisse pas référencer des valeurs en dehors de ce sous-ensemble), ou revenir à une recherche non gouvernée. Ceci est directement lié au problème central abordé dans la <a href="https://www.elastic.co/search-labs/blog/ecommerce-search-governance-improve-retrieval">partie 1</a> : si le LLM recherche "oranges" et qu'Elasticsearch renvoie des sodas à l'orange, l'expérience du chat se dégrade de la même manière que l'expérience de la recherche. L'absence de gouvernance signifie que le système ne peut pas appliquer la résolution prévue par l'acheteur.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt14a980ba09d88ee8/6a16f34d66c4f98516f8bd97/f11c44feb5291002d4ec4ac79484ea39d4e48a95-642x133.png" alt="Un organigramme montre une requête utilisateur, &quot;Je veux confectionner une boisson rafraîchissante…&quot;, aboutissant à une sortie LLM &quot;oranges&quot;, suivie d'un serveur d'application envoyant une requête textuelle sur les oranges à un catalogue de produits, se terminant par des résultats affichant de la marmelade, des oranges entières et du soda à l'orange." /><p>La récupération dynamique de valeurs pertinentes en fonction de la requête est une alternative connue, mais elle introduit une étape supplémentaire non déterministe où la récupération elle-même peut passer à côté de valeurs pertinentes. De plus, cela ajoute de la latence et de la complexité à chaque requête.</p><h2>L'alternative architecturale : dissocier l'intention de l'exécution</h2><p>Le plan de contrôle gouverné décrit dans les parties 1 à 7 offre une approche fondamentalement différente. Au lieu que le LLM soit l'auteur de la requête finale, son rôle est réduit à une seule tâche bien délimitée : extraire une chaîne d'intention de recherche à partir de l'entrée en langage naturel de l'utilisateur.</p><p>L'utilisateur indique : "Je cherche des chaussures marron bon marché." Le rôle de l'agent n'est pas de générer une requête Elasticsearch, mais d'extraire et de transmettre l'intention de recherche (dans ce cas, quelque chose comme "chaussures marron bon marché") au plan de contrôle. Le plan de contrôle suit alors sa procédure habituelle : il filtre la chaîne d'intention par rapport aux politiques stockées, compose les politiques correspondantes par le biais de transformations en cascade, résout les conflits de manière déterministe et produit une requête Elasticsearch gouvernée.</p><p>Le LLM ne voit jamais le mapping des index. Il ne connaît jamais les types de champs, les taxonomies de catégories ou les seuils de tarification. Il ne crée jamais de clause de requête. Il agit du côté du langage naturel d'une frontière architecturale que nous appelons <em>isolation des métadonnées</em> (metadata air gap), une séparation stricte entre la composante probabiliste (le LLM) et la couche de données structurées (schéma, politiques et construction de requêtes).</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb4d701bfa4f2f279/6a16f34e1949f70ddce7a78d/12dacc77f0c481c9ada84725eff370c7e2c4b429-642x143.png" alt="Un diagramme de flux montre une requête utilisateur, &quot;Je veux confectionner une boisson rafraîchissante…&quot;, aboutissant à une sortie LLM de &quot;oranges&quot;, suivie d'un serveur d'application envoyant la requête à un plan de contrôle, puis recevant une requête réécrite qui est utilisée pour effectuer une requête textuelle pour les oranges dans la catégorie Fruits, se terminant par une recherche de produit qui renvoie des images d'oranges." /><h3>Ce que l'espace isolé des métadonnées fournit</h3><ul><li><p><strong>Insensibilité au schéma.</strong> Le LLM n'a pas accès au schéma de la base de données et ne peut donc pas générer de requêtes invalides, halluciner les noms de champs ni être manipulé pour révéler des informations structurelles. Le schéma existe uniquement du côté déterministe de la séparation physique.</p></li><li><p><strong>Contexte minimal.</strong> Au lieu de milliers de tokens de données de mapping, de règles métier et de taxonomies de catégories, le prompt du LLM ne contient qu'une persona et des instructions d'extraction d'intent. Cela réduit considérablement le coût des tokens, la latence et la dégradation du contexte.</p></li><li><p><strong>Exécution déterministe.</strong> Chaque requête qui parvient à Elasticsearch est créée par le plan de contrôle à l'aide de modèles de règles validées par des humains, et non générés de manière probabiliste par un LLM. La validité syntaxique est garantie. La correction sémantique est garantie par le même framework de politiques que celui décrit dans les parties 1 à 6.</p></li><li><p><strong>Sécurité par architecture.</strong> L'injection de prompt devient structurellement inefficace. Même si un utilisateur manipule l'agent pour produire une chaîne d'intention inhabituelle, cette chaîne est filtrée par rapport aux politiques stockées. Si aucune politique ne correspond, aucune requête n'est générée. L'utilisateur ne peut pas demander à l'agent de construire une requête, car l'agent ne construit pas de requêtes. Le plan de contrôle le fait, et le plan de contrôle est déterministe.</p></li></ul><h2>Comment les pièces s'assemblent</h2><p>La procédure suivante explique comment le plan de contrôle gouverné traite une requête transmise par un agent.</p><h3>Étape 1 : L'utilisateur parle à l'agent</h3><p>Un client interagissant avec un chatbot e-commerce déclare : "Je cherche du chocolat pas cher, sans arachide."</p><h3>Étape 2 : L'agent extrait l'intention</h3><p>Le rôle du LLM est d'extraire les intentions, et non de générer des requêtes. À partir d'un simple prompt lui demandant d'identifier l'intention de la recherche du produit, l'agent produit une chaîne de caractères : "chocolat bon marché sans arachide".</p><p>Il s'agit d'une tâche de classement simple. Le LLM n'a pas besoin du mapping d'index, de la taxonomie par catégories ou des règles de tarification pour la réaliser. Il doit comprendre le langage naturel, et c'est exactement ce que font les LLM.</p><h3>Étape 3 : Le plan de contrôle gère la requête</h3><p>La chaîne d'intention "chocolat bon marché sans arachide" est transmise au plan de contrôle, qui la compare à l'index des politiques. Trois politiques correspondent :</p><ul><li><p>La politique "bon marché" (extrait "bon marché", applique un filtre de prix basé sur la catégorie de produit).</p></li><li><p>La politique "chocolat" (limite les résultats aux catégories de chocolat).</p></li><li><p>La politique de négation "sans" (extrait la cible d'exclusion et applique un filtre <code>must_not</code>)</p></li></ul><p>Le plan de contrôle applique ces politiques par le biais de la même transformation en cascade décrite dans la <a href="https://www.elastic.co/search-labs/blog/ecommerce-search-governance-control-plane-architecture">partie 3</a> et <a href="https://www.elastic.co/search-labs/blog/elasticsearch-percolator-search-governance">4</a> : ordre de priorité, résolution des conflits par champ, suivi des expressions consommées. Si une politique "campagne de Noël" est également active, elle se combine avec les politiques de produits exactement comme décrit dans la <a href="https://www.elastic.co/search-labs/blog/ecommerce-search-governance-control-plane-architecture">partie 3</a> ; l'implication de l'agent ne change absolument rien au modèle de gouvernance.</p><h3>Étape 4 : La requête gouvernée s'exécute</h3><p>Le plan de contrôle produit une requête Elasticsearch entièrement gouvernée : une recherche sur "chocolat", limitée aux catégories appropriées, avec un prix plafond dérivé de la politique "bon marché", un filtre d'exclusion pour les produits contenant de l'arachide et toutes les améliorations de campagne actives appliquées. Si la politique "chocolat" comprend également des pondérations d'optimisation économique (<a href="https://www.elastic.co/search-labs/blog/ecommerce-search-optimization-query-governed">Partie 7</a>), celles-ci sont également appliquées. La valeur du boosting de marge est fixée à 3x, car "chocolat" est une requête de navigation où le détaillant bénéficie de la promotion de produits à marge plus élevée. Si l'acheteur a un historique d'achat<a href="https://www.elastic.co/search-labs/blog/elasticsearch-personalized-search-governed-ecommerce">(Partie 6</a>), les signaux de personnalisation sont superposés. Cette requête est syntaxiquement valide par construction et sémantiquement correcte par conception de la politique.</p><h3>Étape 5 : Les résultats sont renvoyés par l'intermédiaire de l'agent</h3><p>Les résultats des produits sont renvoyés à l'agent, qui les présente à l'utilisateur sous forme de conversation. Le rôle de l'agent dans le chemin de retour est la présentation : mettre en forme les résultats, répondre aux questions de suivi, fournir des détails sur les produits. La récupération elle-même était gouvernée, déterministe et explicable.</p><h2>Ce que l'agent sait faire (et ce qu'il ne sait pas faire)</h2><p>Cette architecture tire parti des points forts du LLM et protège le système de ses points faibles.</p><p>Les LLM excellent dans la compréhension de l'intention en langage naturel. "Je cherche du chocolat pas cher, sans arachide" est une tâche de compréhension du langage naturel qui consiste à analyser l'intention, identifier les références aux produits et reconnaître la négation. Les LLM gèrent cela efficacement, car il s'agit d'un problème de classification, et non de génération. Le résultat est une courte chaîne de caractères exprimant l'intention, et non une requête structurée complexe.</p><p>Les LLM peinent à produire des résultats structurés et précis sous des contraintes complexes. Générer du DSL de requêtes Elasticsearch valide exige des noms de champs exacts, une imbrication correcte des clauses, des types de filtres appropriés pour chaque champ et une application cohérente des règles métier à travers des milliers de cas particuliers. Ce sont précisément les propriétés qu'un système déterministe garantit sans difficulté, contrairement à un système probabiliste.</p><p>Le plan de contrôle gouverné place chaque composant à sa place : le LLM côté langage naturel, le moteur de politique déterministe côté construction de requêtes, et une frontière architecturale entre eux.</p><h2>La gouvernance limite le rayon d'action</h2><p>C'est la même idée que dans la <a href="https://www.elastic.co/search-labs/blog/ecommerce-search-governance-control-plane-architecture">partie 3</a>, étendue au contexte agentique. Dans la partie 3, nous avons observé que la gouvernance rend la recherche sémantique plus sûre en réduisant le nombre de candidats avant le début de la recherche. Une recherche sémantique sur plus de 500 produits dans une catégorie gouvernée est fondamentalement différente d'une recherche sémantique sur plus de 500 000 références.</p><p>Le même principe s'applique aux requêtes effectuées par l'intermédiaire d'un agent. Sans gouvernance, un agent qui interprète mal l'expression "chocolat bon marché" pourrait générer une requête qui parcourt l'ensemble du catalogue sans contrainte de prix, sans filtre de catégorie, sans exclusions. Avec la gouvernance, même si l'agent produit une chaîne d'intention imparfaite, le plan de contrôle limite la requête aux politiques qui correspondent. Le pire scénario est la réduction du nombre de politiques déclenchées, et non l'exécution d'une requête illimitée sur le catalogue de produits.</p><p>La gouvernance réduit le rayon d'action des erreurs probabilistes. Cela reste vrai, que le composant probabiliste soit un modèle de récupération sémantique ou un agent LLM.</p><h2>Politiques suggérées par LLM : élargissement de la couverture</h2><p>La <a href="https://www.elastic.co/search-labs/blog/ecommerce-search-governance-zero-deploy">partie 2</a> a introduit l'idée qu'un LLM peut suggérer de nouvelles politiques qui entrent dans le même pipeline Auteur → Test → Promotion que les politiques rédigées par des humains. Dans le contexte agentique, cela devient une puissante boucle de feedback.</p><p>Un LLM peut analyser les logs de requêtes, identifier les modèles où le plan de contrôle n'a pas de politique correspondante (requêtes qui aboutissent à une récupération sans modification) et suggérer de nouvelles politiques pour combler ces lacunes. Un responsable merchandising examine chaque suggestion, la teste et la déploie si elle produit le comportement attendu. Le modèle de gouvernance garantit qu'aucune politique suggérée par le LLM n'est mise en production sans validation humaine.</p><p>Au fil du temps, cela crée un cercle vertueux : la couverture des politiques du plan de contrôle s'étend, la proportion de requêtes nécessitant une récupération non modifiée diminue et le système devient progressivement plus régulé, chaque politique étant auditable, versionnée et réversible individuellement.</p><h2>Le schéma le plus large : garde-fous déterministes pour les systèmes probabilistes</h2><p>L'architecture décrite dans cette série, un plan de contrôle déterministe qui se situe entre une source d'entrée probabiliste et un système de recherche de données, n'est pas spécifique à la recherche e-commerce. Le même schéma s'applique partout où un agent IA doit interagir avec des données structurées.</p><p>Un agent interrogeant une base de données SQL fait face aux mêmes défis : gonflement du contexte dû à l'injection de schéma, noms de colonnes hallucinés, risques d'injection de prompt et sélection de valeurs à haute cardinalité. Un agent interagissant avec un système de billetterie comme Jira, un système de gestion de la relation client (CRM) comme Salesforce ou un dépôt de code comme GitHub est confronté à des problèmes analogues. Dans tous les cas, la question architecturale centrale est la même : le LLM doit-il rédiger la requête, ou doit-il extraire l'intention et la transmettre à une couche déterministe qui rédige la requête ?</p><p>Le plan de contrôle gouverné fournit une réponse répétable à cette question. Les politiques sont des données. L'extraction de l'intention est le travail du LLM. La construction de requêtes est le travail du plan de contrôle. L'espace entre les métadonnées permet de les séparer. Et le framework de gouvernance (ordre des priorités, résolution des conflits, transformations en cascade, auditabilité) garantit que la couche déterministe est gérable opérationnellement à mesure que le nombre de politiques augmente.</p><h2>Conclusion</h2><p>Les modèles de gouvernance de la recherche e-commerce décrits dans cette série (politiques en tant que données, workflow Auteur → Test → Promotion, transformations en cascade, résolution des conflits par champ, correspondance inversée basée sur un percolateur et repli multiniveau) ont été conçus pour un monde où un responsable merchandising rédige des politiques et un client saisit des requêtes. Mais cette architecture offre bien plus de possibilités que son cas d'utilisation initial.</p><p>Lorsque la source d'entrée est un agent IA plutôt qu'un consommateur humain, le plan de contrôle gouverné devient la couche de sécurité critique entre un système probabiliste et un système de stockage de données de production. Il fournit les garanties déterministes (validité syntaxique, exactitude sémantique, auditabilité et sécurité) requises par les systèmes d'entreprise que les LLM ne peuvent assurer seuls.</p><p>Le plan de contrôle déterministe ne remplace pas l'agent IA. Il permet simplement de déployer l'agent IA en toute sécurité.</p><h2>Mettre en pratique la recherche e-commerce réglementée</h2><p>L'architecture de plan de contrôle gouverné décrite dans cette série, depuis le paradigme des politiques en tant que données jusqu'à la recherche par percolateur, en passant par la personnalisation, l'optimisation économique et l'isolation des agents, a été conçue et réalisée par Elastic Services Engineering. Chaque modèle présenté dans cette série provient d'un système opérationnel construit et validé à l'aide de catalogues de produits à l'échelle de l'entreprise.</p><p>Si votre équipe développe des expériences de recherche optimisées par l'IA et a besoin de garde-fous déterministes pour les requêtes gérées par des agents, ou si vous souhaitez implémenter une architecture de recherche gouvernée et modifiable par l'entreprise sur Elasticsearch, les services professionnels d'Elastic peuvent accélérer votre mise en œuvre. Contactez <a href="https://www.elastic.co/consulting">Elastic Professional Services</a>.</p><h2>Rejoignez la discussion</h2><p>Avez-vous des questions sur la gouvernance de la recherche, les stratégies de récupération ou l'architecture de recherche e-commerce ? Participez à la <a href="https://discuss.elastic.co/">discussion élargie de la communauté Elastic</a>.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/agentic-ai-search-deterministic-guardrail-query-execution</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/agentic-ai-search-deterministic-guardrail-query-execution</guid>
    <category><![CDATA[Opérations]]></category>
    <dc:creator><![CDATA[Alexander Marquardt,Honza Král,Taylor Roy]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5b5aa5493a75281a/6a16f3490811ae71b8e9fe94/769cdc7b53cbb222f52095193cd423277e8017d9-1280x720.png" length="0" type="image/png"/>
    <pubDate>Mon, 18 May 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Personnaliser la recherche e-commerce : intégrer l’historique d’achat et les cohortes d’utilisateurs]]></title>
    <description><![CDATA[Découvrez comment créer une expérience de recherche e-commerce personnalisée dans Elasticsearch sans compromettre la gouvernance. Cet article explique comment mettre en avant les produits déjà achetés par un client et comment activer des politiques spécifiques à certaines cohortes selon les profils utilisateurs.]]></description>
    <content:encoded><![CDATA[<p><a href="https://www.elastic.co/search-labs/blog/series/governed-search-patterns">Les parties 1 à 5</a> de cette série décrivent un plan de contrôle gouverné qui classe l’intention, applique les contraintes, résout les conflits de politiques et oriente vers la stratégie de récupération appropriée, le tout avant même l’interrogation du catalogue produit. Tous les mécanismes décrits jusqu’à présent traitent les clients de manière identique. Une recherche sur « chocolat » produit le même ensemble de résultats gouverné, que le client soit vegan, un parent préparant l’anniversaire de son enfant ou un consommateur respectant les règles halal.</p><p>Cet article présente deux mécanismes de personnalisation qui étendent le plan de contrôle gouverné sans en modifier l’architecture. Les deux mécanismes s’ajoutent de manière cumulative à la couche de gouvernance présentée dans les parties 1 à 5 : les politiques continuent de s’appliquer, les contraintes restent respectées, les conflits sont toujours résolus, et les signaux de personnalisation sont intégrés à la même requête gouvernée, garantissant ainsi que les résultats renvoyés par Elasticsearch sont déjà personnalisés.</p><p>Le premier mécanisme met en avant les produits déjà achetés par le client concerné. Le second active des politiques spécifiques à certaines cohortes selon le profil du client. Ensemble, ils montrent que la personnalisation n’est pas un système distinct ajouté à la recherche ni un traitement appliqué après récupération des résultats ; elle constitue une extension naturelle du plan de contrôle piloté par des politiques.</p><p>Pour une analyse approfondie des techniques mathématiques de personnalisation utilisées dans cet article, consultez les articles <a href="https://alexmarquardt.com/elastic/personalizing-search-in-elasticsearch-without-ml-post-processing/">Personnaliser la recherche dans Elasticsearch avec un post-traitement ML</a> et <a href="https://www.elastic.co/search-labs/blog/ecommerce-search-relevance-cohort-aware-ranking-elasticsearch">Classement basé sur les cohortes dans Elasticsearch</a>.</p><p>Pour voir une démonstration en direct montrant comment l’historique d’achat peut être utilisé pour booster les résultats de recherche des clients fidèles, regardez la vidéo <a href="https://www.youtube.com/watch?v=TGf_pOWHA5M">Personnalisation explicable : booster la recherche grâce à l’historique d’achat</a>.</p><h2>Amélioration de l'historique des achats individuels</h2><p>La forme la plus simple de personnalisation est aussi l’une des plus efficaces : lorsqu’un client a déjà acheté un produit, mettez-le en avant lorsqu’il effectue une recherche associée. Un client qui achète régulièrement une marque précise de cookies aux pépites de chocolat devrait voir ces produits apparaître plus haut dans les résultats lorsqu’il recherche « cookies », non pas parce qu’un modèle a prédit une préférence, mais parce qu’il existe des preuves comportementales directes.</p><h3>Fonctionnement</h3><p>Lorsqu’une requête de recherche inclut un identifiant utilisateur, comme c’est le cas pour un utilisateur disposant d’une session ouverte, le plan de contrôle exécute deux requêtes Elasticsearch en parallèle à l’aide d’un pool de threads :</p><ol><li><p>La requête percolator exécutée sur l’index des politiques (la même recherche de gouvernance décrite dans les parties 3 et 4).</p></li><li><p>Une requête sur l'historique des achats dans un index <code>user_purchases</code>, filtrée sur l'utilisateur spécifique par <code>term(user_id)</code>, puis faisant correspondre la chaîne de recherche actuelle avec les titres des produits de cet utilisateur.</p></li></ol><p>Ces requêtes s’exécutent simultanément (aucune n’attend l’autre), de sorte que la recherche de personnalisation n’ajoute aucune latence significative au pipeline de gouvernance.</p><p>La requête sur l’historique d’achat utilise l’<a href="https://www.elastic.co/docs/manage-data/data-store/text-analysis">analyse de texte d’Elasticsearch</a> (racinisation, tokenisation) pour faire correspondre la chaîne de recherche actuelle aux titres de produits enregistrés. Cela signifie qu’une recherche sur « cookies » correspondra à un achat passé de « brownie cookies » grâce à l’analyse de texte standard, sans nécessiter de correspondance exacte de chaîne.</p><h3>Calcul des pondérations de boost</h3><p>Tous les achats passés ne méritent pas le même niveau de boost. La pondération prend en compte deux facteurs intuitifs : la fréquence d’achat du produit par le client et la date récente de cet achat. Un produit acheté 15 fois la semaine dernière constitue un signal bien plus fort qu’un produit acheté une seule fois il y a six mois. La pondération utilise une échelle logarithmique pour la fréquence (afin qu’un seul produit acheté en grande quantité ne domine pas tous les autres) et une décroissance exponentielle pour la récence (afin que les achats plus anciens perdent naturellement en importance au fil du temps).</p><p>Pour les détails mathématiques de la formule de boost, consultez l’article <a href="https://alexmarquardt.com/elastic/personalizing-search-in-elasticsearch-without-ml-post-processing/">Personnaliser la recherche dans Elasticsearch sans post-traitement ML</a>.</p><h3>Transformation en requête</h3><p>Les boosts liés à l’historique d’achat sont intégrés à la requête comme couche de scoring la plus externe, englobant les filtres et boosts des politiques de gouvernance décrits dans les parties 3 et 4, ainsi que tous <a href="https://www.elastic.co/search-labs/blog/function-score-query-boosting-profit-popularity-elasticsearch">les boosts liés aux signaux métier, tels que la marge et la popularité</a> (que nous explorerons dans la partie 7). Cela signifie qu’un produit supprimé par une politique de gouvernance ne réapparaîtra pas à cause d’un boost lié à l’historique d’achat. La <em>gouvernance</em> contrôle l’ensemble de résultats ; la <em>personnalisation</em> ajuste l’ordre des résultats au sein de celui-ci. Les produits sans historique d’achat ne sont pas pénalisés. Leur classement gouverné est préservé, même si les produits disposant d’un historique d’achat pertinent apparaîtront avant eux, toutes choses étant égales par ailleurs.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt731e67dfd3bd6ee2/6a17e9523e9e4582bbba14b6/80f0285bd80935703d39b7a4e1fd6094d71af0aa-545x273.jpg" alt="Un diagramme montre comment la recherche d’un utilisateur pour « oranges » passe par un serveur d’application, un plan de contrôle, des recherches dans l’historique d’achat et les politiques, puis par un index de catalogue produit afin de renvoyer des résultats liés aux oranges." /><h3>Pourquoi interroger Elasticsearch à chaque recherche ?</h3><p>L’historique d’achat est interrogé dans Elasticsearch à chaque recherche plutôt que mis en cache dans la couche applicative. Il s’agit d’un choix de conception délibéré. Comme la requête compare la chaîne de recherche actuelle aux titres des produits à l’aide du pipeline d’analyse de texte d’Elasticsearch, le système bénéficie des mêmes mécanismes de racinisation, de tokenisation et de gestion linguistique que ceux utilisés par la recherche produit elle-même. Une recherche en mémoire mise en cache nécessiterait de réimplémenter cette analyse ou d’accepter une correspondance moins précise.</p><p>Pour comprendre pourquoi cet ordre est important, prenons l’exemple d’un client qui a déjà acheté du jus d’orange et recherche maintenant « oranges ». La requête sur l’historique d’achat associe « jus d’orange » au terme de recherche « oranges » grâce à l’analyse de texte et calcule un boost pour ce produit. Mais la couche de gouvernance a déjà limité « oranges » à la catégorie des produits frais, excluant ainsi totalement le jus d’orange. Le boost lié à l’historique d’achat pour le jus d’orange est bien présent dans la requête, mais il n’a aucun effet, car aucun document correspondant n’existe dans l’ensemble de résultats gouverné sur lequel il pourrait s’appliquer. Le client voit des oranges fraîches classées selon leur pertinence et les critères de personnalisation. Les garde-fous de gouvernance restent en place.</p><p>Le coût en performances reste minimal : l’index de l’historique d’achat est de petite taille (l’historique d’un utilisateur contient généralement quelques dizaines à quelques centaines de documents, et non des millions), et la requête s’exécute en parallèle de la recherche percolator ; elle n’allonge donc pas le chemin critique.</p><h3>Exemple de requête pour « eau de source » sans historique utilisateur</h3><p>Si un utilisateur non connecté, ou un utilisateur n’ayant jamais acheté d’« eau de source », effectue une recherche, il pourra voir des résultats similaires à ceux-ci :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt90249896bcf2b8c2/6a17e954af47b685f5cddfcf/1d03558c8f6492a0999e1ac4f1d22680c8f3a6ce-1130x1028.png" alt="Une page web affiche les résultats de recherche pour « eau de source », avec une barre de recherche, des filtres par catégorie et par marque, ainsi que trois fiches produit contenant des informations telles que la marque, la composition et le prix." /><h3>Exemple d’historique d’achat utilisateur</h3><p>À l’inverse, une utilisatrice nommée Carol dispose d’un historique d’achat contenant les produits suivants :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3aa784ccb0653a0d/6a17e95563baffd6b7741c8d/31c1fb789efc6cef673984e9711d571efce8ed27-661x523.png" alt="Une interface numérique intitulée « Profil d’achat » présente une cliente nommée Carol avec deux cohortes et une liste d’articles récemment achetés, incluant les quantités, les dates du dernier achat et le temps écoulé depuis chaque achat." /><h3>Exemple de recherche pour « eau de source » avec l’historique d’achat ci-dessus</h3><p>Si Carol recherche « eau de source », elle verra des résultats personnalisés qui reflètent ses achats passés. D’après l’historique d’achat ci-dessus, elle a acheté « Carbonated Spring Water » (la bouteille verte) environ 40 fois, le plus récemment il y a deux jours. Si elle recherche « eau de source », ce produit bénéficie alors d’un boost, puisque nous savons qu’elle l’apprécie. Notez que dans les résultats non personnalisés, l’eau de source Rubicon apparaissait en première position.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf243c5ef1a1808ba/6a17e95763baff5d73741c91/6fce63ff051e345a79fef934cd6e71ba113ae585-1159x1062.png" alt="Une page web affiche des résultats de recherche pour « eau de source », avec des informations produit, des prix et des filtres par catégorie de boissons et par marque." /><h2>Activation des politiques basées sur les cohortes</h2><p>L’historique d’achat individuel fonctionne bien pour les clients fidèles dont les habitudes sont déjà établies. Mais de nombreux clients sont nouveaux, anonymes ou naviguent en dehors de leurs habitudes habituelles. Pour ces clients, l’appartenance à une cohorte offre une autre forme de personnalisation, fondée sur le profil du client plutôt que sur ses actions passées.</p><p>Un client vegan recherchant « chocolat » devrait voir les chocolats vegans apparaître plus haut dans les résultats. Un client respectant les règles halal et recherchant « snacks » devrait voir les options certifiées halal mises en avant. Un client soucieux de sa santé recherchant « yaourt » devrait voir les options probiotiques bénéficier d’un boost.</p><h3>Les cohortes comme politiques, et non comme étiquettes produit</h3><p>Les produits possèdent déjà leurs attributs habituels, y compris des champs tels que <code>dietary_restrictions: ["vegan"]</code> ou <code>dietary_restrictions: ["halal"]</code>. La question est de savoir où réside la logique qui relie la cohorte d'un acheteur à ces attributs de produit.</p><p>L’approche naïve serait de coder cette mapping en dur dans la couche application ou dans le modèle de recherche : si l’utilisateur est vegan, ajoutez un bonus à <code>dietary_restrictions: "vegan"</code>. Mais c’est le même spaghetti de couche application décrit dans <a href="https://www.elastic.co/search-labs/blog/ecommerce-search-governance-improve-retrieval">la Partie 1</a>, et cela crée la même friction opérationnelle : ajouter une nouvelle cohorte ou modifier la signification d’une cohorte nécessite un changement de code.</p><p>Le plan de contrôle gouverné conserve la logique de cohorte dans le moteur de politiques. Une politique de cohorte fait le lien entre deux éléments : l'appartenance d'un client à une cohorte (par exemple, « végétalien ») et un attribut de produit (par exemple, <code>dietary_restrictions: “vegan”</code>). La politique définit le lien : lorsqu’un client de la cohorte végane recherche, privilégiez les produits où <code>dietary_restrictions</code> inclut « végan ».</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte15937af719dff39/6a17e95925daab370608a274/2b6fe359774bbea059aaf93f3fa4a03eb31233ea-544x290.jpg" alt="" /><p>Comme la logique des cohortes réside dans le moteur des politiques plutôt que dans le code de l'application, cela signifie :</p><ul><li><p>L’ajout d’une nouvelle cohorte peut se faire en créant une nouvelle politique ; aucune réindexation des produits n’est nécessaire.</p></li><li><p>Les politiques de cohorte utilisent l’intégralité du moteur de règles : elles peuvent ajouter des filtres, appliquer des boosts souples, étendre les synonymes, modifier la stratégie de récupération ou effectuer toute autre action prise en charge par une politique.</p></li><li><p><a href="https://www.elastic.co/search-labs/blog/ecommerce-search-governance-zero-deploy">Le comportement des cohortes est géré via la même interface utilisateur d'administration que toutes les autres politiques : un marchand peut créer, tester et promouvoir des politiques de cohorte via le workflow Auteur → Test → Promouvoir décrit dans la deuxième partie.</a></p></li></ul><h3>Exemple de politique de cohorte vegan</h3><p>Un responsable merchandising crée une politique de cohorte présentant les caractéristiques suivantes :</p><ul><li><p><strong>Cohortes :</strong> <code>["vegan"]</code>.</p></li><li><p><strong>Critères de correspondance :</strong> correspond à n'importe quelle requête (ou à une catégorie de produit spécifique).</p></li></ul><p><strong>Action :</strong> Accélération douce sur <code>dietary_restrictions: "vegan"</code> avec un poids d'accélération de 2.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt835034b54f6790b8/6a17e95b7b54f980408b391e/fc58bbd97c0dd1fa3ce757394ca117d0789c52f6-1080x1018.png" alt="Une interface web intitulée « Edit rewrite policy » affiche des champs pour l’identifiant de la politique, le titre, la description, la sélection de cohorte, les options de requête de règle, le type de règle, les paramètres de filtre, entre autres, avec un focus sur la cohorte contenant « vegan » et sur la valeur « vegan »." /><h3>Comment fonctionne l'activation des cohortes</h3><p>Chaque document de politique comporte un champ <code>cohorts</code>. Les politiques universelles qui s'appliquent à tous les acheteurs, quelle que soit leur cohorte, peuvent laisser ce champ vide, et une valeur de <code>"_all"</code> leur sera attribuée en interne par le plan de contrôle. Les politiques spécifiques à chaque cohorte stockent les noms de leurs cohortes cibles, comme <code>["vegan", "kosher", “sweet_tooth”]</code>.</p><p>Lorsqu’une requête de recherche inclut un profil utilisateur, le plan de contrôle construit un filtre <code>terms</code> simple pour la requête du percolateur :</p>{ "terms": { "cohorts": ["_all", "vegan", "health_conscious"] } }<p>Ce filtre unique inclut toutes les politiques universelles ainsi que les politiques spécifiques à chaque cohorte de l’utilisateur. La sentinelle <code>_all</code> en fait un filtre d'inclusion propre : Aucune requête <code>must_not</code> ou <code>exists</code> n'est nécessaire pour traiter le cas où une politique n'a pas de restriction de cohorte.</p><p>Le percolator évalue ensuite les correspondances de politiques comme d’habitude. La seule différence est que l’ensemble des politiques candidates a été restreint à celles pertinentes pour les cohortes de ce client. Tous les traitements en aval (transformations en cascade, résolution des conflits champ par champ, suivi des expressions consommées) fonctionnent exactement comme dans le flux non personnalisé décrit dans les parties 3 et 4.</p><h3>Résultats d’un utilisateur non vegan (standard) lors d’une recherche sur « chocolat »</h3><p>Lorsqu’un utilisateur non vegan recherche du chocolat, aucun boost lié à une cohorte vegan n’est appliqué à ses résultats. Ils verront souvent des chocolats non vegans parmi les premiers résultats, comme ci-dessous :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc5244b19c2162f5b/6a17e95d3e03d727f74f2cb6/5bade79944ef294e2cb835cfd6e3231392e8fbd0-1159x1104.png" alt="Une page web affiche les résultats de recherche pour « chocolat », avec des filtres de catégorie et de marque à gauche, et trois listes de produits au chocolat avec descriptions, prix et spécifications." /><h3>Résultats de la politique de cohorte vegan lors d’une recherche sur « chocolat »</h3><p>Lorsqu'un client végétalien recherche « chocolat », cette politique est incluse dans l'ensemble des candidats au percolateur. Il correspond, et le plan de contrôle applique un boost doux aux chocolats certifiés végétaliens. Le boost est multiplicatif : les chocolats végétaliens sont mieux classés, mais les chocolats non végétaliens ne sont pas totalement exclus, car le filtre ci-dessus est défini comme un <em>soft boost</em>, comme nous l'avons décrit en détail dans la troisième partie de cette série.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf73ce626bcd3d66d/6a17e95f2f4a5c5341fa8934/fc6f7ec6a9de30f3a6d8f32bb9ee7ec457dea458-1138x1255.png" alt="Une page web affiche les résultats de recherche pour « chocolat », avec des filtres de catégorie et de marque sur la gauche et trois listes de produits chocolatés comprenant des descriptions, des prix et des spécifications, en mettant l'accent sur les étiquettes végétaliennes entourées." /><p>Cependant, si le client recherche explicitement « Hershey milk chocolate », le boost vegan s’applique toujours, mais peut être compensé par la pertinence textuelle plus forte des produits Hershey au chocolat au lait.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0e7487727387e524/6a17e9617b54f965ab8b3922/f47bb8bfa58106f897c4c6c143494f4367355528-1136x1142.png" alt="Une page web affiche des résultats de recherche pour « Hershey milk chocolate », avec des filtres par catégorie et par marque sur la gauche, ainsi que trois fiches produit Hershey contenant des descriptions détaillées, des prix et des informations nutritionnelles." /><p>Un client n’appartenant pas à la cohorte vegan et effectuant la même recherche ne voit jamais la politique « cohorte vegan » ; elle ne fait pas partie de son ensemble de politiques candidates. La couche de gouvernance reste identique ; seul l’ensemble des politiques actives diffère.</p><h3>Cohortes avec historique d’achat</h3><p>Un client vegan disposant d’un historique d’achat important bénéficie à la fois de l’activation des politiques spécifiques à la cohorte vegan et des boosts liés à son historique d’achat. Pour les nouveaux clients ou les utilisateurs anonymes, l’appartenance implicite à une cohorte suffit à offrir une personnalisation pertinente sans nécessiter de données comportementales (par exemple, un utilisateur anonyme n’a peut-être recherché que des produits vegans, et nous le classons donc comme membre de la cohorte vegan). Un client qui indique respecter les règles halal lors de la création de son compte reçoit immédiatement des résultats adaptés au halal dès sa première recherche.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt89044f002807c2e4/6a17e962af47b64034cddfd3/81af35a533a567d99324860c8e69cf9752533c8f-545x301.jpg" alt="Un diagramme de flux montre comment une recherche sur « oranges » passe par un serveur d’application, un plan de contrôle, des recherches dans l’historique et les politiques, puis par un index produit afin de renvoyer des produits liés aux oranges." /><h2>Composition des couches de personnalisation</h2><p>L'ordre d'imbrication des couches <code>function_score</code> est important. De l'intérieur vers l'extérieur :</p><ol><li><p><strong>Requête de base :</strong> la correspondance par mots-clés ou sémantique avec les requêtes nommées (<code>fulltext_match</code>, <code>title_phrase_match</code>).</p></li><li><p><strong>Couche de politique de gouvernance :</strong> Filtres durs sous forme de clauses <code>bool.filter</code>, coups de pouce doux sous forme de fonctions <code>function_score</code> (parties 3 et 4).</p></li><li><p><strong>Stimulation des signaux d'affaires :</strong> L'augmentation des marges et de la popularité (que nous étudierons dans la partie 7).</p></li><li><p><strong>L'historique des achats stimule :</strong> La couche externe <code>function_score</code>.</p></li></ol><p>Cet ordre garantit que la gouvernance contrôle l’ensemble de résultats (ce qui apparaît), que les signaux métier ajustent le classement au sein de cet ensemble (ce qui apparaît en premier du point de vue du distributeur) et que l’historique d’achat affine encore davantage le classement selon le comportement individuel (ce qui apparaît en premier du point de vue du client). Chaque couche s’ajoute à la précédente de manière multiplicative, de sorte que les effets se cumulent plutôt qu’ils n’entrent en conflit.</p><h2>Ce que cela signifie sur le plan opérationnel</h2><p>La personnalisation via le plan de contrôle gouverné préserve toutes les propriétés opérationnelles décrites dans les parties 1 et 2 :</p><ul><li><p><strong>Modifications sans déploiement.</strong> Les politiques de cohorte sont créées, testées et promues via l'interface utilisateur. L'ajout d'une nouvelle cohorte alimentaire ou l'ajustement d'un poids d'appoint ne nécessite aucune modification du code et aucune intervention technique.</p></li><li><p><strong>Auditabilité.</strong> Chaque politique de cohorte est un document distinct et versionné. Lorsqu’un responsable merchandising demande : « Pourquoi les produits vegans sont-ils mieux classés pour cet utilisateur ? », la réponse réside dans une politique précise dotée d’une priorité spécifique, visible dans le panneau de débogage aux côtés de toutes les autres politiques déclenchées pour cette requête.</p></li><li><p><strong>Résolution de conflits.</strong> Les politiques de cohorte participent au même mécanisme de résolution des conflits champ par champ décrit dans la partie 3. Si le boost de catégorie d’une politique de cohorte entre en conflit avec la surcharge de catégorie d’une politique de campagne, le conflit est résolu de manière déterministe à l’aide du même cadre de priorités et de stratégies, sans traitement spécifique supplémentaire.</p></li><li><p><strong>Mesurabilité.</strong> Comme les politiques de cohorte sont distinctes et activables individuellement, leur impact sur les taux de conversion, de clic et d’ajout au panier peut être mesuré indépendamment, comme pour toute autre politique du système.</p></li></ul><h2>À suivre dans cette série</h2><p>Le prochain article explore une autre dimension du plan de contrôle gouverné : la manière dont les boosts liés à la marge et à la popularité peuvent être ajustés requête par requête via des politiques, transformant ainsi l’optimisation économique en décision de gouvernance plutôt qu’en configuration statique.</p><p>Voir la partie 7 : Optimisation économique gouvernée par les requêtes : boosts de marge et de popularité par requête</p><h2>Mettre en pratique la recherche e-commerce réglementée</h2><p>Les mécanismes de personnalisation décrits dans cet article (boost basé sur l’historique d’achat individuel et activation de politiques adaptées aux cohortes) ont été conçus et développés par Elastic Services Engineering dans le cadre de notre accélérateur reproductible de recherche e-commerce. Les deux mécanismes s’intègrent à l’architecture de plan de contrôle gouverné décrite tout au long de cette série. Contactez <a href="https://www.elastic.co/consulting">Elastic Professional Services</a>.</p><h2>Rejoignez la discussion</h2><p>Avez-vous des questions sur la gouvernance de la recherche, les stratégies de récupération ou l'architecture de recherche e-commerce ? Participez à la <a href="https://discuss.elastic.co/">discussion élargie de la communauté Elastic</a>.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-personalized-search-governed-ecommerce</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-personalized-search-governed-ecommerce</guid>
    <category><![CDATA[Opérations]]></category>
    <dc:creator><![CDATA[Alexander Marquardt,Honza Král,Taylor Roy]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte3979255ddfc7f45/6a17e25ffaa913812f93c7cb/92c517a2e7b36122a18feee317a0215981b62b6b-720x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Mon, 11 May 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Percolateur Elasticsearch pour la gouvernance de la recherche e-commerce : traduire les requêtes ambiguës en stratégies de récupération contrôlée]]></title>
    <description><![CDATA[Découvrez comment utiliser le percolateur Elasticsearch pour mettre en œuvre la gouvernance de la recherche. Dans cet article, nous présentons les modèles nécessaires à la création d'un moteur de politiques gouverné en production et à l'élaboration d'une stratégie de récupération contrôlée.]]></description>
    <content:encoded><![CDATA[<p>Cet article propose une analyse technique approfondie de l'implémentation Elasticsearch de l'architecture du plan de contrôle décrite dans la <a href="http://elastic.co/search-labs/blog/ecommerce-search-governance-control-plane-architecture">partie 3</a>, montrant comment l'élaborer à l'aide du percolateur Elasticsearch. Il décrit les modèles utilisés pour mettre en œuvre un moteur de politique déterministe et gouverné en production.</p><h2><strong>De l'architecture à la mise en œuvre</strong></h2><p>L'architecture du plan de contrôle a été décrite dans la <a href="http://elastic.co/search-labs/blog/ecommerce-search-governance-control-plane-architecture">partie 3</a> : la correspondance inverse en tant que primitive de recherche, les documents de politique qui séparent la correspondance de l'action et les transformations en cascade qui composent plusieurs politiques en un seul plan d'exécution. Le présent article présente de manière pratique la fonctionnalité d'Elasticsearch qui sous-tend la recherche de politiques, à savoir la <a href="https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-percolate-query">requête percolateur</a>.</p><p>Le percolateur est parfaitement adapté à la gouvernance, car il inverse le sens de la recherche exactement comme l'exige un plan de contrôle. Cet article présente la mise œuvre étape par étape, en commençant par une explication claire du fonctionnement du percolateur et de son importance, puis en abordant la conception des index, le stockage des politiques, l'évaluation au moment de la requête et la composition de plusieurs politiques.</p><h2><strong>Fonctionnement de la recherche normale</strong></h2><p>Un système e-commerce peut être appelé à traiter des centaines de milliers, voire des millions de documents produit contenant des champs tels que <code>title</code> <code>category</code>et <code>price</code>. Lorsqu'un utilisateur recherche les documents correspondants, Elasticsearch doit comparer la chaîne de recherche de l'utilisateur à un ou plusieurs champs stockés dans ces documents produit. L'analyseur par défaut d'Elasticsearch, l'<a href="https://www.elastic.co/docs/reference/text-analysis/analysis-standard-analyzer">analyseur standard</a>, met le texte en minuscules et le divise en tokens. Une recherche sur "oranges" correspond à "Oranges" en raison de la casse minuscule. Avec un analyseur sensible à la version linguistique qui comprend la racinisation, elle correspond également à "orange", car les deux formes se réduisent à la même racine. Par exemple, la <a href="https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-match-query">requête de correspondance</a> suivante renvoie les documents qui contiennent "orange" ou "oranges" dans leur champ <code>“title”</code>.</p>POST products/_search
{
  "query": {
    "match": {
      "title": "oranges"
    }
  }
}<p>Ainsi, pour la requête ci-dessus, Elasticsearch renvoie les documents produit dont le champ <code>title</code> correspond à "oranges", qui peuvent inclure des résultats tels que "Configure à l'orange", "Jus d'orange", "Oranges juteuses", "Marmelade d'orange", etc. À noter qu'Elasticsearch est couramment utilisé pour comparer une chaîne de recherche à des documents et pour renvoyer les documents qui correspondent à la chaîne de recherche.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt806e1c8c115bc9b6/6a170dba67045b634645c266/ba758f25616f2106d245ce0d47926c174766e028-642x318.png" alt="Diagramme comparant une chaîne de recherche entrante aux titres de produits enregistrés, montrant des correspondances pour trois titres contenant le mot &quot;orange&quot; et aucune correspondance pour deux titres qui ne le contiennent pas." /><h2><strong>Le problème de gouvernance : trouver des politiques pertinentes avant de rechercher des produits</strong></h2><p>Comme indiqué dans les <a href="https://www.elastic.co/search-labs/blog/series/governed-search-patterns">parties 1 à 3</a>, un système de recherche gouverné n'envoie pas la chaîne de recherche de l'utilisateur directement au catalogue de produits. Il vérifie d'abord si des politiques s'appliquent à cette chaîne de recherche.</p><p>Un détaillant décide que lorsqu'un visiteur recherche exactement le mot "oranges", les résultats doivent être limités à la catégorie "Oranges", en excluant le jus d'orange, la confiture d'orange et le soda à l'orange. Cette décision opérationnelle est enregistrée sous forme de politique. Lorsqu'un utilisateur tape "oranges", le plan de contrôle doit trouver cette politique, en lire les instructions et modifier la recherche dans le catalogue de produits en conséquence. Pour ce faire, le plan de contrôle doit déterminer quelles politiques enregistrées sont pertinentes pour cette chaîne de recherche.</p><p>Dans un déploiement d'entreprise, on peut trouver des centaines, voire des milliers de politiques de ce type. Les vérifier une par une à l'aide d'une logique conditionnelle (if/else) est l'antimodèle de la couche applicative comme décrit dans la <a href="http://elastic.co/search-labs/blog/ecommerce-search-governance-zero-deploy">partie 2</a>. Il faut un moyen de stocker toutes ces politiques dans un index et de trouver instantanément celles qui correspondent à une chaîne de recherche donnée. C'est là qu'intervient le percolateur.</p><h2><strong>Inverser le sens : le percolateur</strong></h2><p>Nous avons déjà mentionné que, dans le cadre d'une recherche classique, Elasticsearch sert généralement à comparer une chaîne de recherche à des documents et à renvoyer les documents qui contiennent cette chaîne.</p><p>Le percolateur inverse ce processus. Avec un percolateur, vous disposez d'un index où chaque document stocke un modèle de requête, puis une chaîne de recherche entrante est comparée à ces requêtes stockées afin de déterminer quel modèle de requête stocké a été déclenché.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1e7e2966bf46474d/6a170dbba929cf500aae0a57/1e6348531d1c0be57b385f51d248488cf58489ff-642x279.png" alt="Diagramme illustrant plusieurs modèles de requêtes enregistrés, testés indépendamment les uns des autres par rapport à une chaîne de recherche entrante, le mot &quot;oranges&quot; produisant une correspondance tandis que tous les autres modèles ne renvoient aucune correspondance." /><p>Quant à la gouvernance, les "modèles de requêtes enregistrés" sont des politiques. Chacune d'entre elles contient un modèle décrivant le type de chaîne de recherche auquel elle doit correspondre. Par exemple, la chaîne de recherche correspond-elle exactement à "oranges", ou contient-elle "huile d'olive" ? La chaîne entrante est le texte de recherche de l'utilisateur reçu lors de la requête et qui doit être comparé à tous les modèles de politiques enregistrés. Ce sujet est abordé dans une <a href="https://youtu.be/Ap5K2Y00Xjc?t=246">vidéo PRISM connexe à 04:09</a>.</p><h2>Étape par étape : comment une recherche sur "oranges" trouve la politique correspondante</h2><h3>La politique</h3><p>Un détaillant a créé une politique qui s'applique lorsqu'un utilisateur lance une recherche sur le mot "oranges ", sans aucun autre terme. Une fois la correspondance établie, le reste du document contient les règles que le plan de contrôle utilisera pour construire la requête Produit ; dans cet exemple, l'une des règles consiste à limiter (filtrer) les résultats à la catégorie Fruits.</p>{
  "percolator": {
    "match_phrase": { "query": "START oranges END" }
  },
  "rule_type": "filter",
  "rule_args": {
    "filters": [
      {
        "field": "categories",
        "values": ["Fruits"],
        "mode": "hard_filter",
        "on_conflict": "soft_boost",
        "on_conflict_boost_weight": 1.0
      }
    ]
  },
  "priority": 0,
  "enabled": true
}<p>Le champ <code>percolator</code> contient le modèle qui définit quand cette politique doit s'activer. Dans ce cas, cela correspond à l'expression <code>"START oranges END"</code>. Les champs <code>rule_type</code> et <code>rule_args</code> définissent l'action que la politique doit effectuer en cas de déclenchement. Les jetons <code>START</code> et <code>END</code> sont des repères de délimitation, que nous expliquerons prochainement.</p><p>Vous pouvez voir comment une politique est rédigée dans l'interface utilisateur PRISM Studio à <a href="https://youtu.be/Ap5K2Y00Xjc?t=172">2:52 de la vidéo PRISM associée</a>.</p><h3>L'utilisateur lance une recherche</h3><p>Un acheteur tape "oranges" dans la barre de recherche.</p><h3>Le plan de contrôle vérifie les politiques correspondantes avec précision</h3><p>Avant de rechercher dans le catalogue de produits, le plan de contrôle intercepte la chaîne de recherche de l'utilisateur, l'encapsule dans des repères de délimitation et l'envoie au percolateur :</p>POST policies/_search
{
  "query": {
    "percolate": {
      "field": "percolator",
      "document": {
        "query": "START oranges END"
      }
    }
  }
}<p>La chaîne <code>"START oranges END"</code> est comparée à tous les modèles de politique enregistrés. En interne, Elasticsearch applique ces modèles à cette chaîne et renvoie ceux qui correspondent. C'est le principe du percolateur. La chaîne de recherche de l'utilisateur a été comparée à tous les modèles de politique enregistrés, et ceux qui correspondaient ont été renvoyés. Pas de condition "il/else". Pas d'évaluation séquentielle. L'index gère la correspondance.</p><h3>Le plan de contrôle applique la politique</h3><p>Le plan de contrôle analyse les actions des politiques correspondantes. La politique ci-dessus indique au plan de contrôle de limiter les résultats à la catégorie Fruits. Le plan de contrôle construit la requête Elasticsearch finale sur le catalogue de produits comme suit :</p>POST products/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "title": "oranges" } }
      ],
      "filter": [
        { "terms": { "categories": ["Fruits"] } }
      ]
    }
  }
}<p>L'utilisateur a cherché "oranges". Le catalogue de produits reçoit une requête pour "oranges" limitée à la catégorie Fruits. En raison de cette contrainte, le jus d'orange, la marmelade d'orange et le soda à l'orange sont exclus.</p><h3>Pourquoi "marmelade d'orange" ne déclenche PAS la politique sur les oranges</h3><p>Supposons qu'un autre utilisateur lance une recherche sur "marmelade à l'orange". Le plan de contrôle encadre la chaîne et filtre : <code>"START orange marmalade END"</code>. Le modèle de politique pour les oranges est <code>match_phrase: "START oranges END"</code>. La politique pour les oranges ne correspondant pas, elle n'est pas appliquée et les résultats ne sont pas limités à la catégorie Fruits.</p><p>Telle est la finalité des repères de délimitation <code>START</code> et <code>END</code>. Sans eux, une politique qui met en correspondance le mot "oranges" pourrait s'appliquer par erreur à une requête comme "marmelade d'oranges". En encadrant la chaîne de recherche de l'utilisateur avec <code>START</code> et <code>END</code> et en incluant ces repères dans le modèle de la politique, nous nous assurons que la politique ne s'active que lorsque "oranges" est la chaîne de recherche complète, sans autres termes. Cela correspond aux attentes des acheteurs et du détaillant.</p><h2>Deuxième politique : "huile d'olive" sur le champ lexical racine</h2><p>Toutes les politiques ne nécessitent pas une correspondance exacte des chaînes de caractères. La politique "huile d'olive" correspondant à un champ racinisé, elle se déclenche indépendamment des variations mineures de la forme des mots :</p>{
  "percolator": {
    "bool": {
      "should": [
        { "match_phrase": { "query.stemmed": "START olive oil END" } }
      ]
    }
  },
  "rule_type": "filter",
  "rule_args": {
    "filters": [
      {
        "field": "categories",
        "values": ["Olive oils"],
        "mode": "hard_filter",
        "on_conflict": "soft_boost",
        "on_conflict_boost_weight": 1.0
      }
    ]
  },
  "priority": 300,
  "enabled": true
}<p>Le modèle de cette politique correspond à <code>query.stemmed</code> au lieu de <code>query</code>. Lorsque la chaîne de recherche de l'utilisateur arrive, elle est stockée dans un champ <code>query</code> (le texte exact) et dans un champ <code>query.stemmed</code> (analysé par un analyseur de racinisation qui réduit les mots à leur racine, "olives" et "olive" ayant la même racine, de même que "huiles" et "huile"). Le modèle de la politique est vérifié par rapport à la version racinisée de la chaîne, et s'applique donc quelles que soient les variations mineures de forme des mots.</p><p>Les repères de délimitation <code>START</code> et <code>END</code> fonctionnent également sur le champ racinisé, garantissant que cette politique ne s'active que lorsque "huile d'olive" est la chaîne de recherche complète, et non lorsqu'elle apparaît dans une partie d'un élément plus long.</p><p>La suite de cet article aborde les détails de mise en œuvre qui préparent cette solution à la mise en production : le mapping d'index prenant en charge les deux modes de correspondance, la manière dont les mises en évidence déterminent la suppression des expressions et le suivi des expressions utilisées, ainsi que la façon dont plusieurs politiques contradictoires s'intègrent dans un plan d'exécution unique.</p><h2><strong>Mapping de l'index des politiques</strong></h2><p>L'index des politiques nécessite un champ de percolation pour stocker les modèles de requêtes enregistrés et un champ texte reflétant la structure de la chaîne de recherche entrante sur laquelle le percolateur effectuera la comparaison. Le schéma ci-dessous est simplifié par souci de clarté. Un déploiement en production est plus complexe et utilise des analyseurs personnalisés pour gérer les repères de délimitation, la correspondance de modèles variables (par exemple, identifier que "moins de 4 $" contient une valeur monétaire) et d'autres types d'analyses.</p>PUT policies
{
  "mappings": {
    "properties": {
      "percolator": {
        "type": "percolator"
      },
      "query": {
        "type": "text",
        "fields": {
          "stemmed": {
            "type": "text",
            "analyzer": "stemming"
          }
        }
      },
      "rule_type": { "type": "keyword" },
      "rule_args": { "type": "object", "enabled": false },
      "priority": { "type": "integer" },
      "enabled": { "type": "boolean" }
    }
  }
}<p>L'index est nommé <code>policies</code>, car chaque document représente une politique gouvernée complète telle que définie dans la <a href="http://elastic.co/search-labs/blog/ecommerce-search-governance-zero-deploy">partie 2</a>. Cela inclut les critères de correspondance, l'action, la priorité et les métadonnées. Les champs <code>rule_type</code> et <code>rule_args</code> contiennent la composante "action" de la politique, c'est-à-dire les instructions que le plan de contrôle utilisera pour composer la requête à exécuter sur le catalogue de produits.</p><p>Le champ <code>query</code> correspond à la chaîne de caractères utilisée par le percolateur pour la recherche. Il existe deux variantes : une version exacte et une version racinisée. Lorsque la chaîne de recherche de l'utilisateur est reçue, elle est placée dans ce champ de l'index temporaire en mémoire. Les politiques correspondant à <code>query</code> voient la chaîne exacte ; les politiques qui correspondent à <code>query.stemmed</code> voient la version racinisée.</p><h2><strong>Percolation par mise en évidence, filtrage et tri</strong></h2><p>Les exemples simples ci-dessus illustrent des requêtes de percolation minimales. En pratique, le plan de contrôle ajoute la mise en évidence, filtre les politiques désactivées et trie les éléments par ordre de priorité :</p>POST policies/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "percolate": {
            "field": "percolator",
            "document": {
              "query": "START olive oil END"
            }
          }
        },
        {
          "term": { "enabled": true }
        }
      ]
    }
  },
  "highlight": {
    "fields": {
      "query": {
        "matched_fields": ["query.stemmed"]
      }
    }
  },
  "sort": [
    { "priority": { "order": "desc" } }
  ]
}<p>La configuration de mise en évidence utilise <code>"query"</code> comme clé de champ avec <code>"query.stemmed"</code> dans <code>matched_fields</code>. Cela indique à l'outil surligneur unifié d'<a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/highlighting">Elasticsearch</a> de renvoyer les mises en évidence sur le champ parent <code>query</code>, mais aussi de prendre en compte les correspondances du sous-champ <code>query.stemmed</code> pour déterminer les jetons à surligner. C'est ce qui permet à une politique de correspondance sur le champ racinisé de produire des séquences de mise en évidence précises sur le texte original, ce dont le plan de contrôle a besoin pour la suppression et le suivi des expressions consommées.</p><p>Le filtre <code>enabled: true</code> garantit que les politiques désactivées sont ignorées. Le paramètre de priorité <code>sort</code> garantit que les politiques prioritaires sont renvoyées en premier, afin que le plan de contrôle puisse les traiter dans le bon ordre pour les transformations en cascade. Le champ <code>highlight</code> est l'ajout le plus important ; il indique précisément quels mots de la chaîne de recherche de l'utilisateur ont déclenché chaque correspondance.</p><p>La réponse à une recherche "huile d'olive" peut ressembler à ce qui suit :</p>{
  "hits": {
    "hits": [
      {
        "_id": "en_2c3021c8",
        "_source": {
          "rule_type": "filter",
          "rule_args": {
            "filters": [
              {
                "field": "categories",
                "values": ["Olive oils"],
                "mode": "hard_filter",
                "on_conflict": "soft_boost",
                "on_conflict_boost_weight": 1.0
              }
            ]
          },
          "priority": 300
        },
        "highlight": {
          "query": ["&lt;em&gt;START olive oil END&lt;/em&gt;"]
        }
      }
    ]
  }
}<h2><strong>Pourquoi les points forts sont importants</strong></h2><p>Notez la mise en évidence dans la réponse : <code>"&lt;em&gt;START olive oil END&lt;/em&gt;"</code>. Elasticsearch nous indique précisément quels mots de la requête utilisateur ont déclenché la correspondance avec la politique. Ce n'est pas un simple détail. Les métadonnées mises en évidence influencent deux comportements essentiels en aval :</p><p><strong>Suppression d'expressions.</strong> Certaines politiques nécessitent la suppression du texte correspondant dans la chaîne de recherche avant la construction de la requête du catalogue de produits. Par exemple, une politique qui recherche l'expression "pas cher" la supprime et la remplace par un filtre de prix. La mise en évidence indique précisément la section de la chaîne de recherche concernée par la politique, de sorte que le système sait ce qu'il faut supprimer.</p><p><strong>Suivi des expressions consommées.</strong> Comme décrit dans la <a href="http://elastic.co/search-labs/blog/ecommerce-search-governance-control-plane-architecture">partie 3</a>, lorsque plusieurs politiques correspondent à la même chaîne de recherche, une politique de priorité supérieure peut supprimer des mots auxquels une politique de priorité inférieure correspond également. En comparant la mise en évidence de chaque politique par rapport à la chaîne de recherche actuelle (en évolution), le système peut détecter qu'une expression a été consommée et ignorer la politique de priorité inférieure. Cela empêche le double traitement et assure un comportement déterministe.</p><p>Pour en savoir plus sur le fonctionnement de la mise en évidence, consultez <a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/how-es-highlighters-work-internally">cet article</a>.</p><h2><strong>De la percolation au plan d'exécution</strong></h2><p>Le percolateur renvoie un ensemble de politiques correspondantes. Mais comme décrit dans la <a href="http://elastic.co/search-labs/blog/ecommerce-search-governance-control-plane-architecture">partie 3</a>, la recherche n'est que la moitié du processus. L'autre moitié consiste à composer ces correspondances en un plan d'exécution cohérent. Voici à quoi cela ressemble pour une requête concrète.</p><h3><strong>Exemple concret : "Chocolat pas cher" pendant une campagne de Noël</strong></h3><p>Supposons que le système ait deux politiques actives : la politique "Chocolat bon marché" (priorité 210) et la politique "Chocolats de Noël" (priorité 300), toutes deux décrites en détail dans la <a href="http://elastic.co/search-labs/blog/ecommerce-search-governance-control-plane-architecture">partie 3</a>.</p><p><strong>Étape 1 : Filtrer.</strong> L'utilisateur lance une recherche sur "chocolat pas cher". Le plan de contrôle encapsule la chaîne de recherche sous la forme <code>"START cheap chocolate END"</code> et l'envoie au percolateur. Deux politiques correspondent : le modèle de politique "Chocolat pas cher" correspond à l'expression "chocolat pas cher", et le modèle de politique "Chocolats de Noël" correspond à "chocolat" via le champ racinisé.</p><p><strong>Étape 2 : Trier par priorité.</strong> Le percolateur renvoie les deux politiques, triées par priorité dans l'ordre décroissant. La politique "Chocolats de Noël" (300) est traitée en premier, suivie de la politique "Chocolats pas chers" (210).</p><p><strong>Étape 3 : Appliquer la transformation en cascade.</strong> C'est le modèle <code>initial state → [Policy A] → state' → [Policy B] → state'' → execution plan</code> présenté dans la <a href="http://elastic.co/search-labs/blog/ecommerce-search-governance-control-plane-architecture">partie 3</a>.</p><p>La politique relative aux "Chocolats de Noël" (priorité 300) s'applique en premier :</p><ul><li><p>Ajoute un filtre de catégorie strict : "Aliments et boissons de Noël", "Friandises de Noël".</p></li><li><p>Ajoute un filtre de prix : moins de 7 $.</p></li><li><p>Ajoute un boost de catégorie "Calendriers de l'avent" (3x).</p></li></ul><p>La politique relative au "Chocolat pas cher" (priorité 210) s'applique ensuite à l'état modifié :</p><ul><li><p>Tente d'ajouter un filtre strict par catégorie : "Chocolats", "Chocolats au lait", mais la politique de Noël a déjà défini ce champ sur <code>on_conflict: override</code>, donc les catégories "Chocolat pas cher" sont exclues.</p></li><li><p>Tente d'ajouter un filtre de prix : 2 $, la politique de Noël est définie sur <code>on_conflict: restrict</code> pour le prix, et 2 $ est plus restrictif que 7 $, donc 2 $ l'emporte.</p></li><li><p>Supprime les termes "bon marché" de la chaîne de recherche.</p></li></ul><p><strong>Étape 4 : Créer la requête Elasticsearch.</strong> Le plan de contrôle assemble le plan d'exécution en une seule requête Elasticsearch sur le catalogue de produits :</p>POST products/_search
{
  "query": {
    "function_score": {
      "query": {
        "bool": {
          "must": [
            { "match": { "title": "chocolate" } }
          ],
          "filter": [
            { "terms": { "categories": ["Christmas foods and drinks", "Christmas sweets"] } },
            { "range": { "price": { "lt": 2 } } }
          ]
        }
      },
      "functions": [
        {
          "weight": 1
        },
        {
          "filter": { "terms": { "categories": ["Advent calendars"] } },
          "weight": 3
        }
      ],
      "score_mode": "sum",
      "boost_mode": "multiply"
    }
  }
}<p>La chaîne de recherche initiale était "chocolat pas cher". La requête qui aboutit au catalogue de produits est un plan de récupération contrôlé et adapté à l'intention : les termes "pas cher" sont intégrés et convertis en contrainte de prix, les résultats sont limités aux catégories saisonnières de Noël, les produits du calendrier de l'avent sont mieux référencés et le prix plafond reflète la valeur plus restrictive de la politique de priorité inférieure. Chaque transformation est déterministe, traçable et explicable.</p><p>Pour un aperçu rapide de la façon dont ces multiplicateurs interagissent avec le score BM25 de base, consultez la <a href="https://youtu.be/Ap5K2Y00Xjc?t=525">vidéo PRISM associée à 8:45</a> où ces boosts multiplicatifs sont abordés.</p><h2><strong>Pourquoi cette échelle</strong></h2><p>Le percolateur est efficace pour ce cas d'utilisation en raison de l'asymétrie : un système e-commerce d'entreprise peut comporter des millions de produits mais seulement des centaines ou des milliers de politiques de gouvernance. Le percolateur vérifie une chaîne de recherche entrante par rapport à cet ensemble de modèles de politique stockés, et non en analysant l'intégralité du catalogue de produits. Le coût est proportionnel au nombre de politiques, et Elasticsearch applique des optimisations internes (indexation des termes à partir de schémas de requête stockés, contournant la logique booléenne) afin d'assurer une correspondance rapide.</p><p>L'ajout d'une nouvelle politique revient à indexer un nouveau document. La désactivation d'une politique équivaut à une mise à jour de champ. Aucun changement de code, aucun déploiement, aucun redémarrage.</p><h2><strong>De la recherche à la récupération contrôlée</strong></h2><p>Le percolateur fournit la primitive de correspondance inverse rapide qui rend l'architecture du plan de contrôle évoquée dans la <a href="http://elastic.co/search-labs/blog/ecommerce-search-governance-control-plane-architecture">partie 3</a> pratique à grande échelle. Les politiques sont des données stockées et indexées, puis comparées efficacement aux chaînes de recherche entrantes. Le plan de contrôle compose les politiques de correspondance en un plan d'exécution gouverné grâce à la transformation en cascade et à la résolution des conflits par champ décrites dans la partie 3. Enfin, le moteur de recherche exécute ce plan d'exécution gouverné sur le catalogue de produits.</p><p>Résultat : un système qui permet à un détaillant de créer une nouvelle politique sans toucher au code de l'application, de la tester par rapport à des requêtes représentatives, de la promouvoir en production et de voir immédiatement ses effets. Le percolateur accélère la recherche de politique, le plan de contrôle rend la composition de politique déterministe, et le workflow gouverné sécurise l'ensemble du processus.</p><h2><strong>À suivre dans cette série</strong></h2><p>Le prochain article de cette série étend le plan de contrôle gouverné à de nouveaux territoires. Il introduit une <strong>architecture de recherche à plusieurs niveaux</strong>, expliquant comment orchestrer une récupération stricte, souple et sémantique tout en maintenant une pagination et des facettes stables.</p><h2><strong>Mettre en pratique la recherche e-commerce réglementée</strong></h2><p>Le plan de contrôle basé sur un percolateur décrit dans cet article, depuis les mappings d'index et les repères de délimitation jusqu'au suivi des expressions clés et à la composition de politiques en cascade, a été conçu par Elastic Services Engineering dans le cadre de nos accélérateurs de recherche e-commerce reproductibles. Chaque exemple de requête et chaque structure de politique présentés ici proviennent d'un système opérationnel validé à l'aide de catalogues de produits à l'échelle de l'entreprise.</p><p>Si vous souhaitez implémenter un plan de contrôle gouverné, basé sur des politiques sur Elasticsearch, les services Elastic peuvent vous y aider plus rapidement. Contactez <a href="https://www.elastic.co/consulting">Elastic Professional Services</a>.</p><h2>Rejoignez la discussion</h2><p>Avez-vous des questions sur la gouvernance de la recherche, les stratégies de récupération ou l'architecture de recherche e-commerce ? Participez à la <a href="https://discuss.elastic.co/">discussion élargie de la communauté Elastic</a>.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-percolator-search-governance</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-percolator-search-governance</guid>
    <category><![CDATA[Opérations]]></category>
    <dc:creator><![CDATA[Alexander Marquardt,Honza Král,Taylor Roy]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt19fcc31ad093ad30/6a170dbd7d8d67301070e799/5e485cdd52d78419ff0ac30a4192b953f6d70c61-1280x720.png" length="0" type="image/png"/>
    <pubDate>Mon, 04 May 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Élaboration d'un plan de contrôle pour gérer la recherche dans le commerce électronique]]></title>
    <description><![CDATA[Comment mettre en place un plan de contrôle géré pour le commerce électronique qui intègre des politiques de recherche conflictuelles en un seul plan d'exécution (sans modification du code).]]></description>
    <content:encoded><![CDATA[<p><a href="https://www.elastic.co/search-labs/blog/ecommerce-search-governance-improve-retrieval">Les parties 1</a> et <a href="https://www.elastic.co/search-labs/blog/ecommerce-search-governance-zero-deploy">2</a> de cette série ont démontré pourquoi la recherche e-commerce nécessite une <em>couche de gouvernance</em>, une couche de décision entre la requête utilisateur et le moteur de recherche. Cette couche classe l'intention, applique les contraintes et oriente la requête vers la stratégie de recherche appropriée (par exemple, BM25, sémantique ou hybride). Cet article explique comment construire cette couche à l'aide d'une architecture simple : les politiques d'interprétation des requêtes sont stockées sous forme de documents et récupérées lors de l'exécution de la requête grâce à une correspondance inverse rapide. Comme les nouvelles politiques de recherche (par exemple, "mettre en avant la marque X" ou "afficher uniquement la catégorie Y") ne nécessitent aucune modification du code, la couche de routage reste stable malgré l'évolution des politiques et garantit la sécurité des moteurs de recherche dans les environnements critiques. Si vous souhaitez voir le résultat final de cette architecture avant de poursuivre votre lecture, regardez cette vidéo : <a href="https://www.youtube.com/watch?v=e1GuL9CYWAk">Fixing Search Relevance in Seconds: Introducing PRISM</a>.</p><h2>Pourquoi l'interprétation des requêtes est souvent un défi</h2><p>Le stockage des politiques sous forme de code (blocs if/else dans la couche applicative) génère des dizaines de milliers de lignes de logique fragile, dépourvue de tout système d'indexation permettant une récupération efficace des règles au moment de la requête. L'itération est lente (un changement de comportement de requête unique peut nécessiter un cycle de déploiement de six semaines), la responsabilité n'est pas clairement établie (pourquoi les résultats ont-ils changé ?) et les utilisateurs métier ne peuvent pas modifier le comportement de recherche sans l'intervention de l'ingénierie. Ceci est illustré à gauche dans l'image suivante :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb84f89f4d9029df7/6a170f806234e077cddb1ab6/4e2cd5244ef8b9a05af6337a4825252f321a9a43-1377x768.png" alt="Image comportant deux titres, &quot;Politiques sous forme de code&quot; à gauche et &quot;Politiques sous forme de données&quot; à droite. La partie gauche montre des blocs de code conditionnel définissant des règles de traitement des requêtes avec des remarques sur le déploiement, les cycles de changement et l'évaluation séquentielle. Le côté droit présente les objets de politique JSON avec leurs titres, leurs critères de correspondance, leurs actions, leurs filtres et leurs priorités, ainsi que des remarques concernant leur stockage dans un index Elasticsearch, leur comportement lors des mises à jour et la correspondance indexée." /><p>Le stockage des politiques sous forme de données dans un index Elasticsearch est illustré à droite de l'image ci-dessus. Cette approche résout tous les problèmes liés à une logique de résolution des requêtes codée en dur. Cependant, pour que cela fonctionne, il faut pouvoir déterminer rapidement quelles politiques correspondent à la requête de l'utilisateur et comment les conflits doivent être résolus. C'est là qu'intervient le plan de contrôle géré.</p><h2>Le modèle du plan de contrôle</h2><p>Un plan de contrôle géré s'intercale entre la requête brute de l'utilisateur et la récupération dans Elasticsearch. Il reçoit le texte de l'utilisateur en entrée, et sa sortie est un plan d'exécution qui inclut des filtres, des pondérations et des décisions de routage pour la récupération.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0585c90830d63d02/6a170f82964cea7a5908bc8b/5562da5de521f3c83ed55a13e9be87ca7fa70109-546x489.png" alt="Schéma illustrant deux flux de recherche via un plan de contrôle géré : l'un dans lequel une requête textuelle portant sur le mot &quot;oranges&quot; est reformulée avec une contrainte de catégorie avant la recherche de produits, et l'autre dans lequel une requête sémantique portant sur &quot;cadeau pour grand-père&quot; est reformulée et acheminée afin de récupérer les produits correspondants dans un catalogue de produits." /><p>Un pipeline du plan de contrôle se compose de ces éléments :</p><ol><li><p><strong>Requête utilisateur</strong> : l'utilisateur saisit une chaîne de caractères indiquant ce qu'il recherche, par exemple "oranges" ou "cadeau pour grand-père".</p></li><li><p><strong>Recherche de politique</strong> : mise en correspondance de la requête utilisateur avec l'index des politiques.</p></li><li><p><strong>Renvoi des politiques correspondantes</strong> : Les politiques correspondant à la requête utilisateur sont renvoyées à partir de l'index des politiques.</p></li><li><p><strong>Application de la politique</strong> : le plan de contrôle analyse ces politiques renvoyées et compose les politiques correspondantes en un plan d'exécution cohérent unique comprenant des filtres, des boosts, des remplacements et des garde-fous, et qui applique la méthode de récupération appropriée (par exemple, lexicale, sémantique ou hybride).</p></li><li><p><strong>Exécution</strong> : la requête Elasticsearch modifiée <em>sensible aux intentions</em> est transmise à l'application pour être exécutée sur un index de catalogue de produits.</p></li><li><p><strong>Explication (optionnel)</strong> : en plus de créer une requête qui fournit des résultats alignés sur l'activité et l'intention, le plan de contrôle fournit une charge utile d'explicabilité optionnelle pour montrer quelles politiques ont été déclenchées et comment elles ont été combinées.</p></li></ol><p>Pour déterminer les politiques à appliquer à la chaîne de recherche d'un utilisateur, il faut utiliser une primitive de correspondance inverse rapide, que nous résolvons à l'aide de la <a href="https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-percolate-query">requête percolateur</a>. Après avoir récupéré les politiques pertinentes, la combinaison de plusieurs politiques correspondantes en un plan d'exécution unifié nécessite un framework de jugement : priorités, stratégies de conflit, suivi des expressions utilisées et transformations en cascade qui appliquent les politiques en séquence plutôt qu'indépendamment. De plus, il convient de sélectionner la technologie de récupération la plus appropriée (par exemple, <a href="https://www.elastic.co/elasticon/conf/2016/sf/improved-text-scoring-with-bm25">BM25</a> pour "oranges" ou <a href="https://www.elastic.co/docs/solutions/search/semantic-search">recherche sémantique</a> pour "cadeau pour grand-père").</p><h2>Recherche de politique : vérification de la requête avant la recherche de produits</h2><p>Lorsqu'un client saisit une requête, un système de recherche doté d'une couche de contrôle contrôlée ne l'envoie pas directement au catalogue de produits. La requête est d'abord vérifiée au regard d'un ensemble de règles prédéfinies, puis modifiée pour correspondre à son intention et aux priorités de l'entreprise.</p><h3>Structure de la politique</h3><p>Chaque politique est un simple document qui définit deux choses :</p><ul><li><p><strong>Critères de correspondance</strong> : Le texte de la requête qui doit déclencher l'application de cette politique. Ce peut être une expression exacte, un seul mot, un schéma ou une combinaison des deux.</p></li><li><p><strong>Action</strong> : quoi faire lorsque la politique est déclenchée. Cela peut consister à appliquer un filtre de catégorie, exclure des produits, extraire une contrainte de prix ou modifier la stratégie de récupération.</p></li></ul><p>Le système identifie toutes les politiques correspondantes, les organise en un plan d'exécution, puis lance la recherche de produits. Ensemble, les politiques agissent comme un vendeur compétent qui comprend vos besoins et vous guide vers le bon rayon.</p><h3>Le modèle de politique</h3><p>Les premiers articles de cette série ont présenté des exemples d'application des politiques : la restriction de la recherche d'"oranges" à la catégorie des fruits et légumes, la prise en compte de l'exclusion de l'option "sans cacahuètes" et l'orientation de la recherche "cadeau pour grand-père" vers une recherche sémantique. Le principe architectural fondamental est que, dans chaque cas, la requête est vérifiée par rapport aux politiques enregistrées avant le début de la recherche de produits. Ces politiques déterminent les contraintes à appliquer, le texte à modifier et la stratégie de recherche à utiliser. La requête sur le catalogue de produits intervient après l'application des politiques et la création d'une nouvelle requête réécrite.</p><h3>Pourquoi c'est rapide</h3><p>Un système de commerce électronique d'entreprise peut comporter des millions de produits, mais seulement quelques centaines ou milliers de politiques. La recherche de politiques s'effectue dans un index restreint et ciblé, et non dans le catalogue complet des produits, ce qui la rend rapide. De plus, comme les politiques sont stockées dans leur propre index, un responsable merchandising qui ajoute une nouvelle politique n'a pas besoin de modifier le code de l'application, et un ingénieur qui optimise la recherche de produits n'a pas besoin de modifier l'index des politiques. Ces deux aspects évoluent indépendamment.</p><p>Les exemples ci-dessus décrivent ce qui se passe sur le plan conceptuel. Sous le capot, la recherche de politique est mise en œuvre à l'aide du type de <a href="https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-percolate-query">requête percolator</a> d'Elasticsearch, spécialement conçu pour ce type de schéma : faire correspondre un texte entrant à un ensemble de requêtes stockées. <a href="https://www.elastic.co/search-labs/blog/elasticsearch-percolator-search-governance">La quatrième partie</a> de cette série propose une exploration pratique et approfondie de l'implémentation du percolateur, notamment les mappings d'index, les marqueurs de délimitations et le suivi des expressions par mise en évidence. Le mécanisme de recherche étant traité en détail dans la quatrième partie, examinons maintenant le contenu d'un document de politique et la manière dont le plan de contrôle rassemble plusieurs politiques en un seul plan d'exécution.</p><h2>Exemples de politiques</h2><p>Maintenant que nous avons vu le rôle conceptuel des politiques, examinons leur contenu concret. Les deux politiques ci-dessous ont été conçues pour être intentionnellement conflictuelles, ce qui illustrera le système de résolution des conflits décrit dans les sections suivantes.</p><h3>Chocolat pas cher</h3><p>La politique ci-dessous détecte si un utilisateur a effectué une recherche contenant l'expression "chocolat pas cher". Le cas échéant, les résultats sont limités aux catégories "Chocolats" et "Chocolats au lait". Cette règle applique également un filtre de prix de 2 $. Notez par ailleurs que cette règle a une priorité de 210 ; nous y reviendrons lors de notre discussion plus approfondie sur la résolution des conflits.</p><p>Les paramètres de mode de filtrage et de stratégie de gestion des conflits présentés ici (hard_filter, soft_boost, restrict, override) sont expliqués en détail dans la section ci-dessous relative à la résolution des conflits.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltada4d46e2ab26208/6a170f836f7f04f91f914924/bbcd66b20fc3aa861b5880ca67daf8e809698717-1002x890.png" alt="Interface affichant une configuration de règle avec une expression de correspondance pour &quot;chocolat bon marché&quot;, des filtres de catégorie et de prix, un champ de suppression d'expression et des paramètres de priorité." /><p>Lorsque la politique ci-dessus est activée, une recherche de "chocolat bon marché" respecte le filtre prix de 2 $ et limite les résultats aux catégories "Chocolats" et "Chocolats au lait". Voici des exemples de résultats :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt368bdfbb9a6e5a5e/6a170f8566c4f975a1f8c10f/3f373af9a985864315d7639440a416e45a882a1b-1133x1146.png" alt="Interface affichant une configuration de règle avec une expression de correspondance pour &quot;chocolat bon marché&quot;, des filtres de catégorie et de prix, un champ de suppression d'expression et des paramètres de priorité." /><h3>Chocolat de Noël</h3><p>La politique ci-dessous est un exemple de politique applicable à Noël. Elle limite les résultats aux catégories "Produits alimentaires et boissons de Noël" et "Confiseries de Noël", met en avant les produits appartenant également à la catégorie "Calendriers de l'Avent" et applique un filtre de prix inférieur à 7 $ pour privilégier les articles saisonniers abordables. Notez également que cette politique a une priorité de 300. Nous y reviendrons plus en détail lors de notre discussion sur la résolution des conflits.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta3428d211f2d8304/6a170f86839dfa0049dcffb3/8f1179342d0e05cf78266d142b046021a3694368-1007x941.png" alt="Capture d'écran d'une interface de requête de règle Elasticsearch montrant une requête match_phrase pour &quot;chocolat&quot;, des règles de filtrage basées sur les catégories et le prix, des options de gestion des conflits et des paramètres de priorité des règles." /><p>Lorsque la politique ci-dessus est activée sans aucune politique contradictoire, une recherche de "chocolat" respecte le filtre de prix de 7 $ et limite les résultats aux catégories "Produits alimentaires et boissons de Noël" et "Confiseries de Noël", tout en mettant en avant les produits étiquetés "Calendriers de l'avent". Des exemples de résultats sont présentés ci-dessous :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0e7f1fe91b2cadcd/6a170f8866c4f90b0af8c113/662b0e40cb3a9291c17816c33169e9ff5b68f98d-1129x1085.png" alt="Page de résultats de recherche affichant une requête pour &quot;chocolat&quot; avec des filtres de catégorie et de marque à gauche et une liste de calendriers de l'avent au chocolat avec images, prix, catégories et descriptions à droite." /><h2>Combiner des politiques concordantes</h2><p>La recherche de politique décrite plus haut n'est qu'une partie du processus. L'autre partie concerne ce qui se passe lorsque plusieurs politiques correspondent à la même requête.</p><p>Dans tout déploiement d'une certaine envergure, une seule requête déclenche systématiquement plusieurs politiques à la fois. L'expression "chocolat bon marché" correspondra aux deux politiques que nous avons présentées plus haut. Chaque politique est correcte prise isolément. Le défi consiste à les combiner en un seul plan d'exécution cohérent, sans contradictions, sans double comptage et sans qu'une politique n'annule silencieusement l'action d'une autre.</p><p>Ce n'est pas un problème de recherche, mais un problème de jugement. Le système doit décider si :</p><ul><li><p><strong>Ordre d'application</strong> : si une politique de négation supprime "sans cacahuètes" de la requête, la politique de prix voit-elle toujours le texte original ou le texte modifié ?</p></li><li><p><strong>Conflits de filtres</strong> : si deux politiques fixent des plafonds de prix différents, laquelle prévaut ? La politique perdante est-elle silencieusement supprimée ou se transforme-t-elle progressivement en soft boost ?</p></li><li><p><strong>Propriété des expressions</strong> : si deux polices portent sur le même mot et que la première l'a déjà consommé, la deuxième doit-elle continuer à l'utiliser ?</p></li></ul><p>Une implémentation simple (appliquer toutes les politiques correspondantes indépendamment, puis fusionner les résultats) dysfonctionne dès que les politiques interagissent. L'architecture nécessite un modèle explicite de la composition des politiques. Ce modèle est présenté dans les deux sections suivantes : un framework de priorisation et de résolution des conflits, et un modèle de transformation en cascade qui rend l'interaction des politiques déterministe.</p><p>L'idée clé est que l'application d'une politique n'est pas un ensemble d'opérations indépendantes, mais une transformation en cascade. Chaque politique reçoit l'état de réécriture produit par toutes les politiques de priorité supérieure et le transforme à nouveau :</p><p>État initial → [Politique A] → état' → [Politique B] → état'' → ... → plan d'exécution</p><p>L'état contient le texte de la requête réécrit, les filtres accumulés, l'intention actuelle et toutes les extensions de synonymes. Une politique de haute priorité peut supprimer du texte de la requête, et chaque politique suivante traite la requête modifiée et non la requête initiale. Le contexte s'accumule. L'ordre est important.</p><h2>Priorité et résolution des conflits : le déterminisme est important</h2><p>Les stratégies de résolution de conflits spécifiques relèvent d'un choix de conception. Différentes organisations peuvent gérer les conflits différemment en fonction de leurs besoins opérationnels. L'approche suivante illustre le type de framework de jugement nécessaire à un plan de contrôle. L'important n'est pas tant ces stratégies spécifiques, mais le fait que le système dispose de stratégies explicites et déterministes, plutôt que de laisser les conflits se résoudre par des interactions imprévisibles.</p><h3>Ordre de priorité</h3><p>Les politiques sont triées par priorité (de la plus élevée à la plus basse). Lorsqu'une même requête est traitée par plusieurs politiques, elles sont appliquées par ordre de priorité. Si deux politiques tentent de définir le même champ de filtre, la stratégie déclarée par la politique ayant la priorité la plus élevée pour ce champ prévaut. En cas de déclenchement de plusieurs politiques de même priorité, la politique ayant l'identifiant le plus élevé est prioritaire (comme si elle disposait d'une priorité supérieure) ; ce choix garantit un comportement déterministe en cas de conflit.</p><h3>Résolution par champ, pas par politique</h3><p>Un principe de conception essentiel : la résolution des conflits s'effectue par champ (par exemple, marque, catégorie ou description), et non par politique. Lorsque deux politiques produisent des filtres qui se chevauchent sur certains champs, seuls ces champs sont concernés par la stratégie de résolution des conflits, et cette stratégie est définie par la politique prioritaire correspondante. Les champs non conflictuels des deux politiques restent inchangés.</p><p>Ceci est important, car une approche par politique obligerait le système à accepter ou à rejeter une politique entière dès qu'un seul de ses champs est en conflit.</p><p>La résolution par champ préserve la quantité maximale d'informations utiles sur les contraintes.</p><h3>Trois paramètres par champ de filtre</h3><p>Chaque champ de filtre dans une politique possède trois paramètres indépendants :</p><p><strong>Mode de filtrage</strong> : comment le filtre est appliqué lorsqu'il n'y a pas de conflit.</p><ul><li><p><code>hard_filter</code> (par défaut) : appliqué comme une clause <a href="https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-bool-query#score-bool-filter">Elasticsearch </a><a href="https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-bool-query#score-bool-filter"><code>bool.filter</code></a>. Ceci permet d'exclure complètement les produits non pertinents. Par exemple, limiter une recherche sur "oranges" à la catégorie "fruits et légumes" élimine les résultats tels que le jus d'orange et marmelade d'orange. Les documents non pertinents sont totalement exclus des résultats.</p></li><li><p><code>soft_boost</code>: appliqué comme un poids <a href="https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-function-score-query">Elasticsearch </a><a href="https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-function-score-query"><code>function_score</code></a> avec un <code>boost_weight</code> configurable. Les documents correspondants reçoivent un boost de classement, mais les documents non correspondants ne sont pas exclus. C'est utile pour promouvoir une marque, par exemple, sans exclure d'autres marques.</p></li></ul><h3>Stratégie de conflit</h3><p>Ce qui se passe lorsqu'une politique de moindre priorité définit le même champ :</p><ul><li><p><code>override</code>: la valeur de cette politique prioritaire l'emporte ; la valeur de priorité inférieure est complètement supprimée. Valable pour tous les types de champs.</p></li><li><p><code>restrict</code>: Prenez la valeur numérique la plus restrictive (par exemple, le plafond inférieur pour le prix__max, the higher floor for price__min). Valable uniquement pour les champs de plage numériques.</p></li><li><p><code>merge</code>: combine les deux valeurs en une union. Valable uniquement pour les champs non numériques.</p></li><li><p><code>soft_boost</code>: convertir le filtre conflictuel en un poids <code>function_score</code> avec un <code>boost_weight</code> configurable au lieu d'un filtre strict. Pour plus de détails sur le boosting de function_score, consultez <a href="https://www.elastic.co/search-labs/blog/bm25-ranking-multiplicative-boosting-elasticsearch">Influencer le classement BM25 avec l'optimisation multiplicative dans Elasticsearch</a>. Ceci n'est valable que pour les champs de non-négation.</p></li></ul><p><strong>Valeur</strong> : la valeur réelle du filtre (par exemple, une liste de catégories, un seuil de prix).</p><p><strong>Stratégies par type de champ</strong> : les stratégies ne sont pas toutes adaptées à tous les types de champs. Par exemple, une exclusion étant par nature binaire, elle ne peut pas recevoir un soft boost. Le tableau suivant montre quelles stratégies sont disponibles pour chaque type de champ :</p><p>Type de champ</p><p>Stratégies disponibles</p><p>Par défaut</p><p>Champs de négation (__not, __match__not)</p><p>remplacer, fusionner</p><p>override</p><p>Champs numériques (__max, __min, __gt, __lt)</p><p>restrict, override, soft_boost</p><p>restrict</p><p>Tous les autres champs (mot-clé, texte)</p><p>soft_boost, override, merge</p><p>soft_boost</p><p>Le paramètre soft_boost ne peut pas être appliqué aux champs de négation, car les exclusions sont binaires. Convertir "ne jamais afficher les conserves" en "préférer légèrement les produits non en conserve" modifie fondamentalement la sémantique ; un produit de la catégorie "conserves" apparaîtrait toujours, mais légèrement moins bien classé, ce qui annule l'intérêt de l'exclusion.</p><h2>Un exemple concret : chercher du "chocolat pas cher" lors d'une campagne de Noël</h2><p>Supposons qu'un commerçant ait créé les deux politiques relatives au chocolat que nous avons présentées précédemment : une politique de priorité inférieure pour le chocolat bon marché et une autre de priorité supérieure qui sera activée pendant la période de Noël. Si ces deux politiques sont activées, leur combinaison dépend du mode de filtrage et de la stratégie de gestion des conflits de la politique prioritaire. Dans ce cas, elles seront combinées comme suit :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf930b42611a6126c/6a170f8aacf088ae28be9c1b/0405e193522172bde283180df96ed3651178fafc-529x447.png" alt="Capture d'écran montrant un pipeline de transformation où une requête initiale &quot;chocolat pas cher&quot; est modifiée par de multiples règles, notamment l'ajout de filtres de catégorie et de prix, le comportement de résolution des conflits, les priorités des règles et une requête transformée finale de &quot;chocolat&quot;." /><p>Ceci met en évidence deux conflits, l'un concernant les catégories et l'autre le prix. Notons que la requête qui sera exécutée après cette transformation présente les caractéristiques suivantes :</p><ul><li><p>Seuls les produits des catégories "Aliments et boissons de Noël" et "Friandises de Noël" seront affichés.</p></li><li><p>Dans ces catégories, si les produits sont également étiquetés comme appartenant à la catégorie "Calendriers de l'avent", leur prix sera multiplié par 3.</p></li><li><p>Un filtre de prix de 2 $ est appliqué, provenant de la politique de priorité inférieure (car la politique de priorité supérieure a spécifié de "limiter" en cas de conflit).</p></li><li><p>Les termes "pas cher" sont supprimés, seuls les produits correspondant au mot "chocolat" sont conservés.</p></li></ul><p>Avec ces deux politiques activées, « cheap chocolate » renvoie des résultats similaires à l’image ci-dessous :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7e3c2ee36f963e8c/6a170f8ccdacbf5be17d2ac2/01bbab1c5bd3d0fd37e39c25973d60141f9796e9-1126x1123.png" alt="Page de résultats de recherche affichant une requête pour &quot;chocolat pas cher&quot;, avec des filtres de catégorie et de marque sur la gauche et une liste de produits de calendrier de l'avent en chocolat avec images, prix et détails des produits sur la droite." /><h3>Assouplissement des contraintes</h3><p>Le détaillant ne souhaite peut-être pas exclure les produits des catégories "Chocolats" et "Chocolats au lait" pendant la période de Noël. Les paramètres de la politique de Noël ont peut-être été trop restrictifs et ont supprimé par inadvertance des catégories couvertes par la politique concernant les "chocolats bon marché". Cet exemple illustre pourquoi il peut être plus judicieux de combiner les politiques de moindre priorité avec les politiques de priorité supérieure qui entrent en conflit. Par exemple, nous pourrions modifier la promotion des chocolats de Noël de sorte qu'au lieu d'appliquer une priorité absolue en cas de conflit, nous appliquions un soft boost. La modification apportée à cette politique serait la suivante :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbb7393566aeab705/6a170f8db0367d5b6472bde2/45e88311014d67933ca8cf8381d8f91de090e2b4-1090x103.png" alt="Interface utilisateur affichant une règle de politique de recherche avec le champ défini sur Catégories, l'opérateur défini sur Égal à, les valeurs &quot;Aliments et boissons de Noël&quot; et &quot;Friandises de Noël&quot;, la gestion des conflits définie sur Soft avec priorité 1 et le mode de filtrage défini sur Strict." /><p>Après cette modification, l'exécution du pipeline de transformation de la réécriture de requête pour "chocolat pas cher" se présente comme suit :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6b4453b35b5f8ef0/6a170f8fb339d5ba9b76a09a/396b360e48327421c2c38bcf4a039fb1a6d5a8e0-519x445.png" alt="Capture d'écran d'un pipeline de transformation montrant comment la requête initiale &quot;chocolat pas cher&quot; est modifiée par de multiples règles, notamment des filtres de catégorie, des limites de prix, des modes de filtrage soft et strict, des résultats de gestion des conflits, des priorités de règles et une requête finale de &quot;chocolat&quot;." /><p>Lorsque l'option soft boost en cas de conflit est activée, les filtres conflictuels sont convertis en soft boosts au lieu d'être supprimés. La requête qui sera exécutée sur le catalogue de produits après cette transformation présente les caractéristiques suivantes :</p><ul><li><p>Comme "En cas de conflit" est spécifié comme "Soft boost" sur la politique de priorité élevée, les conflits seront convertis en boosts comme suit :</p><ul><li><p>Un boost de 1x sera appliqué aux produits des catégories "Aliments et boissons de Noël" et "Friandises de Noël".</p></li><li><p>Un boost de 3x sera appliqué aux produits des catégories "Chocolats" et "Chocolats au lait"..</p></li></ul></li><li><p>Comme dans l'exemple précédent, si les produits sont également marqués comme appartenant à la catégorie "Calendriers de l'avent", un boost de 3x leur sera appliqué.</p></li><li><p>Comme dans l’exemple précédent, un filtre de prix de 2 $ est appliqué.</p></li><li><p>Les termes "pas cher" sont supprimés, seuls les produits correspondant au mot "chocolat" sont conservés.</p></li></ul><p>Avec un filtrage assoupli, les résultats sont les suivants :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0288336675c509ef/6a170f917d8d6723bc70e808/7a68c54d878dadfe8b1821dd3860b7b60f9ce45f-1126x1123.png" alt="Page de résultats de recherche pour la requête &quot;chocolat pas cher&quot;, affichant des filtres par catégorie et par marque à gauche et une liste de produits à droite, avec divers articles de chocolat, leurs prix et leurs catégories, ainsi qu'un total de 6 895 résultats indiqué en haut de la page." /><h3>Remplacement du prix défini dans une politique de priorité élevée</h3><p>Ou peut-être que le détaillant souhaite proposer des chocolats légèrement plus chers pendant les fêtes de fin d'année en augmentant le prix maximal à 7 $. Afin d'éviter que le prix maximal défini par la politique relative aux chocolats de Noël ne soit contourné si un utilisateur recherche "chocolats pas chers", nous pouvons configurer le mode de gestion des conflits de prix sur "remplacer" plutôt que sur "limiter", comme suit :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltae1b40d312cf59e6/6a170f92cdacbfa1277d2ac6/c2621e6513281f545b84eb77362f2b93e1c46a1f-996x70.png" alt="Interface utilisateur affichant une règle de politique de recherche avec le champ défini sur Prix, l'opérateur défini sur Inférieur à, la valeur définie sur 7, la gestion des conflits définie sur Remplacer et le mode de filtrage défini sur Strict." /><p>Grâce à ce remplacement, la requête pour "chocolat pas cher" ignore le prix maximal défini dans la politique "chocolat pas cher" et n'applique que le prix spécifié dans la politique "Chocolats de Noël", comme suit :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4a47aa71c925b4a3/6a170f94ab7f0863d3db9f6d/d50da7900beb3c08439e9fd79cbe2ddd98196441-511x389.png" alt="Capture d'écran d'un pipeline de transformation détaillant comment la requête initiale &quot;chocolat pas cher&quot; est traitée par deux règles de filtrage, montrant les filtres de catégorie et de prix ajoutés, les modes de filtrage strict et soft boost, les résultats de la gestion des conflits, les priorités des règles et la suppression d'un filtre de prix en raison d'un conflit." /><p>Ceci est similaire à l'exemple précédent, à la différence que le prix maximal est fixé à 7 $, valeur issue de la politique prioritaire, car celle-ci spécifie "Remplacer" en cas de conflit. Le filtre de prix de Noël étant prioritaire, les résultats sont les suivants :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2b9ac1a62437c967/6a170f96839dfa3f58dcffb9/635ee6353ba84727486e7e053764788fb26b6f44-1134x1079.png" alt="Page de résultats de recherche pour la requête &quot;chocolat pas cher&quot;, affichant des filtres par catégorie et par marque sur la gauche et une liste de produits chocolatés à droite, et comprenant plusieurs calendriers de l'avent avec images, prix, catégories, et un total affiché de 10 000 résultats." /><p>Ces trois variantes (priorité, soft boost et remplacer le prix) illustrent une propriété essentielle du système : un responsable commercial peut modifier l'interaction entre deux politiques en ajustant un seul paramètre au sein d'une même politique, sans déployer de code. La stratégie de gestion des conflits est le levier qui contrôle le comportement opérationnel.</p><h2>Suivi des expressions utilisées</h2><p>Il existe une forme de conflit plus subtile : deux politiques qui correspondent sur la même expression. Si une politique prioritaire supprime "sans cacahuètes" de la requête, une politique moins prioritaire qui correspondait également à "sans" n'a plus rien à traiter. Le système détecte si l'expression correspondante n'est plus présente dans la requête reformulée et ignore la politique moins prioritaire.</p><p>Les politiques d'intention sont exemptées du suivi des expressions utilisées : elles définissent la stratégie de récupération en fonction de la correspondance de la requête d'origine, indépendamment du texte supprimé par les politiques prioritaires.</p><p>L'ordonnancement prioritaire, la résolution des conflits au niveau des champs et le suivi des expressions utilisées confèrent ensemble au plan de contrôle un modèle de composition déterministe. Grâce à cette base, le système est en mesure de prendre des décisions de routage qui seraient risquées sans elle.</p><h2>La gouvernance régule la stratégie de récupération</h2><p>Il est important de noter que le choix de la méthode de recherche appropriée (textuelle, sémantique ou hybride) intervient après la phase de gouvernance. Si vos politiques ont déjà imposé la "catégorie de produit", la recherche sémantique devient alors beaucoup moins risquée, car l'ensemble des candidats est restreint. Une recherche sémantique portant sur 500 articles de produit est très différente d'une recherche sémantique portant sur 500 000 références. La gouvernance permet de limiter le champ d'application de la recherche avant même son lancement.</p><p>Par exemple, sans gouvernance, une requête sémantique pour "Fruits riches en vitamine C à moins de 4 $" pourrait renvoyer, en plus des fruits, des flacons de vitamines, des carottes et des poivrons verts. Le plan de contrôle garantit que ces résultats indésirables ne sont même pas pris en compte dans l'expansion sémantique.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdaa3ff1bb3afaa36/6a170f97acf088954bbe9c1f/6dccd5b8a94bfa81f68e3d1c4ad8929ce8cc4e5e-990x378.png" alt="Diagramme illustrant le flux d'une requête de recherche provenant d'un utilisateur, passant par un serveur d'applications et un plan de contrôle, où les règles de correspondance sont recherchées, la requête est réécrite avec une intention sémantique incluant des contraintes de catégorie et de prix, et les résultats sont extraits d'un catalogue de produits, les produits non correspondants étant exclus." /><p>Avec cette contrainte en place, le plan de contrôle applique une logique de routage pragmatique :</p><ul><li><p><strong>Lexical</strong> pour les requêtes de navigation et les requêtes d'en-tête où la précision déterministe est importante.</p></li><li><p><strong>Sémantique</strong> pour les requêtes d'exploration descriptive où la correspondance conceptuelle est utile.</p></li><li><p><strong>Hybride</strong> de manière sélective, lorsque des contraintes ont déjà été appliquées et que l'entreprise accepte un seuil de rappel plus large.</p></li></ul><h2>De l'architecture à la mise en œuvre</h2><p>Le plan de contrôle gouverné traduit les intentions métier en plans d'exécution déterministes et composables, sans intégrer cette logique dans le code applicatif. Les politiques sont des données : elles sont mises en correspondance lors de la requête, résolues par des stratégies de gestion des conflits explicites par champ et appliquées sous forme de transformations en cascade produisant des résultats explicables. Elastic Services Engineering a conçu et déployé cette architecture pour des équipes e-commerce d'entreprise, en utilisant des modèles et des accélérateurs reproductibles qui raccourcissent le passage du concept à la production. Une démonstration de notre implémentation d'un plan de contrôle est disponible sur YouTube : <a href="https://www.youtube.com/watch?v=e1GuL9CYWAk">Fixing Search Relevance in Seconds: Introducing PRISM</a>.</p><h3><strong>À suivre dans cette série</strong></h3><p>Le prochain article se penchera sur la mise en œuvre pratique : comment le percolateur Elasticsearch gère la recherche de politiques, notamment les mappings d'index, les marqueurs de délimitations, le suivi des expressions par mise en évidence et des exemples concrets de requêtes.</p><h2>Mettre en pratique la recherche e-commerce réglementée</h2><p>L'architecture du plan de contrôle décrite dans cet article (résolution des conflits par champ, transformations de politiques en cascade et routage de récupération soumis à des contraintes de gouvernance) a été conçue et réalisée par Elastic Services Engineering. Chaque modèle, capture d'écran et pipeline de transformation présenté dans cette série provient d'un système opérationnel développé par Elastic Services Engineering et validé par rapport aux catalogues de produits à l'échelle de l'entreprise.</p><p>Si vous souhaitez implémenter un plan de contrôle gouverné et piloté par des politiques sur Elasticsearch, <a href="https://www.elastic.co/consulting">Elastic Services</a> peut vous aider à y parvenir plus rapidement.</p><h2>Rejoignez la discussion</h2><p>Avez-vous des questions sur la gouvernance de la recherche, les stratégies de récupération ou l'architecture de recherche e-commerce ? Participez à la <a href="https://discuss.elastic.co/">discussion élargie de la communauté Elastic</a>.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/ecommerce-search-governance-control-plane-architecture</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/ecommerce-search-governance-control-plane-architecture</guid>
    <category><![CDATA[Opérations]]></category>
    <dc:creator><![CDATA[Alexander Marquardt,Honza Král,Taylor Roy]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb84f89f4d9029df7/6a170f806234e077cddb1ab6/4e2cd5244ef8b9a05af6337a4825252f321a9a43-1377x768.png" length="0" type="image/png"/>
    <pubDate>Fri, 01 May 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Réindexation des flux de données en raison de conflits de mapping]]></title>
    <description><![CDATA[Découvrez comment résoudre les conflits de mapping Elasticsearch en réindexant les flux de données. Cet article explique le processus de réindexation et comment garantir un mapping correct des nouvelles données.]]></description>
    <content:encoded><![CDATA[<p>En cas de conflits de mapping de champs, qu'ils soient conformes à la norme Elastic Common Schema (ECS) ou spécifiques à la source de données, une réindexation des données à l'aide des outils de développement s'avère nécessaire. Ces conflits peuvent avoir un impact négatif sur les fonctions en aval après l'ingestion, entraînant potentiellement des résultats inexacts ou empêchant l'utilisation de l'ensemble des données dans des fonctionnalités telles que les visualisations, les tableaux de bord, l'application Security et les agrégations. Cet article de blog détaille les étapes de ce processus de réindexation.</p><p>Le contenu de ce blog a été développé et vérifié à l'aide des versions Elastic 9.2.8 et 8.19.14, ainsi que des versions Filestream Integration 2.3.0 et 1.2.0.</p><p><strong>Remarque importante</strong> : selon votre environnement, certaines étapes peuvent nécessiter des modifications spécifiques. De plus, sachez que les modèles dynamiques ont été supprimés du modèle de composants <code>@package</code> à compter de la version 2.3.3 de Filestream Integration.</p><p>Avant de commencer le processus de réindexation, il est important de prendre en compte l'allocation actuelle de stockage dans votre environnement. Les étapes décrites ci-dessous impliquent la création d'une copie de l'index sous-jacent existant, qui résidera temporairement dans le <a href="https://www.elastic.co/docs/manage-data/lifecycle/data-tiers">niveau hot</a>.</p><p><u><strong>Niveaux de données Elasticsearch</strong></u></p><ul><li><p><strong>Hot</strong> : le niveau hot est le point d'entrée d'Elasticsearch pour les données temporelles, stockant les données les plus récentes et les plus fréquemment recherchées. Les nœuds du niveau hot nécessitent des lectures et des écritures rapides, ce qui requiert davantage de ressources et un stockage plus rapide (SSD). Ce niveau est obligatoire et de nouveaux index de flux de données y sont automatiquement attribués.</p></li><li><p><strong>Warm</strong> : les données temporelles peuvent passer au niveau warm une fois qu'elles sont interrogées moins fréquemment que les données récemment indexées du niveau hot. Le niveau warm contient généralement les données des dernières semaines. Les mises à jour sont toujours autorisées, mais elles sont probablement peu fréquentes. Les nœuds du niveau warm n'ont généralement pas besoin d'être aussi rapides que ceux du niveau hot. Pour la résilience, les index du niveau hot doivent être configurés pour utiliser une ou plusieurs répliques.</p></li><li><p><strong>Cold</strong> : les données rarement consultées peuvent être déplacées du niveau warm vers le niveau cold. Celui-ci, tout en restant interrogeable, privilégie la réduction des coûts de stockage à la vitesse de recherche. Il est également possible d'y stocker des index classiques avec des répliques plutôt que des instantanés interrogeables, ce qui permet d'utiliser du matériel moins coûteux pour les données anciennes sans pour autant réduire l'espace disque requis par rapport au niveau warm.</p></li><li><p><strong>Frozen</strong> : les données rarement interrogées ou qui ne le sont plus passent du niveau cold au niveau frozen pour la durée restante de leur cycle de vie. Ce niveau utilise un référentiel de snapshots et des index partiellement assemblés pour stocker et charger les données, réduisant ainsi le stockage local et les coûts tout en permettant la recherche. Les recherches sur le niveau frozen sont généralement plus lentes que sur le niveau cold, car Elasticsearch peut avoir besoin de récupérer les données frozen depuis le référentiel de snapshots. Nous vous recommandons d'utiliser des nœuds dédiés au niveau frozen.</p></li></ul><h2>Prérequis : déterminer quels champs présentent des conflits</h2><p>Pour déterminer les champs qui présentent des conflits de mapping, accédez à <strong>Stack Management -&gt; Data Views -&gt; logs-*</strong> (la data view logs-* est la hiérarchie la plus élevée des données présentes avec le préfixe <em>logs-</em>). Si des conflits sont présents, un encadré jaune s'affiche. Vous pouvez cliquer sur <strong>View conflicts</strong> ou, sous la zone <strong>Field type</strong> à côté de la zone <strong>Search</strong>, sélectionnez le <strong>conflit</strong>.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7aa17311023e1ae3/6a170feaa929cf24fbae0aa9/7d41594682b601a30a9544b8db678f118b0146ab-2048x720.png" alt="Interface affichant un modèle d'indexation des logs, avec un avertissement de conflit de mapping et une liste des types de champ. L'accent est mis sur les conflits d'affichage et les conflits de types de champs." /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb4106cf39e1be69b/6a170feb6f7f047b74914932/41ad800daa6fc244a1123ba7538820bff5de6788-747x182.png" alt="Ligne de tableau affichant le nom du champ log.offset avec les types keyword et long marqués comme un conflit." /><p>Cliquez sur le bouton jaune <strong>Conflict</strong> pour voir quels index sont associés à quels types de mapping.</p><p>Cette situation (où le champ est mappé à la fois en tant que <code>keyword</code> et en tant que <code>long</code>) se produit généralement parce que les données ont été ingérées avant qu'un type de mapping spécifique ait été défini dans le <a href="https://www.elastic.co/docs/manage-data/data-store/templates#component-templates">modèle de composants</a> pour le <a href="https://www.elastic.co/docs/manage-data/data-store/data-streams">flux de données</a> concerné. Dans de tels cas, Elasticsearch tente de définir le mapping en fonction de ses modèles dynamiques.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdcec2cd42e2e858a/6a170feda929cff2e4ae0aad/9973c1935aa52292c1ace09a8e9c0b31ad99e7a2-2048x1085.png" alt="Écran affichant le champ log.offset avec un avertissement concernant les différents types et un tableau listant les index pour chaque type." /><p>Pour déterminer quel mapping est approprié pour le champ et si le champ est un champ ECS, une vérification avec la <a href="https://www.elastic.co/docs/reference/ecs/ecs-field-reference">référence des champs ECS</a> est nécessaire. Si le champ en question n'est pas un champ ECS, sa valeur doit être examinée pour déterminer le mapping approprié.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc22eb597f97cbb24/6a170feed7c02291c5de657c/3c77d0a1520bd1ad17e7ffa1480ecf5e224953e1-418x360.png" alt="" /><p>Si un champ, comme <code>log.offset</code> dans cet exemple, n'est pas documenté dans l'ECS, les étapes suivantes consistent à examiner la valeur du champ, à déterminer quel type de mapping conflictuel possède le plus d'index sous-jacents, et à examiner les modèles de composants des autres index.</p><p>En général, le type de mapping associé au plus grand nombre d'index est le bon, mais nous vous recommandons de vérifier la valeur du champ concerné pour le confirmer. Pour confirmer la validité d'un type de mapping (par exemple, <code>long</code>), vous devez également vérifier que la valeur du champ est appropriée pour ce type. Cette vérification peut être effectuée en utilisant <strong>Discover </strong>pour rechercher le champ en question. L'examen d'autres flux de données contenant le même champ peut également apporter une confirmation supplémentaire.</p><p>Pour examiner les valeurs présentes pour le champ qui présente le problème de mapping, revenez au bouton jaune <strong>Conflict </strong>indiqué précédemment, cliquez sur le bouton <strong>Conflict</strong>, sélectionnez l'un des index sous-jacents et collez-le dans une session <strong>Discover </strong>. Votre instruction Kibana Query Language (KQL) devrait ressembler à la capture d'écran suivante, pour inclure le délimiteur de champ <strong><code>_index</code></strong><strong>:</strong>.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4b1966dbd35b7264/6a170ff00c4857919a01ab52/781f63b34a9abd427ceb896484da29af446e3326-2048x1063.png" alt="Écran affichant le champ log.offset avec un avertissement concernant un conflit de type, ainsi qu'un tableau listant les index pour chaque type." /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdf3bb65faeb1e94b/6a170ff214b2701bfbe3c6c3/b7b0cb847c1694ab605c61a538722f5be004ec86-2048x909.png" alt="Écran affichant un histogramme temporel et un tableau des entrées de log comportant des horodatages et des valeurs log.offset." /><h2>Préparation du nouveau modèle de composants personnalisé d'index sous-jacent</h2><p>Pour résoudre le conflit de mapping dans le flux de données, examinez d'abord le modèle de composants <code>@package</code> pertinent. Vous trouverez ceci sous <strong>Stack Management -&gt; Index Management -&gt; Component Template</strong>. Cherchez le flux de données et sélectionnez le lien <code>@package</code> correspondant. Ce modèle contient des mappings prêts à l'emploi pour les champs et, bien que les incohérences de mapping soient rares, il est possible que le type le plus approprié ait été ignoré.</p><p>Vérifiez le modèle pour vous assurer qu'il contient l'imbrication et le mapping de champs nécessaires pour le champ en question. Par exemple, si le modèle liste <code>log.offset</code> comme <code>keyword</code> par erreur, la source du problème est ici.</p><p><strong>Important</strong> : comme il n'est pas recommandé de modifier les modèles <code>@package</code>/managed, vous devez utiliser ou créer un modèle de composants <code>@custom</code> pour corriger le type de mapping (par exemple, pour <code>log.offset</code>) pour toutes les données futures.</p><ul><li><p>Nous ne recommandons pas de modifier les modèles <code>@package</code>/managed, car lorsque vous mettrez à jour l'intégration vers une version plus récente, toutes les modifications que vous apporterez au modèle <code>@package</code> seront remplacées. C'est pourquoi nous recommandons d'utiliser les modèles <code>@custom</code>.</p></li><li><p>Si un flux de données rencontre des conflits de mapping, vous devez ajouter tous les champs manquants (imbrications ou mappings ECS et non-ECS) au modèle de composants <code>@custom</code> du flux de données. Créez ce modèle s'il n'existe pas encore et veillez à spécifier le type de mapping correct pour le champ.</p></li><li><p>Si plusieurs conflits sont présents dans votre data view, appliquez simultanément tous les mappings manquants nécessaires au flux de données afin que la réindexation ne soit effectuée qu'une seule fois. L'ajout d'entrées pour le typage correct des données dans le modèle de composants <code>@custom</code> garantira que toute ingestion ultérieure de données suivra les mêmes règles de mapping.</p></li></ul><p>Pour créer le modèle de composants <code>@custom</code> (ou vérifier qu'il est utilisé et renseigné), accédez ) <strong>Index Templates</strong>, saisissez le nom du flux de données en question et cliquez sur le modèle <code>@custom</code> approprié utilisé par le flux de données. Si le modèle n'est pas encore créé, une case jaune apparaît, vous permettant de le créer via l'interface utilisateur.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt17b6cb8aa8f905c2/6a170ff4964cea702708bc97/bea7cb172227bebc28146e3f2f016e112f34cba5-2048x720.png" alt=" Écran affichant un modèle d'index avec son résumé, son modèle d'index, sa valeur de priorité, son paramètre de flux de données et une liste de modèles de composants, l'accent étant mis sur l'entrée logs‑filestream.generic@custom." /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf5b67199089093f4/6a170ff5d7c0220575de6580/e8f63a2e396efbe7f1e62dc08a137a22700be484-2048x296.png" alt=" Écran montrant l'interface de gestion des index, l'onglet &quot;Modèles de composants&quot; étant sélectionné, et une note indiquant que le modèle personnalisé n'existe pas. L'option &quot;Créer un modèle de composants&quot; est sélectionnée." /><p>La capture d'écran ci-dessous montre la page suivante après que l'option <strong>Create component template</strong> a été sélectionnée. Laissez les paramètres par défaut tels quels sur la première page et cliquez sur <strong>Mappings</strong> ou <strong>Next</strong> jusqu'à atteindre la page <strong>Mappings</strong>.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltca2924bc41cac541/6a170ff7dc55decfd6e00ec5/822f1d864302aa4be438c13756b8372f43fa1b0d-2048x1275.png" alt="" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltee1067cb282ae0af/6a170ff82b835f55bff4b2e5/affa2f1214af516a5a6b571ab813628ed7649275-2048x1235.png" alt="Modèles de mappings" /><p>Pour définir explicitement le mapping d'un nouveau champ entrant ou pour mettre à jour un champ présentant un conflit de mapping, lorsque le flux de données est réinitialisé en raison d'une configuration définie dans la politique de cycle de vie de l'index, une entrée est nécessaire pour le champ dans lequel le conflit existe.</p><p>La procédure suivante permet de définir le mapping du champ <code>log.offset</code> dans le modèle de composants <code>@custom</code> pour le flux de données filestream. Répétez les étapes pour ajouter des champs personnalisés ou mettre à jour les champs nécessaires du <code>@package</code> avec les mappings appropriés, si nécessaire, pour cet ensemble de données. Dans cet exemple, en définissant le décalage sur <code>Long</code>, le type de champ sera <code>Numeric</code> et le type numérique sera <code>Long</code>. Cliquez sur <strong>Add field</strong>, puis en dehors de la zone pour continuer.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltee1067cb282ae0af/6a170ff82b835f55bff4b2e5/affa2f1214af516a5a6b571ab813628ed7649275-2048x1235.png" alt="Écran montrant l'interface de création du modèle de composants avec l'étape &quot;mapping&quot; sélectionnée dans le workflow." /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt611a10bd7567d211/6a170ffa964cea257008bc9d/ea2975ee4e40ac0e10c4170d2a23125101f7f8da-2048x1136.png" alt=": Écran affichant l'interface de création de modèles de composants avec l'étape &quot;Mappings&quot; sélectionnée dans le workflow" /><p>Une fois tous les champs nécessaires ajoutés, cliquez pour vérifier, puis sélectionnez <strong>Create component template</strong> lorsque vous êtes prêt. <code>log.offset</code> sera défini sur <code>long</code> pour toutes les nouvelles données ingérées à partir de cette étape.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3a0c86021cc53e0e/6a170ffcc1e8a57703f8839f/bdf8b8290b0c064c9d88990194b15232ffe85709-2048x1027.png" alt=" Révision d'un modèle Elasticsearch" /><h2>Création de la nouvelle structure de l'index sous-jacent</h2><p>Le nouvel index sous-jacent doit comporter les mappings existants du modèle de composants du flux de données, ainsi que le modèle de composants ECS <code>ecs@mappings</code>. Le modèle de composants <code>ecs@mappings</code> est appliqué après le composant du flux de données en tant que catchall pour les mappings supplémentaires qui n'ont potentiellement pas été capturés dans les modèles de composants précédents.</p><p>Accédez à l'onglet navigateur pour les mappings <code>@package</code> du flux de données. (<strong>Stack Management -&gt; Index Management -&gt; Component Template -&gt; </strong><strong><code>logs-filestream.generic@package</code></strong><strong> -&gt; Manage -&gt; Edit</strong>.) Une fois sur place, cliquez sur la section <strong>Review</strong>, puis sur <strong>Request</strong>, et enfin sur le bouton <strong>Copy</strong> à droite. Le contenu JSON du modèle de composants copié garantit la conservation des mappings de champs et des paramètres restants pendant la mise à jour du mapping de champ <code>log.offset</code>. Ce JSON constituera la structure sous-jacente de l'index nouvellement réindexé.</p><p><strong>Important</strong> : si le JSON du modèle n'avait pas été copié et que l'opération de réindexation se soit poursuivie, le conflit <code>log.offset</code> aurait été résolu, mais de nouveaux conflits seraient survenus avec l'intégration, car l'intégrité des mappings actuels n'a pas été respectée, créant un double travail pour résoudre le problème initial.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1de7b9b0e375867e/6a170ffd8b73cb61f318a0f7/402b0431b0e19374e9b28a4374ed51dfa5fa44ba-2048x897.png" alt="Écran montrant l'interface de création d'un modèle de composants avec l'étape de révision sélectionnée dans le workflow. " /><p>Ouvrez un deuxième onglet de navigateur, accédez aux outils de développement et collez le contenu copié. Ensuite, pour nettoyer ce qui a été collé :</p><p><strong>Modifications de la demande</strong></p><p><strong>1. Nom de l'index</strong> : remplacez <code>_component_template/logs-filestream.generic@package</code> par le nom de l'index sous-jacent que vous souhaitez réindexer, en ajoutant <code>-1</code> à la fin. Par exemple, utilisez <code>PUT &lt;backing index to reindex&gt;-1</code>.</p><ul><li><p>Le <code>-1</code> ajouté indique une réindexation et ne sera pas en conflit avec les paramètres de substitution ILM par défaut, qui sont basés sur la date de création de l'index.</p></li></ul><p><strong>2. Paramètres</strong> : supprimez la ligne <code>"template"</code> (ligne 3), ainsi que la toute dernière accolade fermante de l'ensemble de la charge utile JSON ; la ligne 3 doit commencer par <code>"settings": {</code>.</p><ul><li><p>Remplacez le contenu interne de la section des paramètres par <code>"index.codec": "best_compression"</code>. Cette action appliquera la meilleure compression d'Elastic à l'index lors de sa création.</p></li><li><p>Ajoutez <code>"index.lifecycle.name": "logs"</code>, ainsi qu'une ligne pour <code>"index.lifecycle.rollover_alias": ""</code>.</p><ol><li><p>L'entrée <code>"index.lifecycle.name": "logs"</code> appliquera la politique ILM des logs au nouvel index sous-jacent. Modifiez le nom de la politique ILM si vous n'utilisez pas de logs.</p></li><li><p>Le <code>"index.lifecycle.rollover_alias": ""</code> est vide, car cet index sous-jacent ne sera par reconduit ; ce paramètre est néanmoins nécessaire pour éviter les erreurs de substitution ILM dans la phase ILM qui suit la phase hot.</p></li></ol></li></ul><p><strong>3. Structure</strong> : la requête doit désormais inclure à la fois une section <code>Settings</code> et une section <code>Mappings</code>. Dans <code>"mappings": {</code>, vous devriez trouver <code>"dynamic_templates"</code> et une section <code>"properties"</code> contenant des champs codés en dur et leurs mappings.</p><p><strong>4. Modification des modèles dynamiques</strong> : la section des modèles dynamiques actuels contient des entrées de champs qui peuvent être remplacés lorsque les modèles dynamiques <code>ecs@mappings </code> sont ajoutés ensuite, ce qui génère une redondance et des lignes supplémentaires qui ne sont pas nécessaires.</p><ul><li><p>Supprimez toutes les sections de <code>"dynamic_templates"</code> sauf la deuxième intitulée <code>"_embedded_ecs-data_stream_to_constant": {</code>.</p></li><li><p>Répétez le même processus que celui décrit ci-dessus, en rassemblant les mappings dynamiques pour le modèle de composants <code>@package</code>, mais cette fois-ci les mappings dynamiques pour le modèle de composants <code>ecs@mappings</code>.</p><ul><li><p>Il peut être plus simple de copier l'intégralité du contenu des mappings depuis l'interface utilisateur pour le modèle de composants <code>ecs@mappings</code>, de coller dans la section Dev Tools <code>dynamic_templates</code> fonctionnelle, et de supprimer les lignes dupliquées et inutiles là où c'est approprié. Incluez ces contenus de paramètres de modèle dynamique après l'entrée <code>"_embedded_ecs-data_stream_to_constant": {</code>. La section <code>dynamic_templates</code> doit être très proche des exemples de contenus ci-dessous dans Dev Tools.</p></li></ul></li><li><p><strong>Si les </strong><strong><code>dynamic_templates</code></strong><strong> ne sont pas inclus/supprimés</strong>, d'autres champs (voir la capture d'écran ci-dessous) comporteront des mappings en double : <code>text</code> et <code>keyword</code> par rapport aux mappings appropriés, si la section <code>dynamic_templates</code> n'a pas été retirée. Ce qui reste devrait être la section <code>"properties"</code> sous <code>"mappings"</code>. Cela créera également des problèmes dans la data view puisque les champs ont été mappés en double (s'ils n'ont pas déjà été mappés de cette façon) et provoquera des conflits de mapping supplémentaires.</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfb7494f882d7e358/6a170fffa6c2b93e46e797d2/24e972cd0fc8eadf943b21cfdd80a5d435e705aa-2048x994.png" alt="Éditeur de code en écran partagé affichant les commandes Elasticsearch à gauche et les mappings d'index à droite. Une flèche indique le type de champ texte dans le mapping, et une autre flèche indique le type de sous-champ keyword." /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcaca899f8d92e72b/6a1710010c485745e901ab5a/aac13fbe882516e5ed5b5b1b5271c0ae34e80b04-1890x2048.png" alt=": Écran affichant la page de modèle d'index pour logs-* avec un avertissement concernant les conflits de mapping, mettant l'accent sur les listes de type &quot;keyword, text&quot; pour agent.ephemeral_id et agent.id dans le tableau des champs." /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2c692786ab74f1ca/6a171002964ceaa53c08bca1/c43d6f61c8ece4de2d51657f239a0c34ced07cdb-1928x1452.png" alt="Écran affichant la page du modèle d'indexation pour logs-* avec un avertissement concernant les conflits de mapping. Une flèche pointe vers le type indiquant &quot;ip, text&quot; pour le champ host.ip." /><p><strong>5. Suppression des métadonnées</strong> : supprimez la dernière section étiquetée <code>"_meta"</code>, ainsi que la section étiquetée <code>"version"</code>, si elle est présente.</p><p><strong>6. Formatage</strong> : indentez automatiquement les sections restantes et ajustez ou supprimez les accolades inutiles qui pourraient empêcher une exécution correcte.
</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0906ffe338df1a9d/6a1710046f7f042aac914936/ebe1573647500de75315e7655256a0db9604c40d-2048x1402.png" alt="Éditeur de code affichant les paramètres d'index et les mappings d'Elasticsearch. Un menu déroulant est ouvert à droite, et une flèche pointe vers l'option &quot;Auto indent&quot; dans le menu." /><p><strong>7. Modification du mapping</strong> : accédez à la section <code>"properties"</code>, recherchez <code>"log"</code>, puis localisez <code>"offset"</code> imbriqué en dessous. Changez le type de <code>keyword</code> pour <code>long</code>, puis supprimez l'entrée de ligne (virgule incluse) étiquetée <code>"ignore_above": 1024,</code>. Si plus d'une entrée a été ajoutée au modèle de composants <code>@custom</code> créé précédemment, incluez-les ici.</p><p>La vue console de vos outils de développement devrait maintenant être semblable à l'exemple ci-dessous.</p>PUT .ds-logs-filestream.generic-default-2026.04.14-000001-1
{
  "settings": {
    "index.codec": "best_compression",
    "index.lifecycle.name": "logs",
    "index.lifecycle.rollover_alias": ""
  },
  "mappings": {
    "dynamic_templates": [
      {
        "_embedded_ecs-data_stream_to_constant": {
          "path_match": "data_stream.*",
          "mapping": {
            "type": "constant_keyword"
          }
        }
      },
      {
        "ecs_timestamp": {
          "mapping": {
            "ignore_malformed": false,
            "type": "date"
          },
          "match": "@timestamp"
        }
      },
      {
        "ecs_message_match_only_text": {
          "path_match": [
            "message",
            "*.message"
          ],
          "mapping": {
            "type": "match_only_text"
          },
          "unmatch_mapping_type": "object"
        }
      },
      {
        "ecs_non_indexed_keyword": {
          "path_match": [
            "*event.original"
          ],
          "mapping": {
            "index": false,
            "type": "keyword",
            "doc_values": false
          }
        }
      },
      {
        "ecs_non_indexed_long": {
          "path_match": [
            "*.x509.public_key_exponent"
          ],
          "mapping": {
            "index": false,
            "type": "long",
            "doc_values": false
          }
        }
      },
      {
        "ecs_ip": {
          "path_match": [
            "ip",
            "*.ip",
            "*_ip"
          ],
          "mapping": {
            "type": "ip"
          },
          "match_mapping_type": "string"
        }
      },
      {
        "ecs_wildcard": {
          "path_match": [
            "*.io.text",
            "*.message_id",
            "*registry.data.strings",
            "*url.path"
          ],
          "mapping": {
            "type": "wildcard"
          },
          "unmatch_mapping_type": "object"
        }
      },
      {
        "ecs_path_match_wildcard_and_match_only_text": {
          "path_match": [
            "*.body.content",
            "*url.full",
            "*url.original"
          ],
          "mapping": {
            "fields": {
              "text": {
                "type": "match_only_text"
              }
            },
            "type": "wildcard"
          },
          "unmatch_mapping_type": "object"
        }
      },
      {
        "ecs_match_wildcard_and_match_only_text": {
          "mapping": {
            "fields": {
              "text": {
                "type": "match_only_text"
              }
            },
            "type": "wildcard"
          },
          "unmatch_mapping_type": "object",
          "match": [
            "*command_line",
            "*stack_trace"
          ]
        }
      },
      {
        "ecs_path_match_keyword_and_match_only_text": {
          "path_match": [
            "*.title",
            "*.executable",
            "*.name",
            "*.working_directory",
            "*.full_name",
            "*file.path",
            "*file.target_path",
            "*os.full",
            "*email.subject",
            "*vulnerability.description",
            "*user_agent.original"
          ],
          "mapping": {
            "fields": {
              "text": {
                "type": "match_only_text"
              }
            },
            "type": "keyword"
          },
          "unmatch_mapping_type": "object"
        }
      },
      {
        "ecs_date": {
          "path_match": [
            "*.timestamp",
            "*_timestamp",
            "*.not_after",
            "*.not_before",
            "*.accessed",
            "created",
            "*.created",
            "*.installed",
            "*.creation_date",
            "*.ctime",
            "*.mtime",
            "ingested",
            "*.ingested",
            "*.start",
            "*.end",
            "*.indicator.first_seen",
            "*.indicator.last_seen",
            "*.indicator.modified_at",
            "*threat.enrichments.matched.occurred"
          ],
          "mapping": {
            "type": "date"
          },
          "unmatch_mapping_type": "object"
        }
      },
      {
        "ecs_path_match_float": {
          "path_match": [
            "*.score.*",
            "*_score*"
          ],
          "mapping": {
            "type": "float"
          },
          "path_unmatch": "*.version",
          "unmatch_mapping_type": "object"
        }
      },
      {
        "ecs_usage_double_scaled_float": {
          "path_match": "*.usage",
          "mapping": {
            "scaling_factor": 1000,
            "type": "scaled_float"
          },
          "match_mapping_type": [
            "double",
            "long",
            "string"
          ]
        }
      },
      {
        "ecs_geo_point": {
          "path_match": [
            "*.geo.location"
          ],
          "mapping": {
            "type": "geo_point"
          }
        }
      },
      {
        "ecs_flattened": {
          "path_match": [
            "*structured_data",
            "*exports",
            "*imports"
          ],
          "mapping": {
            "type": "flattened"
          },
          "match_mapping_type": "object"
        }
      },
      {
        "all_strings_to_keywords": {
          "mapping": {
            "ignore_above": 1024,
            "type": "keyword"
          },
          "match_mapping_type": "string"
        }
      }
    ],
    "properties": {
      "input": {
        "properties": {
          "type": {
            "ignore_above": 1024,
            "type": "keyword"
          }
        }
      },
      "@timestamp": {
        "ignore_malformed": false,
        "type": "date"
      },
      "ecs": {
        "properties": {
          "version": {
            "ignore_above": 1024,
            "type": "keyword"
          }
        }
      },
      "log": {
        "properties": {
          "file": {
            "properties": {
              "inode": {
                "ignore_above": 1024,
                "type": "keyword"
              },
              "path": {
                "ignore_above": 1024,
                "type": "keyword"
              },
              "device_id": {
                "ignore_above": 1024,
                "type": "keyword"
              },
              "fingerprint": {
                "index": false,
                "type": "keyword"
              }
            }
          },
          "offset": {
            "type": "long"
          },
          "level": {
            "ignore_above": 1024,
            "type": "keyword"
          }
        }
      },
      "data_stream": {
        "properties": {
          "namespace": {
            "type": "constant_keyword"
          },
          "type": {
            "type": "constant_keyword"
          },
          "dataset": {
            "type": "constant_keyword"
          }
        }
      },
      "event": {
        "properties": {
          "original": {
            "index": false,
            "type": "keyword",
            "doc_values": false
          },
          "module": {
            "type": "constant_keyword",
            "value": "filestream"
          },
          "dataset": {
            "type": "constant_keyword",
            "value": "filestream.generic"
          }
        }
      },
      "message": {
        "type": "match_only_text"
      },
      "tags": {
        "ignore_above": 1024,
        "type": "keyword"
      }
    }
  }
}<p>Une fois que votre console ressemble à l'exemple (avec tous les champs personnalisés supplémentaires inclus et les valeurs personnalisées spécifiques à votre environnement), exécutez la commande pour créer la structure du nouvel index sous-jacent, en prenant le temps de résoudre les erreurs éventuelles.</p><h2>Démarrer le processus de réindexation</h2><p>Une fois la structure du nouvel index sous-jacent correctement créée, l'étape suivante consiste à réindexer et à résoudre les conflits de mapping.</p><p><strong>Important</strong> : si l'index sous-jacent qui présente le conflit de mapping est l'index le plus récent et l'index d'écriture actuel (par exemple, si le numéro final de l'index sous-jacent est -000001), le flux de données doit être remplacé. Le remplacement du flux de données est nécessaire, car l'index d'écriture actuel, dans lequel des documents sont ingérés, est un index sous-jacent actif et ne peut pas être modifié.</p><p>Maintenant que le mapping correct a été appliqué au dernier index d'écriture via le modèle de composants <code>@custom</code> créé précédemment, tous les nouveaux documents refléteront ce changement.</p><p>Ceci s'effectue en exécutant ce qui suit : </p>POST &lt;full data stream name&gt;/_rollover<p>Par exemple : </p>POST logs-filestream.generic-default/_rollover<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0e0ae084fe6ade43/6a171006a6c2b91078e797d6/22abc1a2f6de0420aa0d56ac498894111df7f4fd-2048x330.png" alt="Résultat de la substitution" /><p>La réindexation consiste à copier les données d'un index sous-jacent existant vers un nouvel index dans le cadre de la même convention de dénomination, généralement pour appliquer les modifications nécessaires. Ces modifications peuvent inclure des mises à jour d'un modèle de composants ou l'ajout d'un nouveau pipeline d'ingestion pour les données à traiter.</p><p>Ensuite, les données seront copiées depuis l'index sous-jacent dont les mapping sont incorrects vers un nouvel index sous-jacent. L'index sous-jacent initial a été remplacé, ce qui signifie qu'aucun nouveau document ne peut y être ajouté. Le nouvel index sous-jacent suivra la même convention de dénomination, ce qui préserve la visibilité et l'intégrité des données tout en appliquant la politique ILM adéquate, mais il contiendra le suffixe <code>-1</code> pour indiquer qu'il a été réindexé.</p><p>Ajustez les noms d’index selon les besoins et collez le code suivant dans la console. En incluant <code>wait_for_completion=false</code>, vous pouvez suivre la progression de la copie des documents, ce qui permet d'estimer le temps de réindexation restant. Sans ce paramètre, vous ne pourrez pas suivre le statut à l'aide de la commande <code>GET _tasks</code> ci-dessous et ne pourrez vérifier le nombre de documents dans l'index de sauvegarde plus récent qu'à l'aide de la commande <code>GET &lt;backing index name&gt;-1/_count</code>.</p><p><strong>Important</strong> : en cas de problèmes pendant le processus de réindexation, ne relancez pas la commande de réindexation, car cela redémarrera le processus et créera des enregistrements en double dans l'index se terminant par <code>-1</code>. Si un redémarrage est nécessaire, supprimez d'abord l'index avec <code>-1</code> à la fin, puis exécutez la commande <code>PUT</code> précédente pour recréer le nouveau shell de l'index sous-jacent.</p>POST _reindex?wait_for_completion=false
{
  "source": {
    "index": "&lt;source backing index&gt;"
  },
  "dest": {
    "index": "&lt;new backing index&gt;-1"
  }
}

i.e.
POST _reindex?wait_for_completion=false
{
  "source": {
    "index": ".ds-logs-filestream.generic-default-2026.04.13-000001"
  },
  "dest": {
    "index": ".ds-logs-filestream.generic-default-2026.04.13-000001-1"
  }
}<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb30fd97a045b6008/6a171007cf4f2566d6b2d22b/22f9b1f762802ecd20faa7c7c1f76c9d1444aba5-2048x530.png" alt=" Sortie de tâche" /><p>À l'exécution, la réponse inclura un identifiant de tâche. Vous pouvez surveiller la progression de la réindexation en utilisant cet ID avec la commande : <code>GET _tasks/&lt;task ID&gt;</code>.</p><p>La durée de la réindexation dépend du volume de données dans l'index initial. L'achèvement peut être suivi en recherchant <code>"completed": true</code> lors de l'exécution de la commande <code>GET</code>, ce qui devrait produire une sortie similaire.</p><p><code>GET _tasks/&lt;task ID&gt;</code></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4d40766e48cc0813/6a17100960084ba9043c4642/dbf0fb0a560a78236440b8c3de68cdf5c83e6d7a-2048x824.png" alt="Résumé de la tâche" /><p>Le processus de réindexation étant maintenant terminé pour le nombre de documents, l'étape suivante consiste à vérifier que les mappings entre le nouvel index sous-jacent et le champ spécifique en question sont corrects.</p>GET &lt;backing index&gt;-1/_mapping<p>Par exemple :</p>GET .ds-logs-filestream.generic-default-2026.04.13-000001-1/_mapping<p>Vous pouvez vérifier que le mapping pour <code>log.offset</code> est conforme à celui indiqué ci-dessous. Pour confirmer que les autres champs n'ont qu'une seule entrée de mapping (et non <code>text</code> et <code>keyword</code>), comparez-les à un champ qui ne faisait pas partie de la section de modèle dynamique dans la commande <code>PUT</code> précédente.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc156907e9635e4a9/6a17100b60084b59673c464e/db5c12c0a651e804a916d517e6e260e49a8b835a-2048x1121.png" alt=" Focus sur le mapping" /><p>Si l'index de support en cours de réindexation contient un grand nombre de documents, il est utile de vérifier l'état de ces documents copiés vers le nouvel index de support ; cela peut être fait à l'aide des deux commandes suivantes des outils de développement pour comparer les comptes.</p><p><code>GET .ds-logs-filestream.generic-default-2026.04.14-000001/_count</code></p><p><code>GET .ds-logs-filestream.generic-default-2026.04.14-000001-1/_count</code></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbc27c4da42ddc33d/6a17100c7d8d67e0ad70e816/a0e49ac79edb0abf9fe99d0e6fd35e96d0e3e0e5-2048x880.png" alt="" /><p>Une fois que vous avez vérifié que les nombres correspondent et que les mappings corrects sont présents, mettez à jour le flux de données pour inclure le nouvel index sous-jacent afin d'éviter que la gestion des index comporte un index sous-jacent orphelin auquel la politique ILM ne s'appliquera jamais.</p><ul><li><p>Si l'opération aboutit, une confirmation de réussite est renvoyée.</p></li></ul>POST _data_stream/_modify
{
  "actions": [
    {
      "add_backing_index": {
        "data_stream": "logs-filestream.generic-default",
        "index": ".ds-logs-filestream.generic-default-2026.04.14-000001-1"
      }
    }
  ]
}<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1bb6db6c761628fb/6a17100e7d8d67533770e81a/0aa3233377c0175258d37eaa661d56cf9f310d5e-2048x1288.png" alt="" /><p>Vérifiez que le nouvel index sous-jacent a été ajouté à l'aide de la commande suivante, en vous assurant que le paramètre <code>ilm_policy</code> est correct :</p>GET _data_stream/logs-filestream.generic-default<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7f4208ae6d7bf331/6a171010961e696241c4cfeb/af8b75cf260f6f088c28a78da86ad31527e0bfd5-2048x839.png" alt="" /><p>Vérifiez l'état ILM de l'index sous-jacent suivant avec cette commande :</p><ul><li><p>Vous constaterez que l'index est en mode hot, ce qui est normal car il a été créé très récemment (consultez la ligne 8 ou 10).</p></li></ul>GET .ds-logs-filestream.generic-default-2026.04.14-000001-1/_ilm/explain<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt953e1a062a040311/6a171012acf0885905be9c29/cd181a31001c7a3ee2b0599a7388909ce5b50baf-2048x972.png" alt="" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd398451578d070c9/6a1710140e2e492dc041a204/20f6e7632804f173533e655f0292c3c540f26597-2048x894.png" alt="" /><p>Exécutez la procédure suivante pour faire passer l'index de sauvegarde du niveau chaud au niveau approprié suivant la phase chaude de la stratégie ILM pour ce flux de données. Les valeurs spécifiques pour <code>phase</code>, <code>action</code> et <code>name</code> dans le <code>current_step</code> ci-dessous peuvent être consultées respectivement à partir des lignes 11, 13 et 15, dans la capture d’écran fournie ci-dessus.</p><p>La valeur <code>next_step</code> indique la phase ILM ou le niveau de données ultérieur auquel l'index passera.</p><p>Par exemple :</p>POST _ilm/move/.ds-logs-filestream.generic-default-2026.04.14-000001-1
{
  "current_step": {
    "phase": "hot",
    "action": "rollover", 
    "name": "check-rollover-ready"
  },
  "next_step": {
    "phase": "warm" 
  }
}<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt246a6538585234f1/6a1710160c4857ddc001ab60/7ae60b900ce1d0b46ce26ec301901bc8a9ef750c-2048x1249.png" alt="" /><ul><li><p>Ce n'est pas nécessaire, mais par mesure de sécurité, vous pouvez exécuter à nouveau la commande <code>_ilm/explain</code> pour vous assurer que l'index sous-jacent est passé à la phase suivante et n'est plus en phase hot.</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf77bba4d9b495048/6a17101867045b3b7d45c2c1/58a460cf2ec443223ea68ba7e7166a7cf9d8c97a-2048x915.png" alt="" /><p>Lorsque les conditions suivantes sont remplies, vous pouvez supprimer en toute sécurité l'index sous-jacent initial qui présentait des conflits de mapping :</p><ol><li><p>Un nouvel index sous-jacent a été correctement créé.</p></li><li><p>Les documents ont été déplacés vers le nouvel index et le nombre de documents correspond.</p></li><li><p>Les mappings ont été corrigés (ceux spécifiques au flux de données et ceux d'ECS).</p></li><li><p>Le flux de données intègre le nouvel index sous-jacent.</p></li><li><p>La politique ILM a été appliquée et a permis à l'index de sortir de sa phase chaude.</p></li></ol><p><strong>Important</strong> : sinon, avant de supprimer l'index initial, vous pouvez consulter la page <strong>Data Views</strong>. Sélectionnez <code>logs-*</code> et vérifiez que l'index sous-jacent réindexé (qui se termine par <code>-1</code>) apparaît maintenant dans la section <strong><code>long</code></strong>. L'index sous-jacent initial devrait toujours être présent sous <strong><code>keyword</code></strong>. Si l'index sous-jacent initial réindexé ne se trouve pas dans la section <strong><code>long</code></strong>, revenez en arrière pour vérifier les étapes précédentes et effectuer les corrections nécessaires.</p><p>Par exemple :</p>DELETE .ds-logs-filestream.generic-default-2026.04.14-000001<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt835a79be274513a3/6a17101aa929cf43c6ae0ab1/09d661b20a44929b4736a43eaa3df84180b25f30-2048x1295.png" alt="" /><p>Après avoir résolu les conflits, retournez à la page <strong>Data Views</strong> et sélectionnez <code>logs-*</code>. Si le conflit était uniquement lié à <code>log.offset</code>, aucun conflit ne devrait plus être listé. Si d'autres conflits étaient présents, l'index sous-jacent initial ne devrait plus apparaître dans la liste des conflits, et le nouvel index sous-jacent devrait désormais figurer dans la section <code>long</code>.</p><p>Vous pouvez également vérifier dans <strong>Discover</strong> que le champ <code>log.offset</code> affiche désormais les icônes appropriées.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt127cb539b70acada/6a17101ba929cfbc66ae0ab5/1c3bb7029c99aa4bc6b0931f39f5648654b35ccd-2048x1204.png" alt="" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltaa1eb678773c23d9/6a17101d4a531b00a636aa3b/0af1b1aa3a031c207aa5eb083696dd081d941e67-2048x1001.png" alt="" /><p>Poursuivez ce processus en répétant les étapes ci-dessus pour chaque index de sauvegarde présentant un conflit de mapping, jusqu'à ce que tous soient résolus avec succès.</p><p>Références :</p><ul><li><p><a href="https://www.elastic.co/docs/reference/ecs/ecs-field-reference">Référence de champ ECS</a></p></li><li><p><a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-reindex">Réindexer les documents</a></p></li></ul><h2>Conclusions</h2><p>En suivant les étapes décrites dans cet article, vous résoudrez les conflits de mapping et vous assurerez que toutes les nouvelles données sont correctement mappées. Pour ce faire, vous lierez les modèles de composants nécessaires à votre source de données. Ce processus permet non seulement de corriger les problèmes immédiats, mais aussi d'établir une méthode sécurisée et reproductible pour gérer les modifications de schéma à mesure que vos données et vos besoins évoluent.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-mapping-conflicts-reindex-data-streams</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-mapping-conflicts-reindex-data-streams</guid>
    <category><![CDATA[Opérations]]></category>
    <dc:creator><![CDATA[Lisa Larribas]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9654eb32edb4a44a/6a17101fcdacbf0ac17d2ad8/2f2573aa3d29b3a628e4fce606c803add2641501-720x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Fri, 24 Apr 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Pourquoi la recherche en e-commerce nécessite une gouvernance]]></title>
    <description><![CDATA[Découvrez pourquoi la recherche e-commerce échoue sans gouvernance et comment une couche de contrôle garantit des résultats prévisibles et axés sur l’intention, améliorant ainsi la récupération des données.]]></description>
    <content:encoded><![CDATA[<p>Pour l’e-commerce, il est crucial de pouvoir prendre en charge des types de requêtes variés et de natures diverses au sein d’un seul et même dispositif. Un acheteur cherchant des « oranges » veut le fruit lui-même, pas des articles incluant le terme « orange » (comme du jus ou de la confiture), ni des agrumes sémantiquement liés. Un client cherchant un « cadeau pour un grand-père gourmand » a besoin d’une découverte sémantique, et non d’une simple correspondance littérale par mots-clés.</p><p>La <em>recherche lexicale</em> (mise en correspondance de textes), la <em>recherche sémantique</em> (mise en correspondance de concepts) et la <em>recherche hybride</em> (combinaison de signaux lexicaux et sémantiques) ne résolvent pas ces problèmes à elles seules. La recherche lexicale peut renvoyer n’importe quel résultat contenant le mot « oranges », tandis qu’une recherche purement sémantique sur une requête à forte intention comme « oranges » peut s’élargir à des articles connexes, tels que des citrons ou des pamplemousses. La récupération hybride mélange ces signaux lexicaux et sémantiques, mais elle ne permet toujours pas de déterminer si cette requête doit être traitée comme navigationnelle, quelles contraintes doivent être imposées ou quelles politiques commerciales doivent s’appliquer. Le problème n’est pas lié à l’outil de récupération en soi, mais plutôt au manque d’un palier de gouvernance qui identifierait le type de requête et les restrictions à imposer en amont du processus de recherche.</p><p>Cet article se penche sur la gouvernance des moteurs de recherche e-commerce, les enjeux qu’elle représente et comment une couche de contrôle assure un « retrieval » fiable et pertinent.</p><h2>Que signifie la gouvernance dans la recherche sur les sites e-commerce ?</h2><p>Dans ce contexte, <em>la gouvernance</em> signifie l’introduction d’une couche de décision entre la requête de l’utilisateur et le moteur de recherche. Cette couche remplit les fonctions suivantes :</p><ul><li><p>Classifie l’intention de la requête : s’agit-il de navigation (« oranges ») ou de découverte (« cadeau pour grand-père ») ?</p></li><li><p>Applique des contraintes commerciales : quelles limites de catégorie, règles d'éligibilité, contraintes de disponibilité ou politiques de merchandising s'appliquent ?</p></li><li><p>Oriente vers la stratégie appropriée : faut-il utiliser la récupération lexicale, la récupération sémantique ou une approche hybride ?</p></li></ul><p>Une couche de gouvernance détermine l’approche de récupération à utiliser pour chaque requête, les contraintes à respecter et les politiques commerciales à appliquer avant que la recherche ne commence. Il est important de ne pas confondre la gouvernance avec la récupération hybride : la recherche hybride est une stratégie de récupération qui combine des signaux lexicaux et sémantiques, tandis que la gouvernance est la couche de décision en amont qui détermine s’il convient d’utiliser une approche lexicale, sémantique ou hybride.</p><h2>Le statu quo : l’implémentation « spaghetti » de la couche application</h2><p>Aujourd’hui, la solution retenue par de nombreux distributeurs consiste à injecter de la logique métier directement au niveau de l’application. Cette approche mène souvent à un <em>code spaghetti</em> : des milliers de lignes mêlant structures conditionnelles rigides, expressions régulières et modèles de recherche alambiqués.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdd7b33454d925cfd/6a1710f1e8fbce25ee39fd4d/f532b099ee103458e15563a711dae92952f8df02-1024x765.png" alt="Parallèle entre une application à logique fixe et Elasticsearch : voyez comment Elasticsearch facilite l’ordonnancement et l’extraction des résultats sans nécessiter de structures de contrôle manuelles et lourdes." /><p>Cette approche peut fournir les résultats de recherche souhaités, comme indiqué ci-dessus, mais elle crée des frictions opérationnelles importantes :</p><ul><li><p><strong>Contraintes liées à l’ingénierie :</strong> sans tickets de développement et sans cycles de déploiement prolongés (souvent de plusieurs semaines), les responsables métier ne disposent d’aucun levier pour faire évoluer le comportement de recherche.</p></li><li><p><strong>Fragmentation :</strong> la logique de recherche se retrouve éparpillée entre le code applicatif et les modèles de recherche, ce qui la rend difficile à expliquer ou à auditer, et rend toute évolution risquée.</p></li></ul><p>Même lorsque les équipes reconnaissent la nécessité du routage, le débat se concentre souvent sur la mauvaise question : quelle méthode de récupération choisir.</p><h2>Le faux choix : lexical ou sémantique ou hybride</h2><p>Les équipes de recherche présentent souvent le défi comme un choix de stratégie de récupération : lexicale/BM25 versus sémantique/vecteurs versus hybride. Cette approche est compréhensible (les méthodes de récupération sont importantes), mais elle passe à côté du mode d'échec le plus courant dans les déploiements réels, à savoir qu'utiliser une seule approche de récupération pour toutes les requêtes donnera des résultats sous-optimaux.</p><p>La recherche commerciale est un mélange d'intentions fondamentalement différentes :</p><ul><li><p><strong>Recherche de navigation déterministe, intention marquée</strong> (ex. : « oranges », « lait », « chocolat sans arachides », « huile d’olive à petit prix »).</p></li><li><p><strong>Découverte exploratoire</strong> (« blouson pour la randonnée en montagne », « cadeau pour un enfant de 12 ans qui aime la robotique »).</p></li><li><p><strong>Contraintes opérationnelles</strong> (disponibilité, taille, prix, couleur).</p></li><li><p><strong>Merchandising et campagnes</strong> (Boost, Bury, campagnes saisonnières).</p></li></ul><p>Lorsque le système achemine tout cela via la même stratégie de récupération, les résultats sont souvent systématiquement erronés de manière prévisible, car le modèle opérationnel manque de gouvernance. Lorsque les équipes ne reconnaissent pas cela comme une lacune de gouvernance, elles réagissent avec le seul levier dont elles disposent : davantage de réglages.</p><h2>Pourquoi le réglage de la pertinence peut devenir cyclique</h2><p>Sans couche de routage, la « pertinence » se transforme souvent en un carnet de commandes interminable :</p><ul><li><p>Pourquoi cette requête affiche-t-elle les accessoires au-dessus du produit principal ?</p></li><li><p>Pourquoi cette requête phare affiche-t-elle tout à coup des produits apparentés plutôt que des correspondances exactes ?</p></li><li><p>Pourquoi les résultats ont-ils changé après l’ajout de synonymes, l’ajustement des analyseurs ou l’activation du mode hybride ?</p></li><li><p>Pourquoi l'équipe métier a-t-elle besoin d'une version d'ingénierie pour corriger une seule requête ?</p></li></ul><p>En réponse, les équipes intensifient les ajustements : ajout de synonymes, hausse des pondérations, nouveaux essais de réordonnancement et prolifération de cas particuliers dans le code de l’application. Cela peut donner des résultats temporaires, toutefois la solution reste instable : sans un étage décisionnel clair pour identifier la nature de la requête et appliquer les restrictions nécessaires en amont, le système demeure imprévisible.</p><h2>Structure des intentions e-commerce : entre requêtes fréquentes et requêtes spécifiques de la longue traîne</h2><p>Nous employons ici les appellations « head » et « tail » pour illustrer de manière concrète les types de requêtes de navigation et de découverte les plus fréquents sur les sites de vente en ligne. Dans le monde réel, de nombreuses requêtes présentent des caractéristiques propres à ces deux catégories :</p><h3>Requêtes principales (intention déterministe)</h3><p>Ce sont des requêtes de navigation ciblées pour lesquelles l’utilisateur a une idée précise de son besoin :</p><ul><li><p>Intention à un seul élément (« oranges », « lait », « pain »).</p></li><li><p>Des marques exactes ou des familles de produits (« iPhone 15 Pro », « Diet Coke »).</p></li><li><p>Des références (SKU), des numéros de modèles ou des tailles (« ABC123 », « Air Max 270 »).</p></li></ul><p>Pour ces requêtes, la récupération lexicale peut gérer la correspondance des jetons (faire correspondre les mots), mais l’entreprise s’attend également à ce que les contraintes soient respectées, que les classements soient prévisibles et que les résultats soient contrôlables. Un gestionnaire de catalogue doit garantir que les résultats d’une requête respectent le cloisonnement des catégories, les règles de disponibilité et les priorités stratégiques de l’entreprise.</p><p>Une gouvernance est nécessaire pour mettre en œuvre la résolution envisagée. Par exemple, « oranges » doit correspondre à la catégorie des produits agricoles, et non au jus d'orange, à la marmelade d'orange ou au soda à l'orange.</p><h3>Requêtes extrêmes (découverte exploratoire)</h3><p>Il s’agit de requêtes descriptives, riches en intentions, dans lesquelles les clients explorent :</p><ul><li><p>« Cadeau pour un grand-père gourmand »</p></li><li><p>« Blouson pour la randonnée en montagne »</p></li><li><p>« Chaussures pour rester debout toute la journée »</p></li></ul><p>La récupération lexicale est souvent difficile à mettre en œuvre. La récupération sémantique excelle car elle peut l’intention de la requête au produit, même lorsque les termes ne correspondent pas littéralement. Mais la récupération sémantique seule est rarement suffisante non plus. Les requêtes réelles nécessitent souvent l'application de contraintes, quelle que soit la méthode de recherche utilisée.</p><h2>Le respect des contraintes est indépendant de la méthode de recherche utilisée</h2><p>L'application de contraintes à la récupération sémantique ne signifie pas <em>recherche hybride</em>. Ces notions sont orthogonales. Les contraintes (filtres, boosts) au sein d’Elasticsearch sont applicables à n’importe quel mode de récupération : lexical, sémantique ou hybride. Toute la difficulté réside dans le choix de l’interprétation de la requête, des contraintes à respecter et de la méthode de récupération des données la plus appropriée.</p><p>Voici quelques exemples de requêtes combinant la récupération avec des contraintes strictes :</p><ul><li><p><strong>Oranges :</strong> recherche lexicale sur le terme « oranges » associée à un filtre de catégorie (ex. : « Fruits »), excluant ainsi la confiture d’orange, le jus d’orange ou les boissons gazeuses à l’orange.</p></li><li><p><strong>Fruits riches en vitamine C à moins de 4 $ :</strong> recherche sémantique pour cibler l’aspect nutritionnel, complétée par des restrictions pour ne conserver que la catégorie des fruits et les articles dont le prix ne dépasse pas 4 $.</p></li><li><p><strong>Chaussures confortables pour le travail :</strong> recherche sémantique pour l'intention contextuelle plus une contrainte de catégorie limitant les résultats aux chaussures.</p></li></ul><p>Ces requêtes ne peuvent pas être traitées par une seule approche :</p><ul><li><p>La <strong>récupération lexicale pure</strong> s’avère ici limitée, car des locutions comme « riche en vitamine C » ou « confortable » ne correspondent pas toujours à des attributs propres et structurés. Il peut être nécessaire de les inférer en analysant les descriptions, les évaluations d’utilisateurs ou les caractéristiques des articles.</p></li><li><p>Une <strong>recherche sémantique pure</strong> peut également montrer ses limites ; sans l’application de contraintes, une requête du type « fruits riches en vitamine C » risque de proposer des compléments alimentaires, des boissons fruitées ou des légumes, dépassant alors le cadre de la catégorie et des prix initialement prévus.</p></li></ul><p>Une couche de gouvernance détermine si une requête nécessite une récupération lexicale, une compréhension sémantique, l’application de contraintes, ou une combinaison de ces éléments. Faute d’une telle structure, les équipes e-commerce pourraient être confrontées aux situations suivantes :</p><ul><li><p><strong>Sur-filtrage :</strong> appliquer une recherche lexicale à des requêtes sémantiques (comme « cadeau pour grand-père »), ce qui limite indûment les résultats.</p></li><li><p><strong>Sous-contrainte : </strong>utiliser des requêtes sémantiques pour des requêtes de tête à forte intention (par exemple, « oranges »).</p></li></ul><p>En matière de gouvernance, la difficulté réside dans la création d’un système pouvant appliquer le traitement le plus approprié selon la classe de requête rencontrée.</p><h2>Ce qui se passe en l’absence de gouvernance</h2><p>Le mode de défaillance le plus courant est simple : les équipes prennent la requête brute de l’utilisateur et la transmettent directement à une stratégie de récupération unique (lexicale, sémantique ou hybride), sans couche de gouvernance intermédiaire.</p><h3>La récupération lexicale ne parvient pas à la résolution prévue</h3><p>Lorsqu'un utilisateur recherche « oranges », une stratégie de recherche lexicale peut renvoyer tout élément contenant ce jeton : jus d'orange, marmelade d'orange ou soda à l'orange. Le système a correctement associé le terme, mais sans gouvernance, il peut ne pas résoudre le contexte d'achat prévu (le fruit).</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1b4595242ea6eb05/6a1710f35091684ba3e1bbd0/99abc7a46f9c56a26a68d0a089d7ab830b9b5568-1560x814.png" alt=" Illustration montrant comment une requête unique pour « oranges » renvoie différents résultats associés, tels que de la marmelade, des oranges fraîches et du soda à l’orange." /><h3>La récupération sémantique va au-delà des contraintes prévues</h3><p>Lorsqu’un utilisateur recherche des « oranges », un système sémantique peut récupérer des articles conceptuellement liés à travers des concepts de produits proches. Le système peut comprendre correctement le domaine plus large (fruits ou produits), mais sans une gouvernance explicite, il peut encore s'élargir au-delà de la contrainte voulue par l'utilisateur (notamment les oranges).</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltff1aba60c7b13fc8/6a1710f58b73cb3cef18a117/c9de86363ecbed499fe48259f47b3c5b2c26bc43-1568x796.png" alt="Diagramme illustrant comment une requête pour « oranges » est acheminée vers différentes catégories de fruits, notamment les pommes, les oranges et les fruits mélangés." /><h3>L'écart, c'est la gouvernance</h3><p>Ce qu’il faut, c’est une couche de décision en amont qui détermine l’intention de la requête et impose les bonnes contraintes avant même que la récupération ne commence. Cette approche corrige les types d’erreurs suivants :</p><ul><li><p>Éléments similaires ou connexes apparaissant aux côtés de ce que l'utilisateur voulait réellement.</p></li><li><p>Des frontières de catégories floues (« boissons » par rapport à « produits frais »).</p></li><li><p>Incapacité à mettre en œuvre des augmentations saisonnières ou des campagnes.</p></li><li><p>Des résultats imprévisibles et inexplicables.</p></li></ul><h2>Compréhension de l'intention et routage : le plan de contrôle nécessaire</h2><p>Un système de recherche gouverné introduit un plan de contrôle léger devant la recherche (avant d’exécuter une requête dans Elasticsearch). Ce mécanisme de contrôle sera examiné plus en profondeur dans les <a href="https://www.elastic.co/search-labs/blog/ecommerce-search-governance-control-plane-architecture">troisième </a>et <a href="https://www.elastic.co/search-labs/blog/elasticsearch-percolator-search-governance">quatrième </a>volets de cette série ; ici, nous nous concentrons sur ses capacités plutôt que sur ses modalités techniques :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt373bd838e1751998/6a1710f74a531b1e5436aa57/88c3d0f9731a128d73a765dcdffed897308110a6-2680x766.png" alt="Schéma montrant comment différentes requêtes sont acheminées via un plan de contrôle vers BM25 ou vers des résultats de recherche sémantiques." /><p>Un plan de contrôle peut détecter l'intention, appliquer des politiques commerciales et assurer la stratégie de récupération appropriée comme suit :</p><p><strong>1. Détectez les signaux d'intention</strong></p><ul><li><p>Cette requête relève-t-elle de la navigation ou de la découverte ?</p></li><li><p>La requête correspond-elle à un produit phare identifié (lait, pain, bananes) ?</p></li><li><p>Y a-t-il une correspondance identifiée avec un produit, une marque ou une catégorie spécifique (par exemple, « oranges » devrait être redirigé vers les produits frais) ?</p></li><li><p>La requête est-elle un modèle de type SKU ?</p></li><li><p>Cette recherche correspond-elle à une campagne en cours ou à une règle saisonnière (par exemple, mettre en avant les produits liés à la dinde lors des fêtes de fin d’année) ?</p></li><li><p>Cette recherche contient-elle des restrictions implicites (catégorie, caractéristiques, éléments à exclure, prix/format/coloris) ?</p></li></ul><p><strong>2. Appliquer les politiques de gouvernance et commerciales</strong></p><ul><li><p>Appliquez d'abord les contraintes déterministes (catégorie/attribut/négation/disponibilité).</p></li><li><p>Appliquer les politiques de merchandising actives (promotion/enterrement/épinglage/remplacement).</p></li><li><p>Résoudre les conflits à l’aide de règles de priorité (par exemple, les dérogations liées aux campagnes par rapport aux politiques globales).</p></li></ul><p><strong>3. Orientation vers la stratégie de récupération appropriée</strong></p><ul><li><p>Lexicale (rapide, déterministe) pour les requêtes principales de navigation/à forte intention.</p></li><li><p>Extraction sémantique pour les requêtes True Discovery.</p></li><li><p>Une approche hybride où le cumul des signaux lexicaux et sémantiques crée de la valeur, tout en respectant des règles métier explicites.</p></li></ul><p>Dans les faits, la sortie du plan de contrôle n’est pas une simple commande du type « utiliser la recherche hybride » ou « utiliser la recherche sémantique ». Il s’agit d’un plan de recherche régulé, incluant une analyse de l’intention de l’utilisateur, les politiques et contraintes applicables, ainsi que la stratégie d’extraction à lancer. Pour illustrer ce propos, prenons quelques exemples simples :</p><p>Requête d'acheteur</p><p>Interprétation dirigée</p><p>Exemple de plan de récupération</p><p>« chocolat sans arachides »</p><p>Requête orientée produit avec une contrainte d’exclusion stricte</p><p>Recherche lexicale sur le chocolat, avec un filtre d’exclusion pour les produits contenant des arachides</p><p>« huile d’olive bon marché »</p><p>Requête produit/catégorie avec contrainte de prix</p><p>Récupération lexicale pour l'huile d'olive avec un filtre de prix plafonné au seuil du détaillant pour les produits bon marché</p><p>« fruit riche en vitamine C en moins de 4 $ »</p><p>Requête de découverte nécessitant une compréhension sémantique et des contraintes strictes</p><p>Recherche sémantique pour l'intention nutritionnelle, limitée à la catégorie des fruits et filtrée aux produits d'un prix inférieur à 4 $</p><p>Un plan de contrôle sélectionne la politique et la stratégie de récupération appropriées pour chaque requête de manière cohérente, prévisible et à grande échelle. Cette approche fiabilise les méthodes de recherche complexes en environnement de production, dans la mesure où les restrictions liées à l’intention priment et où les choix de routage sont clairement définis plutôt que suggérés.</p><h2>Comment cela se rapporte à d'autres approches</h2><p>Certaines équipes s’appuient sur des modèles de plongements sémantiques plus performants pour affiner la compréhension des produits, ce qui permet d’accroître sensiblement la pertinence de la recherche sémantique. Certaines équipes privilégient des méthodes de reclassement comme le <a href="https://www.elastic.co/docs/solutions/search/ranking/learning-to-rank-ltr">Learning To Rank (LTR)</a>, qui permettent d’ajuster l’ordre des résultats selon l’interaction des utilisateurs ou des indicateurs métier une fois le « retrieval » effectué. Les deux sont précieux et souvent complémentaires. De meilleurs plongements améliorent la correspondance de similarité. Le reclassement améliore l'ordre parmi les candidats récupérés.</p><p>La gouvernance traite un aspect différent de la problématique : elle intervient en amont du processus de récupération des données. Ce plan définit la stratégie de recherche (lexicale, sémantique ou hybride), impose les contraintes déterministes adéquates et identifie les requêtes nécessitant l’application conjointe de plusieurs politiques d’entreprise.</p><h2>Ce que permet un plan de contrôle gouverné</h2><p>Une fois qu'une couche de gouvernance est mise en place, le modèle opérationnel change fondamentalement. Les requêtes critiques pour les revenus deviennent prévisibles. Les équipes métier peuvent mettre à jour les comportements de recherche sans attendre les cycles de publication de l'ingénierie. Les techniques de récupération de données sophistiquées, comme les modèles sémantiques ou hybrides, peuvent être déployées de manière incrémentale, sécurisées par un aiguillage et des barrières de sécurité, au lieu d’être activées de façon binaire à l’échelle du système.</p><p>Le <a href="https://www.elastic.co/search-labs/blog/ecommerce-search-governance-zero-deploy">prochain article</a> de cette série examine à quoi ressemble ce modèle opérationnel dans la pratique et explique pourquoi il peut être tout aussi important que la technologie de recherche qui le sous-tend.</p><p>Si la correction d’une requête à fort impact financier nécessite l’ouverture d’un ticket Jira et un déploiement technique, le blocage ne se situe pas au niveau du moteur de recherche, mais bien au niveau du modèle d’exploitation. Le commerce en ligne actuel doit pouvoir transformer une intention métier en un comportement de recherche encadré et vérifiable, avec rapidité et sécurité, tout en tirant parti des méthodes de récupération de données sophistiquées quand elles génèrent une valeur ajoutée concrète.</p><h2>À suivre dans cette série</h2><p>Les approches abordées dans cette série interviennent en amont de la recherche : il s'agit de traduire l'intention métier en une stratégie de requête adaptée avant même que la génération de la requête ne commence. Dans le <a href="https://www.elastic.co/search-labs/blog/ecommerce-search-governance-zero-deploy">prochain article</a>, nous passerons du problème technique au problème opérationnel : que se passe-t-il lorsque les équipes métier peuvent modifier le comportement de recherche sans intervention technique, et pourquoi la gouvernance garantit la sécurité de cette démarche.</p><h2>Mettre en pratique la recherche e-commerce réglementée</h2><p>Les freins techniques, la fragilité de la couche logique applicative et l’instabilité des résultats de recherche sont autant de défis que les services Elastic vous aident à relever dans le cadre de prestations pour le commerce en ligne de grande envergure. L’architecture de plan de contrôle gouverné décrite dans cette série a été conçue par l’ingénierie des services Elastic.</p><p>Que vous perdiez un temps précieux en développement pour ajuster vos stratégies de mise en avant ou que l’optimisation de votre moteur de recherche stagne, nous sommes là pour analyser votre infrastructure et mettre en place une solution de recherche structurée, directement éditable par vos experts métier. Contactez <a href="https://www.elastic.co/consulting">Elastic Services</a>.  </p><h2>Rejoignez la discussion</h2><p>Avez-vous des questions sur la gouvernance de la recherche, les stratégies de récupération ou l'architecture de recherche e-commerce ? Participez à la <a href="https://discuss.elastic.co/">discussion élargie de la communauté Elastic</a>.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/ecommerce-search-governance-improve-retrieval</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/ecommerce-search-governance-improve-retrieval</guid>
    <category><![CDATA[Opérations]]></category>
    <dc:creator><![CDATA[Alexander Marquardt,Honza Král,Taylor Roy]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt840c7a0a5b92080f/6a1710f967045b3e5445c2cd/3793259b01a5653a7520393a2f006610de0d21e7-1280x720.png" length="0" type="image/png"/>
    <pubDate>Thu, 09 Apr 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Débit plus élevé et latence plus faible : Elastic Cloud Serverless sur AWS bénéficie d'une amélioration significative des performances–]]></title>
    <description><![CDATA[Nous avons mis à niveau l'infrastructure AWS pour Elasticsearch Serverless vers du matériel plus récent et plus performant. Découvrez comment cette amélioration considérable des performances permettent des requêtes plus rapides, une scalabilité plus réactive et des coûts réduits.]]></description>
    <content:encoded><![CDATA[<p>Elastic Cloud Serverless est déjà la solution de référence pour les développeurs souhaitant créer des applications de recherche et d'IA performantes sans se soucier de la gestion de l'infrastructure. Désormais, les performances de vos projets sans serveur atteignent un tout autre niveau.</p><p>Nous avons effectué une mise à niveau majeure de l'infrastructure pour tous les projets <a href="https://www.elastic.co/cloud/serverless">Elastic Cloud Serverless</a> exécutés sur AWS, en migrant vers du matériel plus récent et plus performant. Cette modification a été déployée automatiquement sur tous les projets sans serveur. Vous bénéficiez maintenant <strong>d'un débit plus élevé et d'une latence plus faible</strong> pour les projets sans serveur Elasticsearch, Elastic Observability et Elastic Security sur AWS.</p><h2><strong>Principaux avantages en termes de performances pour les développeurs</strong></h2><p>La nouvelle infrastructure matérielle d'AWS sous-tend tout ce que vous faites avec Elastic Cloud Serverless, ce qui se traduit par des avantages tangibles au niveau de la vitesse et de la réactivité de vos applications.</p><h3><strong>Latence des requêtes réduite… débit accru</strong></h3><p>Le matériel amélioré augmente considérablement la vitesse des ressources de calcul ; vos requêtes de recherche sont ainsi traitées plus rapidement que jamais.</p><ul><li><p><strong>Recherche et recherche vectorielle</strong> : que vous exécutiez des recherches full text traditionnelles ou que vous utilisiez la recherche vectorielle de pointe pour vos <a href="https://www.elastic.co/generative-ai">applications d'IA générative et de génération augmentée par récupération (RAG)</a>, vous constaterez une diminution notable de la latence. Une analyse comparative interne a révélé une diminution moyenne de 35 % de la latence de recherche.</p></li><li><p><strong>Indexation plus rapide</strong> : les taux d'ingestion de données sont optimisés, vous permettant d'indexer d'énormes volumes de données et des documents complexes avec un débit accru. Ceci est crucial pour les applications qui nécessitent une visibilité des données en temps quasi‑réel. L'évaluation comparative interne a montré une augmentation moyenne de 26 % du débit d'indexation.</p></li></ul><h3><strong>Performances constantes sous charge</strong></h3><p>Elastic Cloud Serverless est conçu pour s'adapter automatiquement et dynamiquement en temps réel à la demande, minimisant ainsi la latence, quelle que soit votre charge de travail. Grâce à cette amélioration matérielle, le scaling est désormais plus performant et réactif.</p><ul><li><p><strong>Gestion facile des pics de charge</strong> : qu'il s'agisse d'une augmentation soudaine du trafic utilisateur ou d'une ingestion massive de données par lots, la nouvelle infrastructure garantit un scaling vertical plus efficace sur vos ressources de recherche et d'indexation afin de maintenir une latence faible de façon constante.</p></li><li><p><strong>Découplage optimisé calcul‑stockage</strong> : l'architecture sans serveur sépare le calcul et le stockage, ce qui permet aux charges de travail de scaler indépendamment pour des performances et une rentabilité optimales. Le matériel plus rapide améliore la couche de calcul, maximisant l'efficacité de cette conception découplée.</p></li></ul><h2><strong>Sous le capot : résultats des analyses comparatives internes</strong></h2><p>Pour quantifier l'impact de la mise à niveau de notre infrastructure AWS, l'équipe d'ingénierie d'Elastic a mené des tests de performance internes complets sur un large éventail de charges de travail sans serveur. Ces charges de travail ont fourni des preuves concrètes des améliorations de performances que vous pouvez attendre de vos applications, quel que soit votre cas d'utilisation.</p><h3><strong>L'approche d'analyse comparative</strong></h3><p>Nous avons concentré nos tests sur les indicateurs clés qui influencent directement l'expérience développeur et la réactivité des applications : le temps de réponse (c'est-à-dire la latence) et le débit lors des opérations de recherche et d'indexation.</p><ul><li><p><strong>Test des charges de travail</strong> : les tests comprenaient des opérations de recherche à haute simultanéité typiques des applications destinées aux utilisateurs, des requêtes de recherche vectorielle complexes et l'ingestion/l'indexation de données à fort volume pour des cas d'utilisation d'observabilité et de sécurité. Plus précisément, notre méthodologie de test a utilisé des ensembles de données <a href="https://github.com/elastic/rally-tracks/tree/master">accessibles au public</a> <a href="https://github.com/elastic/rally-tracks/tree/master">pour Rally</a>, l'outil d'évaluation comparative d'Elastic.</p><ul><li><p><a href="https://github.com/elastic/rally-tracks/tree/3bedd51/wikipedia"><code>wikipedia</code></a>: Un ensemble de données issu d'un instantané du contenu textuel de Wikipédia, pour mesurer les performances de recherche textuelle à usage général.</p></li><li><p><a href="https://github.com/elastic/rally-tracks/tree/3bedd51/msmarco-passage-ranking"><code>MSMARCO-Passage-Ranking</code></a>: Un ensemble de données issu de Microsoft Machine Reading Comprehension (MS MARCO), pour mesurer les performances de recherche sur des champs vectoriels épars.</p></li><li><p><a href="https://github.com/elastic/rally-tracks/tree/3bedd51/openai_vector"><code>OpenAI_Vector</code></a>: Un ensemble de données issu du NQ de BEIR et enrichi d'embeddings générés par le modèle <code>text-embedding-ada-002</code> d'OpenAI, pour évaluer les performances de recherche sur des champs vectoriels denses.</p></li></ul></li><li><p><strong>Mesure</strong> : nous avons comparé les performances de l'ancienne et de la nouvelle infrastructure, en mesurant la latence au 99e percentile (P99) afin de capturer les performances les plus mauvaises et le nombre d'opérations par seconde, en tenant compte de la latence de queue. Chaque piste a été exécutée cinq fois pour chaque profil de matériel afin de garantir la cohérence des résultats.</p></li><li><p><strong>L'objectif</strong> : Notre objectif était de valider la capacité de l'infrastructure à fournir <strong>des performances plus rapides et plus prévisibles</strong> de manière constante, même pendant les périodes d'autoscaling rapide.</p></li></ul><h3><strong>Résumé des données de performance</strong></h3><p>Les résultats confirment des gains d'efficacité et de rapidité significatifs. Ces gains se traduisent directement par des temps de réponse plus courts pour vos utilisateurs et par une réduction des coûts opérationnels grâce à la possibilité d'effectuer la même quantité de travail avec moins de ressources de calcul.</p><p>Les tableaux suivants décrivent en détail les améliorations quantitatives. Plus les valeurs sont élevées, meilleur est le débit ; plus les valeurs sont faibles, meilleure est la latence.</p><p><strong>Résultats des recherches de référence :</strong></p><p>Référence</p><p>Comparatif</p><p>Ancienne infrastructure</p><p>Nouvelle infrastructure</p><p>Différentiel</p><p>'wikipedia' (texte brut)</p><p>Débit des opérations de recherche (ops/s)</p><p>729</p><p>1107</p><p>+52 %</p><p>'wikipedia' (texte brut)</p><p>Latence des opérations de recherche (p99, ms)</p><p>56</p><p>35</p><p>-37 %</p><p>`MSMARCO-Passage-Ranking` (vecteurs épars)</p><p>Débit des opérations de recherche (ops/s)</p><p>22</p><p>31</p><p>+40 %</p><p>`MSMARCO-Passage-Ranking` (vecteurs épars)</p><p>Latence des opérations de recherche (p99, ms)</p><p>108</p><p>67</p><p>-38 %</p><p>'OpenAI_Vector' (vecteurs denses)</p><p>Débit des opérations de recherche (ops/s)</p><p>475</p><p>624</p><p>+31 %</p><p>'OpenAI_Vector' (vecteurs denses)</p><p>Latence des opérations de recherche (p99, ms)</p><p>35</p><p>22</p><p>-37 %</p><p><strong>Résultats de référence de l'indexation :</strong></p><p>Référence</p><p>Comparatif</p><p>Ancienne infrastructure</p><p>Nouvelle infrastructure</p><p>Différentiel</p><p>'wikipedia' (texte brut)</p><p>Débit des opérations de recherche (ops/s)</p><p>2 845</p><p>3 220</p><p>+13 %</p><p>'wikipedia' (texte brut)</p><p>Latence des opérations de recherche (p99, ms)</p><p>1769</p><p>1120</p><p>-37 %</p><p>`MSMARCO-Passage-Ranking` (vecteurs épars)</p><p>Débit des opérations de recherche (ops/s)</p><p>7087</p><p>8 900</p><p>+26 %</p><p>`MSMARCO-Passage-Ranking` (vecteurs épars)</p><p>Latence des opérations de recherche (p99, ms)</p><p>824</p><p>677</p><p>-18 %</p><p>'OpenAI_Vector' (vecteurs denses)</p><p>Débit des opérations de recherche (ops/s)</p><p>2972</p><p>3187</p><p>+7%</p><p>'OpenAI_Vector' (vecteurs denses)</p><p>Latence des opérations de recherche (p99, ms)</p><p>2946</p><p>2944</p><p>0 %</p><h2><strong>L'avantage supplémentaire : réduction des coûts</strong></h2><p>Bien que notre priorité soit de fournir des performances à faible latence, l'efficacité du nouveau matériel a également un impact direct et positif sur les coûts des projets Elasticsearch.</p><p>La <a href="https://www.elastic.co/pricing/serverless-search">tarification d'Elasticsearch Serverless</a> est basée sur l'utilisation : vous ne payez que pour les ressources d'ingestion et de recherche que vous consommez. Grâce à un matériel plus récent et plus rapide, vos charges de travail s'exécuteront souvent avec moins de ressources, ce qui se traduit par une réduction des coûts pour la plupart des projets. Vous bénéficiez ainsi de performances optimales sans le surcoût : l'efficacité par excellence.</p><h2><strong>Qu'est-ce que cela signifie pour vous, le développeur ?</strong></h2><p>Cette mise à niveau de l'infrastructure est entièrement gérée par Elastic ; vous n'avez donc rien à faire, aucune migration ni modification de configuration. L'amélioration est immédiate et automatique pour tous vos projets sans serveur sur AWS.</p><p>Cette mise à niveau vous permet de :</p><ul><li><p><strong>Créez des applications plus rapides</strong> : concentrez-vous sur la vélocité des fonctionnalités, en sachant que votre plateforme de recherche sous-jacente offre la vitesse exigée par vos utilisateurs.</p></li><li><p><strong>Innovez en confiance</strong> : déployez de nouvelles fonctionnalités de recherche, d'observabilité et de sécurité, y compris des capacités d'IA complexes telles que la recherche vectorielle et le classement par pertinence, sachant que la plateforme peut gérer la charge à des performances optimales.</p></li><li><p><strong>Simplifiez votre stack</strong> : utilisez un service entièrement géré qui prend en charge l'infrastructure, la planification de la capacité et le scaling, et concentrez‑vous sur votre code et vos données.
</p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-serverless-aws-performance-boost</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-serverless-aws-performance-boost</guid>
    <category><![CDATA[Elastic Cloud Serverless]]></category>
    <category><![CDATA[Opérations]]></category>
    <dc:creator><![CDATA[Pete Galeotti,Yuvraj Gupta,Rachel Forshee]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt399bcc5a2e55bfe0/6a1708b45091684557e1ba3c/3aa0b481994d2445ba979d3c79fff64c5ee6676a-720x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Wed, 14 Jan 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Amélioration de la pertinence des modèles d'intégration multilingues grâce à un système hybride de classement des recherches]]></title>
    <description><![CDATA[Découvrez comment améliorer la pertinence des résultats de recherche du modèle d'intégration multilingue E5 en utilisant le reranker de Cohere et la recherche hybride dans Elasticsearch.]]></description>
    <content:encoded><![CDATA[<h2>Introduction</h2><p>Dans la <a href="https://www.elastic.co/search-labs/blog/multilingual-embedding-model-deployment-elasticsearch">dernière partie de cette série</a>, nous avons déployé le modèle E5 pré-entraîné d'Elastic (ainsi que d'autres modèles d'intégration de texte multilingue de Hugging Face) et nous nous sommes plongés dans la génération d'intégrations vectorielles denses à partir de vos données textuelles à l'aide d'Elasticsearch et de Kibana. Dans ce blog, nous examinerons les résultats de ces encastrements et mettrons en évidence les avantages significatifs de l'utilisation d'un modèle multilingue.</p><p>Maintenant que nous avons notre index <code>coco_multilingual</code>, la recherche nous donnera des documents en plusieurs langues, avec le champ "en" pour référence :</p># GET coco_multilingual/_search
    {
       "_index": "coco_multilingual",
       "_id": "WAiXQJYBgf6odR9bLohZ",
       "_score": 1,
       "_source": {
         "description": "Ein Parkmeßgerät auf einer Straße mit Autos",
         "en": "A row of parked cars sitting next to parking meters.",
         "language": "de",
         "vector_description": {...}
       }
     },
     . . .<h2>Effectuer une recherche en anglais</h2><p>Essayons d'effectuer la recherche en anglais et voyons ce qu'il en est :</p>GET coco_multi/_search
{
"size": 10,
"_source": [
  "description", "language", "en"
],
"knn": {
  "field": "vector_description.predicted_value",
  "k": 10,
  "num_candidates": 100,
  "query_vector_builder": {
    "text_embedding": {
      "model_id": ".multilingual-e5-small_linux-x86_64_search",
      "model_text": "query: kitty"
    }
  }
}
}{
       "_index": "coco_multi",
       "_id": "JQiXQJYBgf6odR9b6Yz0",
       "_score": 0.9334303,
       "_source": {
         "description": "Eine Katze, die in einem kleinen, gepackten Koffer sitzt.",
         "en": "A brown and white cat is in a suitcase.",
         "language": "de"
       }
     },
      {
       "_index": "coco_multi",
       "_id": "3AiXQJYBgf6odR9bFod6",
       "_score": 0.9281012,
       "_source": {
         "description": "Una bambina che tiene un gattino vicino a una recinzione blu.",
         "en": "A little girl holding a kitten next to a blue fence.",
         "language": "it"
       }
     },
     . . .<p>Ici, même si la requête semble faussement simple, nous recherchons les enchâssements numériques du mot "kitty" dans tous les documents, dans toutes les langues, sous le capot. Et comme nous effectuons une recherche vectorielle, nous pouvons rechercher sémantiquement tous les mots susceptibles d'être liés à "kitty" : "chat", "chaton", "félin", "gatto" (italien), "mèo" (vietnamien), 고양이 (coréen), 猫 (chinois), etc. Ainsi, même si ma requête est en anglais, nous pouvons rechercher du contenu dans toutes les autres langues. Par exemple, la recherche d'un chat l<code>ying on something</code> donne des documents en italien, en néerlandais ou en vietnamien. Une question d'efficacité !</p><h2>Recherche de contenu dans d'autres langues</h2>GET coco_multi/_search
{  
 "size": 100,
 "_source": [
   "description", "language", "en"
 ],
 "knn": {
   "field": "vector_description.predicted_value",
   "k": 50,
   "num_candidates": 1000,
   "query_vector_builder": {
     "text_embedding": {
       "model_id": ".multilingual-e5-small_linux-x86_64_search",
       "model_text": "query: kitty lying on something"
     }
   }
 }
}{
 "description": "A black kitten lays on her side beside remote controls.",
 "en": "A black kitten lays on her side beside remote controls.",
 "language": "en"
},
{
 "description": "un gattino sdraiato su un letto accanto ad alcuni telefoni ",
 "en": "A black kitten lays on her side beside remote controls.",
 "language": "it"
},
{
 "description": "eine Katze legt sich auf ein ausgestopftes Tier",
 "en": "a cat lays down on a stuffed animal",
 "language": "de"
},
{
 "description": "Một chú mèo con màu đen nằm nghiêng bên cạnh điều khiển từ xa.",
 "en": "A black kitten lays on her side beside remote controls.",
 "language": "vi"
}
. . .<p>De même, une recherche par mot-clé pour "chat" en coréen ("고양이") donnera également des résultats significatifs. Ce qui est spectaculaire ici, c'est que nous n'avons même pas de documents en coréen dans cet index !</p>GET coco_multi/_search
{
 "size": 100,
 "_source": [
   "description", "language", "en"
 ],
 "knn": {
   "field": "vector_description.predicted_value",
   "k": 50,
   "num_candidates": 1000,
   "query_vector_builder": {
     "text_embedding": {
       "model_id": ".multilingual-e5-small_linux-x86_64_search",
       "model_text": "query: 고양이"
     }
   }
 }
} {
       {
         "description": "eine Katze legt sich auf ein ausgestopftes Tier",
         "en": "a cat lays down on a stuffed animal",
         "language": "de"
       }
     },
     {
       {
         "description": "Một con chó và con mèo đang ngủ với nhau trên một chiếc ghế dài màu cam.",
         "en": "A dog and cat lying  together on an orange couch. ",
         "language": "vi"
       }
     },<p>Cela fonctionne parce que le modèle d'intégration représente le sens dans un espace sémantique partagé, ce qui permet de retrouver des images pertinentes même si la requête est formulée dans une langue différente de celle des légendes indexées.</p><h2>Augmenter la pertinence des résultats de recherche grâce à la recherche hybride et au reranking</h2><p>Nous sommes heureux que les résultats pertinents soient apparus comme prévu. Mais dans le monde réel, par exemple dans le commerce électronique ou dans les applications RAG qui doivent se limiter aux 5 à 10 premiers résultats les plus pertinents, nous pouvons utiliser un modèle de classement pour hiérarchiser les résultats les plus pertinents.</p><p>Par exemple, une requête demandant "quelle est la couleur du chat ?" en vietnamien donnera un grand nombre de résultats, mais les 1 ou 2 premiers ne seront pas forcément les plus pertinents.</p>GET coco_multi/_search
{
 "size": 20,
 "_source": [
   "description",
   "language",
   "en"
 ],
 "knn": {
   "field": "vector_description.predicted_value",
   "k": 20,
   "num_candidates": 1000,
   "query_vector_builder": {
     "text_embedding": {
       "model_id": ".multilingual-e5-small_linux-x86_64_search",
       "model_text": "query: con mèo màu gì?"
     }
   }
 }
}<p>Les résultats mentionnent tous le chat, ou une forme de couleur :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt979f5944b1708042/6a17ef76420229ff6829f6aa/33e1e887dbbdd1066cfedc7375f5e3b46538529e-859x847.png" alt="" /><p>Améliorons donc cela ! Intégrons le modèle de rerank multilingue de <a href="https://cohere.com/blog/rerank-3pt5">Cohere</a>pour améliorer le raisonnement correspondant à notre question.</p>PUT _inference/rerank/cohere_rerank
{
 "service": "cohere",
 "service_settings": {
   "api_key": "your_api_key",
   "model_id": "rerank-v3.5"
 },
 "task_settings": {
   "top_n": 10,
   "return_documents": true
 }
}


GET coco_multi/_search
{
"size": 10,
"_source": [
  "description",
  "language",
  "en"
],
"retriever": {
  "text_similarity_reranker": {
    "retriever": {
      "rrf": {
        "retrievers": [
          {
            "knn": {
              "field": "vector_description.predicted_value",
              "k": 50,
              "num_candidates": 100,
              "query_vector_builder": {
                "text_embedding": {
                  "model_id": ".multilingual-e5-small_linux-x86_64_search",
                  "model_text": "query: con mèo màu gì?" // English: What color is the cat?
                }
              }
            }
          }
        ],
        "rank_window_size": 100,
        "rank_constant": 0
      }
    },
    "field": "description",
    "inference_id": "cohere_rerank",
    "inference_text": "con mèo màu gì?"
  }
}
} {
       "_index": "coco_multi",
       "_id": "rQiYQJYBgf6odR9bBYyH",
       "_score": 1.5501487,
       "_source": {
         "description": "Hai cái điện thoại được đặt trên một cái chăn cạnh một con mèo con màu đen.",
         "en": "A black kitten lays on her side beside remote controls.",
         "language": "vi"
       }
     },
     {
       "_index": "coco_multi",
       "_id": "swiXQJYBgf6odR9b04uf",
       "_score": 1.5427427,
       "_source": {
         "description": "Một con mèo sọc nâu nhìn vào máy quay.", // Real translation: A brown striped cat looks at the camera 
         "en": "This cat is sitting on a porch near a tire.",
         "language": "vi"
       }
     },<p>Maintenant, avec les premiers résultats, notre application peut répondre en toute confiance que la couleur du chaton est noire ou brune avec des rayures. Ce qui est encore plus intéressant ici, c'est que notre recherche vectorielle a détecté une omission dans la légende anglaise de l'ensemble de données original. Il est capable de trouver le chat à rayures brunes alors que la traduction anglaise de référence a omis ce détail. C'est la force de la recherche vectorielle.</p><h2>Conclusion</h2><p>Dans ce blog, nous avons présenté l'utilité d'un modèle d'intégration multilingue, et comment tirer parti d'Elasticsearch pour intégrer les modèles afin de générer des intégrations, et d'améliorer efficacement la pertinence et la précision avec une recherche hybride et un reranker. Vous pouvez <a href="https://cloud.elastic.co/registration?onboarding_token=vectorsearch&amp;cta=cloud-registration&amp;tech=trial&amp;plcmt=article%20content&amp;pg=search-labs">créer votre propre cluster Cloud</a> pour essayer la recherche <a href="https://www.elastic.co/docs/explore-analyze/machine-learning/nlp/ml-nlp-e5">sémantique multilingue en utilisant notre modèle E5 prêt</a> à l'emploi sur la langue et l'ensemble de données de votre choix.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/multilingual-embedding-model-hybrid-search-reranking</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/multilingual-embedding-model-hybrid-search-reranking</guid>
    <category><![CDATA[Base vectorielle]]></category>
    <category><![CDATA[Opérations]]></category>
    <dc:creator><![CDATA[Quynh Nguyen]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf625e3f63fcd9f54/6a17ef7796142a61f8eb1bcd/d341b04acecc8eeec321f5404e1643447ecc8526-720x420.png" length="0" type="image/png"/>
    <pubDate>Mon, 03 Nov 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Déploiement d'un modèle d'intégration multilingue dans Elasticsearch]]></title>
    <description><![CDATA[Apprenez à déployer un modèle d'intégration multilingue e5 pour la recherche vectorielle et l'extraction multilingue dans Elasticsearch.]]></description>
    <content:encoded><![CDATA[<h2>Introduction</h2><p>Dans un monde d'utilisateurs globaux, la recherche d'informations multilingues (CLIR) est cruciale. Au lieu de limiter les recherches à une seule langue, le CLIR vous permet de trouver des informations dans <em>n'importe quelle</em> langue, ce qui améliore l'expérience de l'utilisateur et rationalise les opérations. Imaginez un marché mondial où les clients du commerce électronique pourraient rechercher des articles dans leur langue et où les bons résultats apparaîtraient, sans qu'il soit nécessaire de localiser les données à l'avance. Ou encore, où les chercheurs universitaires peuvent rechercher des articles dans leur langue maternelle, avec nuance et complexité, même si la source est dans une autre langue.</p><p>Les modèles d'intégration de textes multilingues nous permettent justement de le faire. Les emboîtements sont un moyen de représenter le sens d'un texte sous forme de vecteurs numériques. Ces vecteurs sont conçus de manière à ce que les textes ayant des significations similaires soient situés à proximité les uns des autres dans un espace à haute dimension. Les modèles d'intégration de textes multilingues sont spécifiquement conçus pour représenter dans un espace vectoriel similaire les mots et les phrases ayant la même signification dans différentes langues.</p><p>Les modèles tels que le logiciel libre Multilingual E5 sont formés sur des quantités massives de données textuelles, souvent à l'aide de techniques telles que l'apprentissage contrastif. Dans cette approche, le modèle apprend à distinguer les paires de textes dont le sens est similaire (paires positives) de ceux dont le sens est différent (paires négatives). Le modèle est entraîné à ajuster les vecteurs qu'il produit de manière à maximiser la similarité entre les paires positives et à minimiser la similarité entre les paires négatives. Pour les modèles multilingues, ces données d'entraînement comprennent des paires de textes dans différentes langues qui sont des traductions l'une de l'autre, ce qui permet au modèle d'apprendre un espace de représentation commun pour plusieurs langues. Les enchâssements résultants peuvent ensuite être utilisés pour diverses tâches de NLP, y compris la recherche multilingue, où la similarité entre les enchâssements de texte est utilisée pour trouver des documents pertinents quelle que soit la langue de la requête.</p><h2>Avantages de la recherche vectorielle multilingue</h2><ul><li><p><strong>Nuance</strong>: La recherche vectorielle excelle à capturer le sens sémantique, allant au-delà de la correspondance des mots clés. Ceci est crucial pour les tâches qui nécessitent de comprendre le contexte et les subtilités de la langue.</p></li><li><p><strong>Compréhension multilingue</strong>: Permet de rechercher efficacement des informations dans plusieurs langues, même lorsque la requête et les documents utilisent un vocabulaire différent.</p></li><li><p><strong>Pertinence</strong>: Fournit des résultats plus pertinents en se concentrant sur la similarité conceptuelle entre les requêtes et les documents.</p></li></ul><p>"Prenons l'exemple d'un chercheur universitaire qui étudie l'impact des médias sociaux sur le discours politique" dans différents pays. Grâce à la recherche vectorielle, ils peuvent saisir des requêtes telles que "l'impatto dei social media sul discorso politico" (italien) ou "ảnh hưởng của mạng xã hội đối với diễn ngôn chính trị" (vietnamien) et trouver des articles pertinents en anglais, espagnol ou toute autre langue indexée. En effet, la recherche vectorielle identifie les articles qui traitent du <em>concept</em> de l'influence des médias sociaux sur la politique, et pas seulement ceux qui contiennent les mots clés exacts. Cela améliore considérablement l'étendue et la profondeur de leurs recherches.</p><h2>Se lancer</h2><p>Voici comment configurer CLIR en utilisant Elasticsearch - avec le modèle E5 qui est fourni dans la boîte. Nous utiliserons l'<a href="https://huggingface.co/datasets/romrawinjp/multilingual-coco">ensemble de données multilingues COCO</a>, qui contient des légendes d'images dans plusieurs langues, pour nous aider à visualiser deux types de recherches :</p><ol><li><p>Requêtes et termes de recherche dans d'autres langues sur un ensemble de données en anglais, et</p></li><li><p>Requêtes en plusieurs langues à partir d'un ensemble de données contenant des documents en plusieurs langues.</p></li></ol><p>Ensuite, nous exploiterons la puissance de la recherche hybride et du reranking pour améliorer encore les résultats de la recherche.</p><h2>Produits requis</h2><ul><li><p>Python 3.6+</p></li><li><p>Elasticsearch 8+</p></li><li><p>Client Elasticsearch Python : pip install elasticsearch</p></li></ul><h2>Ensemble de données</h2><p>L'<a href="https://huggingface.co/datasets/romrawinjp/multilingual-coco">ensemble de données COCO</a> est un ensemble de données de sous-titrage à grande échelle. Chaque image de l'ensemble de données est légendée dans plusieurs langues différentes, avec plusieurs traductions disponibles par langue. À des fins de démonstration, nous indexerons chaque traduction comme un document individuel, avec la première traduction anglaise disponible à titre de référence.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfc7e508e9a7dffe8/6a17f3e2b1e113249579f394/d4f0632529c71a22fbdecf21c9f4f0bb64b8e69c-1600x567.png" alt="" /><h3>Étape 1 : télécharger l'ensemble de données multilingues COCO</h3><p>Pour simplifier le blog et faciliter le suivi, nous chargeons ici les 100 premières lignes du restval dans un fichier JSON local à l'aide d'un simple appel à l'API. Vous pouvez également utiliser la bibliothèque de données HuggingFace pour charger le jeu de données complet ou des sous-ensembles du jeu de données.</p>import requests
import json
import os
### Download multilingual coco dataset into a json file (for easy viewing)
### Here we are retrieving first 100 rows for this example
### Alternatively, you can use `datasets` library from Hugging Face
url = "https://datasets-server.huggingface.co/rows?dataset=romrawinjp%2Fmultilingual-coco&amp;config=default&amp;split=restval&amp;offset=0&amp;length=100"
response = requests.get(url)


if response.status_code == 200:
   data = response.json()
   output_file = "multilingual_coco_sample.json" 
   ### Loading the downloaded content into a json file locally
   with open(output_file, "w", encoding="utf-8") as f:
       json.dump(data, f, indent=4, ensure_ascii=False)
   print(f"Data successfully downloaded and saved to {output_file}")
else:
   print(f"Failed to download data: {response.status_code}")
   print(response.text)<p>Si les données sont chargées avec succès dans un fichier JSON, vous devriez voir quelque chose de similaire à ce qui suit :</p><p><code>Data successfully downloaded and saved to multilingual_coco_sample.json</code></p><h3>Étape 2 : (Démarrer Elasticsearch) et indexer les données dans Elasticsearch</h3><p>a) Démarrez votre serveur Elasticsearch local.</p><p>b) Lancer le client Elasticsearch.</p>from elasticsearch import Elasticsearch
from getpass import getpass


# Initialize Elasticsearch client
es = Elasticsearch(getpass("Host: "), api_key=getpass("API Key: "))


index_name = "coco"


# Create the index if it doesn't exist
if not es.indices.exists(index=index_name):
   es.indices.create(index=index_name, body=mapping)<p>c) Données d'index</p># Load the JSON data
with open('./multilingual_coco_sample.json', 'r') as f:
   data = json.load(f)


rows = data["rows"]
# List of languages to process
languages = ["en", "es", "de", "it", "vi", "th"]


# For each image, we will process each individual caption as its own document
bulk_data = []
for data in rows:
   row = data["row"]
   image = row.get("image")
   image_url = image["src"]


   # Process each language
   for lang in languages:
       # Skip if language not present in this row
       if lang not in row:
           continue


       # Get all descriptions for this language
 # along with first available English caption for reference
       descriptions = row[lang]
       first_eng_caption = row["en"][0]


       # Prepare bulk indexing data
       for description in descriptions:
           if description == "":
               continue
           # Add index operation
           bulk_data.append(
               {"index": {"_index": index_name}}
           )
           # Add document
           bulk_data.append({
               "language": lang,
               "description": description,
               "en": first_eng_caption,
               "image_url": image_url,
           })


# Perform bulk indexing
if bulk_data:
   try:
       response = es.bulk(operations=bulk_data)
       if response["errors"]:
           print("Some documents failed to index")
       else:
           print(f"Successfully bulk indexed {len(bulk_data)} documents")
   except Exception as e:
       print(f"Error during bulk indexing: {str(e)}")


print("Indexing complete!")<p>Une fois les données indexées, vous devriez voir quelque chose de similaire à ce qui suit :</p><p><code>Successfully bulk indexed 4840 documents</code></p><p><code>Indexing complete!</code></p><h3>Étape 3 : Déployer le modèle formé E5</h3><p>Dans Kibana, accédez à la page Stack Management &gt; <strong>Trained Models</strong>, et cliquez sur <strong>Deploy</strong> pour le modèle .multilingual-e5-small_linux-x86_64. option. Ce modèle E5 est un petit ordinateur multilingue optimisé pour linux-x86_64, que l'on peut utiliser dès sa sortie de l'emballage. En cliquant sur "Déployer", vous accédez à un écran où vous pouvez ajuster les paramètres de déploiement ou les configurations des vCPUs. Par souci de simplicité, nous utiliserons les options par défaut, en sélectionnant les ressources adaptatives, ce qui permettra de dimensionner automatiquement notre déploiement en fonction de l'utilisation.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfbc09867063a8e6f/6a17f3e3148009a295b4889d/95cd8f352425d1db2d04b00c3c88d1e71d1ef19a-1600x440.png" alt="" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt264a2016341e9b6f/6a17f3f0e8fbce18de3a1aa7/1599d99949dda8267acc58f400a403a3af5373ef-1600x655.png" alt="" /><p>Si vous souhaitez utiliser d'autres modèles d'intégration de texte, vous pouvez le faire en option. Par exemple, pour utiliser le BGE-M3, vous pouvez utiliser <a href="https://www.elastic.co/docs/reference/elasticsearch/clients/eland/machine-learning#ml-nlp-pytorch">le client Python Eland d'Elastic</a> pour importer le modèle de HuggingFace.</p>export MODEL_ID="bge-m3"
export HUB_MODEL_ID="BAAI/bge-m3"
export CLOUD_ID={{CLOUD_ID}}
export ES_API_KEY={{API_KEY}}
docker run -it --rm docker.elastic.co/eland/eland \
eland_import_hub_model --cloud-id $CLOUD_ID --es-api-key $ES_API_KEY --hub-model-id $HUB_MODEL_ID --es-model-id $MODEL_ID --task-type text_embedding --start<p>Accédez ensuite à la page Modèles formés pour déployer le modèle importé avec les configurations souhaitées.</p><h3>Étape 4 : Vectorisation ou création d'enchâssements pour les données d'origine avec le modèle déployé</h3><p>Pour créer les enchâssements, nous devons d'abord créer un pipeline d'ingestion qui nous permettra de prendre le texte et de le faire passer par le modèle d'enchâssement de texte d'inférence. Vous pouvez le faire dans l'interface utilisateur de Kibana ou via l'API d'Elasticsearch.</p><p><strong>Pour ce faire via l'interface Kibana</strong>, après avoir déployé le modèle entraîné, cliquez sur le bouton <strong>Test </strong>. Cela vous permettra de tester et de prévisualiser les éléments intégrés générés. Créez une nouvelle vue de données pour l'index <code>coco</code> , définissez Data view sur la vue de données coco nouvellement créée, et définissez Field sur <code>description</code> car c'est le champ pour lequel nous voulons générer des embeddings.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt24a2b9a9a5111bbc/6a17f3f13e9e452c7fba15d5/cfe189e13dc118d325e7fb90bdace0c912e29f51-1088x1600.png" alt="" /><p>Cela fonctionne très bien ! Nous pouvons maintenant créer le pipeline d'ingestion et réindexer nos documents originaux, les faire passer par le pipeline et créer un nouvel index avec les embeddings. Pour ce faire, cliquez sur <strong>Créer un pipeline</strong>, ce qui vous guidera tout au long du processus de création du pipeline, avec des processeurs auto-remplis nécessaires pour vous aider à créer les embeddings.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte39c5ad52702103d/6a17f3f3e9ea87dd05a9c734/1e043c1c3279b66fbdf19c06b41e76e613043998-1600x1126.png" alt="" /><p>L'assistant peut également remplir automatiquement les processeurs nécessaires pour gérer les défaillances lors de l'ingestion et du traitement des données.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt63e002a79d177cf4/6a17f3f596142a3e91eb1c48/8804d31b4f869078e3b2245040bbb0ab1720a94a-1600x1084.png" alt="" /><p>Créons maintenant le pipeline d'ingestion. Je nomme le pipeline <code>coco_e5</code>. Une fois le pipeline créé avec succès, vous pouvez immédiatement l'utiliser pour générer les embeddings en réindexant les données indexées d'origine vers un nouvel index dans l'assistant. Cliquez sur <strong>Réindexer </strong>pour lancer le processus.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt39243d9ad1779fdf/6a17f3f696142a13eaeb1c4c/e34b1b18f5b24420d4581fe4d657c569926c2023-1600x1126.png" alt="" /><h2>Pour des configurations plus complexes, nous pouvons utiliser l'API Elasticsearch.</h2><p>Pour certains modèles, en raison de la manière dont ils ont été entraînés, il peut être nécessaire d'ajouter certains textes à l'entrée réelle avant de générer les enchâssements, faute de quoi les performances s'en trouveront dégradées.</p><p>Par exemple, avec le e5, le modèle s'attend à ce que le texte d'entrée suive "passage : {content of passage}". Utilisons les pipelines d'ingestion pour y parvenir : Nous allons créer un nouveau pipeline d'ingestion <strong>vectorize_descriptions</strong>. Dans ce pipeline, nous allons créer un nouveau champ temporaire <code>temp_desc</code>, ajouter "passage : " au texte <code>description</code>, faire passer <code>temp_desc</code> par le modèle pour générer des enchâssements de texte, puis supprimer le champ <code>temp_desc</code>.</p>PUT _ingest/pipeline/vectorize_descriptions
{
"description": "Pipeline to run the descriptions text_field through our inference text embedding model",
"processors": [
 {
   "set": {
     "field": "temp_desc",
     "value": "passage: {{description}}"
   }
 },
 {
   "inference": {     
"field_map": {
       "temp_desc": "text_field"
     },
     "model_id": ".multilingual-e5-small_linux-x86_64_search",
     "target_field": "vector_description"
   }
 },
 {
   "remove": {
     "field": "temp_desc"
   }
 }
]
}<p>En outre, nous pourrions vouloir spécifier le <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/dense-vector#dense-vector-quantization">type de quantification</a> que nous voulons utiliser pour le vecteur généré. Par défaut, Elasticsearch utilise <code>int8_hnsw</code>, mais ici je veux <a href="https://www.elastic.co/search-labs/blog/better-binary-quantization-lucene-elasticsearch">Better Binary Quantization</a> (ou <code>bqq_hnsw</code>), qui réduit chaque dimension à une précision d'un seul bit. Cela permet de réduire l'empreinte mémoire de 96% (ou 32x) au prix d'une plus grande précision. J'opte pour ce type de quantification parce que je sais que j'utiliserai plus tard un reranker pour améliorer la perte de précision.</p><p>Pour ce faire, nous allons créer un nouvel index nommé <strong>coco_multi</strong>, et spécifier les mappings. La magie réside ici dans le champ vector_description, où nous spécifions que le type de l'<strong>index_options</strong>est <strong>bbq_hnsw</strong>.</p>PUT coco_multi
{
 "mappings": {
   "properties": {
     "description": {
       "type": "text"
     },
     "en": {
       "type": "text"
     },
     "image_url": {
       "type": "keyword"
     },
     "language": {
       "type": "keyword"
     },
     "vector_description.predicted_value": {
       "type": "dense_vector",
       "dims": 384,
       "index": "true",
       "similarity": "cosine",
       "index_options": {
         "type": "bbq_hnsw" 
       }
     }
   }
 }
}<p>Nous pouvons maintenant réindexer les documents originaux dans un nouvel index, avec notre pipeline d'ingestion qui va "vectoriser" ou créer des embeddings pour le champ des descriptions.</p>POST _reindex?wait_for_completion=false
{
 "source": {
   "index": "coco"
 },
 "dest": {
   "index": "coco_multilingual",
   "pipeline": "vectorize_descriptions"
 }
}<p>Et c'est tout ! Nous avons déployé avec succès un modèle multilingue avec Elasticsearch et Kibana et appris étape par étape comment créer les vector embeddings avec vos données avec Elastic, soit via l'interface utilisateur Kibana, soit avec l'API Elasticsearch. Dans la deuxième partie de cette série, nous explorerons les résultats et les nuances de l'utilisation d'un modèle multilingue. En attendant, vous pouvez <a href="https://cloud.elastic.co/registration?onboarding_token=vectorsearch&amp;cta=cloud-registration&amp;tech=trial&amp;plcmt=article%20content&amp;pg=search-labs">créer votre propre cluster Cloud</a> pour essayer <a href="https://www.elastic.co/docs/explore-analyze/machine-learning/nlp/ml-nlp-e5">la recherche sémantique multilingue en utilisant notre modèle E5 prêt à</a> l'emploi sur la langue et l'ensemble de données de votre choix.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/multilingual-embedding-model-deployment-elasticsearch</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/multilingual-embedding-model-deployment-elasticsearch</guid>
    <category><![CDATA[Base vectorielle]]></category>
    <category><![CDATA[Opérations]]></category>
    <dc:creator><![CDATA[Quynh Nguyen]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt59254226694f93a6/6a17f3f81480098988b488a1/8f2aa7bebb6b2f701e274ba7282273f9ab4abed6-720x432.png" length="0" type="image/png"/>
    <pubDate>Wed, 22 Oct 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elastic Open Web Crawler en tant que code]]></title>
    <description><![CDATA[Apprenez à utiliser les actions GitHub pour gérer les configurations d'Elastic Open Crawler, de sorte que chaque fois que nous apportons des modifications au référentiel, celles-ci sont automatiquement appliquées à l'instance déployée du crawler.]]></description>
    <content:encoded><![CDATA[<p>Avec <a href="https://github.com/elastic/crawler">Elastic Open Web Crawler</a> et son architecture pilotée par CLI, il est désormais assez simple d'avoir des configurations de crawler versionnées et un pipeline CI/CD avec des tests locaux.</p><p>Traditionnellement, la gestion des robots d'indexation était un processus manuel et sujet aux erreurs. Il s'agissait de modifier les configurations directement dans l'interface utilisateur et de se débattre avec le clonage des configurations de crawl, le retour en arrière, la gestion des versions, etc. Traiter les configurations des robots comme du code résout ce problème en offrant les mêmes avantages que ceux que nous attendons du développement de logiciels : répétabilité, traçabilité et automatisation.</p><p>Ce flux de travail facilite l'intégration de l'Open Web Crawler dans votre pipeline CI/CD pour les retours en arrière, les sauvegardes et les migrations, tâches qui étaient beaucoup plus délicates avec les Elastic Crawlers précédents, tels que l'Elastic Web Crawler ou l'App Search Crawler.</p><p>Dans cet article, nous allons apprendre à.. :</p><ul><li><p>Gérer nos configurations de crawl en utilisant GitHub</p></li><li><p>Disposer d'une installation locale pour tester les pipelines avant de les déployer</p></li><li><p>Créer une configuration de production pour exécuter le robot d'exploration avec de nouveaux paramètres à chaque fois que nous apportons des modifications à notre branche principale.</p></li></ul><p>Vous pouvez trouver le dépôt du projet <a href="https://github.com/llermaly/elastic-open-crawler-as-code"><em><strong>ici</strong></em></a><em><strong>. </strong></em><em>Pour l'instant, j'utilise Elasticsearch 9.1.3 et Open Web Crawler 0.4.2.</em></p><h2>Produits requis</h2><ul><li><p>Bureau Docker</p></li><li><p>Instance Elasticsearch</p></li><li><p>Machine virtuelle avec accès SSH (par exemple, AWS EC2) et Docker installé.</p></li></ul><h2>Étapes</h2><ol><li><p>Structure des dossiers</p></li><li><p>Configuration du robot</p></li><li><p>Fichier Docker-compose (environnement local)</p></li><li><p>Actions Github</p></li><li><p>Tests au niveau local</p></li><li><p>Déploiement vers prod</p></li><li><p>Modifications et redéploiement</p></li></ol><h2>Structure des dossiers</h2><p>Pour ce projet, nous aurons la structure de fichier suivante :</p>├── docker-compose.yml # Local elasticsearch + crawler
├── config/crawler-config.yml # Crawler config
├── .github/workflows/deploy.yml # GH Action to deploy changes
├── local.sh # Script to run our local crawler<h2>Configuration du robot</h2><p>Sous <code>crawler-config.yml,</code>, nous mettrons les éléments suivants :</p>output_sink: elasticsearch
output_index: web-crawl-index
max_crawl_depth: 1

elasticsearch:
  host: ${ES_HOST}
  api_key: ${ES_API_KEY}
     
domains:
  - url: https://web-scraping.dev
    seed_urls:
      - https://web-scraping.dev/product/1
      - https://web-scraping.dev/product/2
      - https://web-scraping.dev/product/3<p>Il s'agit d'une recherche à partir de <a href="https://web-scraping.dev/products">https://web-scraping.dev/products,</a> un site fictif pour les produits. Nous ne parcourrons que les trois premières pages du produit. Le paramètre <code>max_crawl_depth</code> empêchera le robot d'exploration de découvrir d'autres pages que celles définies comme <code>seed_urls</code> en n'ouvrant pas les liens qu'elles contiennent.</p><p>Elasticsearch <code>host</code> et <code>api_key</code> seront alimentés dynamiquement en fonction de l'environnement dans lequel nous exécutons le script.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7d37b966aafbd3c1/6a17ef9842022946e929f6b9/f9831034e1c4ccb554d37bdd188f2824338355a0-890x624.png" alt="La page produit pour &quot;Boîte de bonbons au chocolat&quot; provient du domaine web-scraping.dev, un site fictif pour tester le web scraping. La page affiche le titre du produit, l'image, la description et les éléments HTML pour les boutons de prix et d'achat." /><h2>Fichier Docker-compose (environnement local)</h2><p>Pour le site local <code>docker-compose.yml,</code>, nous allons déployer le crawler et un seul cluster Elasticsearch + Kibana, de sorte que nous puissions facilement visualiser nos résultats de crawling <em><strong>avant de</strong></em> les déployer en production.</p>services:
  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:9.1.3
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - ES_JAVA_OPTS=-Xms1g -Xmx1g
    ports:
      - "9200:9200"
    networks: [esnet]
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9200"]
      interval: 5s
      timeout: 5s
      retries: 10

  kibana:
    image: docker.elastic.co/kibana/kibana:9.1.3
    environment:
      - ELASTICSEARCH_HOSTS=http://es01:9200
    ports:
      - "5601:5601"
    networks: [esnet]
    depends_on: [es01]

  crawler:
    image: docker.elastic.co/integrations/crawler:0.4.2
    environment:
      - ES_HOST=http://es01:9200
      - CRAWLER_JRUBY_OPTS=--server
    container_name: crawler
    volumes:
      - ./config:/home/app/config
    networks: [esnet]
    entrypoint: ["/home/app/bin/crawler", "crawl", "/home/app/config/crawl-config-final.yml"]
    stdin_open: true
    tty: true

networks:
  esnet:
    driver: bridge<p>Notez que le crawler attend qu'Elasticsearch soit prêt à fonctionner.</p><h2>Actions Github</h2><p>Nous devons maintenant créer une action GitHub qui copiera les nouveaux paramètres et exécutera le crawler dans notre machine virtuelle à chaque poussée vers main. Ainsi, nous disposons toujours de la dernière configuration déployée, sans avoir à entrer manuellement dans la machine virtuelle pour mettre à jour les fichiers et exécuter le crawler. Nous allons utiliser AWS EC2 comme fournisseur de machines virtuelles.</p><p>La première étape consiste à ajouter l'hôte (<code>VM_HOST</code>), l'utilisateur de la machine (<code>VM_USER</code>), la clé RSA SSH (<code>VM_KEY</code>), l'hôte Elasticsearch (<code>ES_HOST</code>) et la clé API Elasticsearch (<code>ES_API_KEY</code>) aux secrets d'action GitHub :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb5a0fcfff9b7f997/6a17ef9a6df731d7d40a0fdf/e1075bc54151b4b94eac2a6bd2682e9997e6c709-1106x707.png" alt="Une page de configuration &quot;actions, secrets et variables&quot;, affichant les secrets du référentiel tels que VM_HOST, VM_KEY et VM_USER dans une interface web." /><p>De cette manière, l'action pourra accéder à notre serveur pour copier les nouveaux fichiers et exécuter le crawl.</p><p>Maintenant, créons notre fichier <code>.github/workflows/deploy.yml</code>:</p>name: Deploy

on:
  push:
    branches: [main]

jobs:
  Deploy:
    name: Deploy to EC2
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v5

      - name: Deploy crawler
        env:
          HOSTNAME: ${{ secrets.VM_HOST }}
          USER_NAME: ${{ secrets.VM_USER }}
          PRIVATE_KEY: ${{ secrets.VM_KEY }}
          ES_HOST: ${{ secrets.ES_HOST }}
          ES_API_KEY: ${{ secrets.ES_API_KEY }}
        run: |
          # Save private key
          echo "$PRIVATE_KEY" &gt; private_key
          chmod 600 private_key

          # Generate final config locally
          envsubst &lt; config/crawler-config.yml &gt; config/crawl-config-final.yml

          # Copy the config folder to VM
          scp -o StrictHostKeyChecking=no -i private_key -r config ${USER_NAME}@${HOSTNAME}:~/config

          # SSH into VM and run crawler
          ssh -o StrictHostKeyChecking=no -i private_key ${USER_NAME}@${HOSTNAME} &lt;&lt; EOF
            docker run --rm \
              -v ~/config:/config \
              docker.elastic.co/integrations/crawler:latest jruby \
              bin/crawler crawl /config/crawl-config-final.yml
          EOF<p>Cette action exécutera les étapes suivantes à chaque fois que des modifications seront apportées au fichier de configuration du crawler :</p><ol><li><p>Renseigner l'hôte Elasticsearch et la clé API dans la configuration yml</p></li><li><p>Copier le dossier config sur notre VM</p></li><li><p>Se connecter via SSH à notre VM</p></li><li><p>Exécuter le crawl avec la configuration que nous venons de copier depuis le repo</p></li></ol><h2>Tests au niveau local</h2><p>Pour tester notre crawler localement, nous avons créé un script bash qui remplit l'hôte Elasticsearch avec l'hôte local de Docker et démarre un crawl. Vous pouvez lancer <code>./local.sh</code> pour l'exécuter.</p>#!/bin/bash

# Exit on any error
set -e

# Load environment variables
export ES_HOST="http://es01:9200"

# Generate final crawler config
envsubst &lt; ./config/crawler-config.yml &gt; ./config/crawl-config-final.yml

# Bring everything up
docker compose up --build<p>Regardons Kibana DevTools pour confirmer que le site<code> web-crawler-index</code> a été correctement renseigné :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt989660368fe14db8/6a17ef9b9da390c79ce46562/18551635e8265866e389a9632c4e4540958e4468-990x723.png" alt="Code Kibana DevTools pour confirmer que le web-crawler-index est correctement configuré." /><h2>Déploiement vers prod</h2><p>Nous sommes maintenant prêts à pousser vers la branche principale, ce qui déploiera le crawler dans votre machine virtuelle et commencera à envoyer des logs à votre instance Serverless Elasticsearch.</p>git add .
git commit -m "First commit"
git push<p>Cela déclenchera l'action GitHub, qui exécutera le script de déploiement dans la machine virtuelle et commencera l'exploration.</p><p>Vous pouvez confirmer que l'action a été exécutée en allant sur le dépôt GitHub et en visitant l'onglet "Actions" :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt986f1a4e4f3288d2/6a17ef9c7f6f1584fdc09c10/67ba3a7164d7a8049fe5661264820826cb18ed64-667x325.png" alt="Les actions se déploient sur l'onglet EC2 dans un dépôt GitHub." /><h2>Modifications et redéploiement</h2><p>Vous avez peut-être remarqué que le site <code>price</code> de chaque produit fait partie du champ "body" du document. L'idéal serait de stocker le prix dans un champ distinct afin de pouvoir utiliser des filtres.</p><p>Ajoutons cette modification au fichier <code>crawler.yml</code> afin d'utiliser des <a href="https://github.com/elastic/crawler/blob/main/docs/features/EXTRACTION_RULES.md">règles d'extraction</a> pour extraire le prix de la classe CSS <code>product-price</code>:</p>output_sink: elasticsearch
output_index: web-crawl-index
max_crawl_depth: 1

elasticsearch:
  host: ${ES_HOST}
  api_key: ${ES_API_KEY}
     
  # Index ingest pipeline to process documents before indexing          
  pipeline_enabled: true
  pipeline: pricing-pipeline

domains:
  - url: https://web-scraping.dev
    seed_urls:
      - https://web-scraping.dev/product/1
      - https://web-scraping.dev/product/2
      - https://web-scraping.dev/product/3
    extraction_rulesets:
      - url_filters:
          - type: ends
            pattern: /product/*
        rules:
          - action: extract
            field_name: price
            selector: .product-price
            join_as: string
            source: html<p>Nous constatons également que le prix comprend un signe de dollar (<code>$</code>), que nous devons supprimer si nous voulons exécuter des requêtes de plage. Nous pouvons utiliser un pipeline d'acquisition pour cela. Notez que nous y faisons référence dans notre nouveau fichier de configuration du crawler ci-dessus :</p>PUT _ingest/pipeline/pricing-pipeline
{
  "processors": [
    {
      "script": {
        "source": """
                ctx['price'] = ctx['price'].replace("$","")
            """
      }
    }
  ]
}<p>Nous pouvons exécuter cette commande dans notre cluster Elasticsearch de production. Pour celui de développement, comme il est éphémère, nous pouvons intégrer la création du pipeline dans le fichier <code>docker-compose.yml</code> en ajoutant le service suivant. Notez que nous avons également ajouté un <code>depends_on</code> au service crawler afin qu'il démarre après la création réussie du pipeline.</p> crawler:
    image: docker.elastic.co/integrations/crawler:0.4.2
    environment:
      - ES_HOST=http://es01:9200
      - CRAWLER_JRUBY_OPTS=--server
    container_name: crawler
    volumes:
      - ./config:/home/app/config
    networks: [esnet]
    entrypoint: ["/home/app/bin/crawler", "crawl", "/home/app/config/crawl-config-final.yml"]
    depends_on:
      pipeline-init:
        condition: service_completed_successfully
    stdin_open: true
    tty: true  


  pipeline-init:
    image: curlimages/curl:latest
    depends_on:
      es01:
        condition: service_healthy
    networks: [esnet]
    entrypoint: &gt;
        sh -c "
        echo 'Creating ingest pipeline...';
        curl -s -X PUT http://es01:9200/_ingest/pipeline/pricing-pipeline \\
          -H 'Content-Type: application/json' \\
          -d '{\"processors\":[{\"script\":{\"source\":\"ctx.price = ctx.price.replace(\\\"$\\\", \\\"\\\")\"}}]}';
        echo 'Pipeline created!';
        "<p>Exécutons maintenant <code>`./local.sh`</code> pour voir les changements localement :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0f390aedf67cb4fe/6a17ef9eaf47b62bd2cde05b/dc1801599344a9f69f072b07ff828c4ba3815d7b-738x473.png" alt="Exécution de `./local.sh` pour voir le prix changer localement." /><p>C'est très bien ! Poussons maintenant la modification :</p>git add crawler-config.yml
git commit -m "added price CSS selector"
git push<p>Pour confirmer que tout fonctionne, vous pouvez vérifier votre Kibana de production, qui devrait refléter les changements et afficher le prix comme un nouveau champ sans le signe du dollar.</p><h2>Conclusion</h2><p>Elastic Open Web Crawler vous permet de gérer votre crawler en tant que code, ce qui signifie que vous pouvez automatiser l'ensemble du pipeline - du développement au déploiement - et ajouter des environnements locaux éphémères et des tests sur les données explorées de manière programmatique, pour ne citer que quelques exemples.</p><p>Vous êtes invités à cloner le dépôt officiel et à commencer à indexer vos propres données à l'aide de ce flux de travail. Vous pouvez également lire <a href="https://www.elastic.co/search-labs/blog/semantic-search-open-crawler">cet article</a> pour apprendre comment effectuer une recherche sémantique sur les index produits par le crawler.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elastic-open-crawler-config-as-code</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elastic-open-crawler-config-as-code</guid>
    <category><![CDATA[Indexer des données]]></category>
    <category><![CDATA[Opérations]]></category>
    <dc:creator><![CDATA[Gustavo Llermaly]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt00e7c95012dc38cc/6a17efa0fbc5f80dad491b93/0ac41f55c85ad3f647cb0e0d750ed80bacd397f3-1036x581.png" length="0" type="image/png"/>
    <pubDate>Mon, 22 Sep 2025 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>