{"title":"Recherche","version":"5.2","locale":"fr","docname":"topics/db/search","url":"/fr/5.2/topics/db/search/","canonical":"https://djangodocs.dev/fr/5.2/topics/db/search/","summary":"Un tâche courante des applications Web est de rechercher des données dans la base de données en fonction de la saisie d’utilisateurs. Dans un cas simple, cela peut…","html":"<h1>Recherche<a class=\"heading-anchor\" href=\"#search\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Un tâche courante des applications Web est de rechercher des données dans la base de données en fonction de la saisie d’utilisateurs. Dans un cas simple, cela peut se limiter à filtrer une liste d’objets par catégorie. Un cas d’utilisation plus complexe pourrait impliquer une recherche avec pondération, catégorisation, mise en évidence, multilingue, etc. Ce document présente certains cas d’utilisation possibles et les outils pouvant être utilisés.</p>\n<p>Nous ferons référence aux mêmes modèles que dans <a class=\"reference internal\" href=\"/fr/5.2/topics/db/queries/\"><span class=\"doc\">Création de requêtes</span></a>.</p>\n<section id=\"use-cases\">\n<h2>Cas d’utilisation<a class=\"heading-anchor\" href=\"#use-cases\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"standard-textual-queries\">\n<h3>Requêtes textuelles standard<a class=\"heading-anchor\" href=\"#standard-textual-queries\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Les champs basés sur du texte offrent quelques opérations de correspondance. Par exemple, vous pourriez vouloir permettre de rechercher un auteur comme ceci :</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Author</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">name__contains</span><span class=\"o\">=</span><span class=\"s2\">&quot;Terry&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">[&lt;Author: Terry Gilliam&gt;, &lt;Author: Terry Jones&gt;]</span>\n</code></pre></div>\n<p>Il s’agit d’une solution très fragile car elle exige que l’utilisateur connaisse une sous-chaîne exacte du nom de l’auteur. Une meilleure approche pourrait faire appel à une recherche indépendante de la casse (<a class=\"reference internal\" href=\"/fr/5.2/ref/models/querysets/#std-fieldlookup-icontains\"><code class=\"xref std std-lookup docutils literal notranslate\"><span class=\"pre\">icontains</span></code></a>), mais ce n’est qu’une petite amélioration.</p>\n</section>\n<section id=\"a-database-s-more-advanced-comparison-functions\">\n<h3>Des fonctions comparatives de base de données plus avancées<a class=\"heading-anchor\" href=\"#a-database-s-more-advanced-comparison-functions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si vous utilisez PostgreSQL, Django fournit <a class=\"reference internal\" href=\"/fr/5.2/ref/contrib/postgres/search/\"><span class=\"doc\">une sélection d’outils spécifiques à cette base de données</span></a> pour permettre d’exploiter des options de requête plus complexes. D’autres bases de données ont des outils différents, parfois via des greffons ou des fonctions définies par les utilisateurs. Django ne les prend pas en charge pour le moment. Nous utiliserons quelques exemples tirés de PostgreSQL pour démontrer le genre de fonctionnalités que les bases de données peuvent offrir.</p>\n<aside class=\"admonition-searching-in-other-databases admonition\">\n<p class=\"admonition-title\">Recherche avec d’autres bases de données</p>\n<p>Tous les outils de recherche proposés par <a class=\"reference internal\" href=\"/fr/5.2/ref/contrib/postgres/#module-django.contrib.postgres\" title=\"django.contrib.postgres: PostgreSQL-specific fields and features\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">django.contrib.postgres</span></code></a> sont construits entièrement sur des API publiques telles que les <a class=\"reference internal\" href=\"/fr/5.2/ref/models/lookups/\"><span class=\"doc\">expressions de recherche personnalisées</span></a> et les <a class=\"reference internal\" href=\"/fr/5.2/ref/models/database-functions/\"><span class=\"doc\">fonctions de base de données</span></a>. En fonction de la base de données, vous devriez pouvoir construire des requêtes en approchant des API similaires. Si des aspects spécifiques ne peuvent pas être résolus de cette façon, merci de bien vouloir ouvrir un ticket.</p>\n</aside>\n<p>Dans l’exemple ci-dessus, nous avons déterminé qu’une recherche non sensible à la casse serait plus utile. Quand on est confronté à des noms sortant de l’alphabet anglais, une autre amélioration possible est d’utiliser les <a class=\"reference internal\" href=\"/fr/5.2/ref/contrib/postgres/lookups/#std-fieldlookup-unaccent\"><code class=\"xref std std-lookup docutils literal notranslate\"><span class=\"pre\">comparaisons</span> <span class=\"pre\">sans</span> <span class=\"pre\">accents</span></code></a>:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Author</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">name__unaccent__icontains</span><span class=\"o\">=</span><span class=\"s2\">&quot;Helen&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">[&lt;Author: Helen Mirren&gt;, &lt;Author: Helena Bonham Carter&gt;, &lt;Author: Hélène Joy&gt;]</span>\n</code></pre></div>\n<p>Cela fait apparaître un autre problème, où nous cherchons des correspondances avec une autre orthographe du nom. Dans ce cas, nous obtenons toutefois une asymétrie, une recherche pour  <code class=\"docutils literal notranslate\"><span class=\"pre\">Helen</span></code> trouvera <code class=\"docutils literal notranslate\"><span class=\"pre\">Helena</span></code> ou <code class=\"docutils literal notranslate\"><span class=\"pre\">Hélène</span></code>, mais pas l’inverse. Une autre option serait d’utiliser une comparaison par <a class=\"reference internal\" href=\"/fr/5.2/ref/contrib/postgres/lookups/#std-fieldlookup-trigram_similar\"><code class=\"xref std std-lookup docutils literal notranslate\"><span class=\"pre\">trigram_similar</span></code></a> qui compare des suites de lettres.</p>\n<p>Par exemple :</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Author</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">name__unaccent__lower__trigram_similar</span><span class=\"o\">=</span><span class=\"s2\">&quot;Hélène&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">[&lt;Author: Helen Mirren&gt;, &lt;Author: Hélène Joy&gt;]</span>\n</code></pre></div>\n<p>Nous rencontrons maintenant un problème différent : le nom plus long « Helena Bonham Carter » n’apparaît pas car il est bien plus long. Les recherches par trigramme envisagent toutes les combinaisons de trois lettres et comparent combien apparaissent à la fois dans les chaînes source et de recherche. En ce qui concerne le nom plus long, il y a plus de combinaisons qui n’apparaissent pas dans la chaîne source, ce qui explique qu’il n’est plus considéré comme une correspondance proche.</p>\n<p>Le choix correct de fonctions de comparaison dépend ici du jeu de données particulier, par exemple en fonction des langues utilisées et du type de texte à rechercher. Tous les exemples que nous avons examinés portent sur des chaînes courtes et où l’utilisateur va probablement saisir un terme proche (selon plusieurs définitions) des données sources.</p>\n</section>\n<section id=\"document-based-search\">\n<h3>Recherche basée sur des documents<a class=\"heading-anchor\" href=\"#document-based-search\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Les opérations de base de données standard atteignent leurs limites lorsqu’on est confronté à de gros blocs de texte. Alors que les exemples précédents peuvent être considérés comme des opérations sur une chaîne de caractères, la recherche plein texte examine les mots réels. En fonction du système utilisé, il est probable que certains des concepts suivants seront utilisés :</p>\n<ul class=\"simple\">\n<li><p>Ignorance des « mots vides » tels que « a », « le », « et ».</p></li>\n<li><p>Racines de mots, afin que « cheval » et « chevaux » soient considérés identiques.</p></li>\n<li><p>Pondération des mots basée sur différents critères tels que la fréquence d’apparition dans le texte ou l’importance des champs (titre, mots-clés, etc.) dans lesquels ils apparaissent.</p></li>\n</ul>\n<p>Il existe de nombreuses alternatives de logiciels spécialisés pour la recherche, dont <a class=\"reference external\" href=\"https://www.elastic.co/\">Elastic</a> et <a class=\"reference external\" href=\"https://solr.apache.org/\">Solr</a> sont parmi les plus célèbres. Ce sont des solutions de recherche basées sur des documents complets. Pour les utiliser avec des modèles Django, il sera nécessaire d’ajouter une couche de traduction des données en documents textuels, y compris des références inverses contenant les identifiants de base de données. Lorsqu’une recherche utilisant ces moteurs renvoie un certain document, il est alors possible de l’extraire de la base de données. Plusieurs bibliothèques tierces sont conçues pour vous assister dans cette tâche.</p>\n<section id=\"postgresql-support\">\n<h4>Prise en charge des outils PostgreSQL<a class=\"heading-anchor\" href=\"#postgresql-support\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>PostgreSQL possède sa propre implémentation de recherche plein texte. Même si elle n’est pas autant performante que certains autres moteurs de recherche, elle a l’avantage de se trouver dans la base de données elle-même et peut donc être facilement combinée à d’autres requêtes relationnelles telles que la catégorisation.</p>\n<p>Le module <a class=\"reference internal\" href=\"/fr/5.2/ref/contrib/postgres/#module-django.contrib.postgres\" title=\"django.contrib.postgres: PostgreSQL-specific fields and features\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">django.contrib.postgres</span></code></a> fournit certains utilitaires pour préparer ces requêtes. Par exemple, une requête pourrait sélectionner tous les articles de blog qui mentionnent « cheese »:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Entry</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">body_text__search</span><span class=\"o\">=</span><span class=\"s2\">&quot;cheese&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">[&lt;Entry: Cheese on Toast recipes&gt;, &lt;Entry: Pizza recipes&gt;]</span>\n</code></pre></div>\n<p>Il est aussi possible de filtrer sur une combinaison de champs et de modèles liés :</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Entry</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">search</span><span class=\"o\">=</span><span class=\"n\">SearchVector</span><span class=\"p\">(</span><span class=\"s2\">&quot;blog__tagline&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;body_text&quot;</span><span class=\"p\">),</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">search</span><span class=\"o\">=</span><span class=\"s2\">&quot;cheese&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">[</span>\n<span class=\"go\">    &lt;Entry: Cheese on Toast recipes&gt;,</span>\n<span class=\"go\">    &lt;Entry: Pizza Recipes&gt;,</span>\n<span class=\"go\">    &lt;Entry: Dairy farming in Argentina&gt;,</span>\n<span class=\"go\">]</span>\n</code></pre></div>\n<p>Voir le document <a class=\"reference internal\" href=\"/fr/5.2/ref/contrib/postgres/search/\"><span class=\"doc\">Recherche plein texte</span></a> de <code class=\"docutils literal notranslate\"><span class=\"pre\">contrib.postgres</span></code> pour de plus amples détails.</p>\n</section>\n</section>\n</section>","rootId":"search","toc":[{"title":"Cas d’utilisation","anchor":"use-cases","children":[{"title":"Requêtes textuelles standard","anchor":"standard-textual-queries","children":[]},{"title":"Des fonctions comparatives de base de données plus avancées","anchor":"a-database-s-more-advanced-comparison-functions","children":[]},{"title":"Recherche basée sur des documents","anchor":"document-based-search","children":[{"title":"Prise en charge des outils PostgreSQL","anchor":"postgresql-support","children":[]}]}]}],"breadcrumbs":[{"docname":"topics/index","title":"Utilisation de Django","url":"/fr/5.2/topics/"},{"docname":"topics/db/index","title":"Modèles et bases de données","url":"/fr/5.2/topics/db/"}],"prev":{"docname":"topics/db/aggregation","title":"Agrégation","url":"/fr/5.2/topics/db/aggregation/"},"next":{"docname":"topics/db/managers","title":"Gestionnaires","url":"/fr/5.2/topics/db/managers/"},"formats":{"html":"/fr/5.2/topics/db/search/","markdown":"/fr/5.2/topics/db/search.md","json":"/fr/5.2/topics/db/search.json"},"source":"https://github.com/django/django/blob/stable/5.2.x/docs/topics/db/search.txt","official":"https://docs.djangoproject.com/fr/5.2/topics/db/search/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10"],"inLocales":["en","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}