{"title":"全文搜索","version":"3.1","locale":"zh-hans","docname":"ref/contrib/postgres/search","url":"/zh-hans/3.1/ref/contrib/postgres/search/","canonical":"https://djangodocs.dev/zh-hans/3.1/ref/contrib/postgres/search/","summary":"django.contrib.postgres.search 模块中的数据库函数方便了 PostgreSQL 的 全文搜索引擎 的使用。 在本文档的例子中，我们将使用 执行查询 中定义的模型。 See also 有关搜索的高级概述，请参见 主题文档 。 search 查找 Link to this heading #…","html":"<h1>全文搜索<a class=\"heading-anchor\" href=\"#full-text-search\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">django.contrib.postgres.search</span></code> 模块中的数据库函数方便了 PostgreSQL 的 <a class=\"reference external\" href=\"https://www.postgresql.org/docs/current/textsearch.html\">全文搜索引擎</a> 的使用。</p>\n<p>在本文档的例子中，我们将使用 <a class=\"reference internal\" href=\"/zh-hans/3.1/topics/db/queries/\"><span class=\"doc\">执行查询</span></a> 中定义的模型。</p>\n<aside class=\"admonition admonition-seealso\">\n<p class=\"admonition-title\">See also</p>\n<p>有关搜索的高级概述，请参见 <a class=\"reference internal\" href=\"/zh-hans/3.1/topics/db/search/\"><span class=\"doc\">主题文档</span></a>。</p>\n</aside>\n<section id=\"the-search-lookup\">\n<h2><code class=\"docutils literal notranslate\"><span class=\"pre\">search</span></code> 查找<a class=\"heading-anchor\" href=\"#the-search-lookup\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p id=\"std-fieldlookup-search\">使用全文检索的常见方法是针对数据库中的单一列进行单项检索。例如：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code 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=\"s1\">&#39;Cheese&#39;</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>这将使用默认的数据库搜索配置，从 <code class=\"docutils literal notranslate\"><span class=\"pre\">body_text</span></code> 字段在数据库中创建一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">to_tsvector</span></code>，从搜索词 <code class=\"docutils literal notranslate\"><span class=\"pre\">'Cheese'</span></code> 中创建一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">plainto_tsquery</span></code>。通过匹配查询和向量得到结果。</p>\n<p>要使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">search</span></code> 查找，<code class=\"docutils literal notranslate\"><span class=\"pre\">'django.contrib.postgres'</span></code> 必须在你的 <a class=\"reference internal\" href=\"/zh-hans/3.1/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">INSTALLED_APPS</span></code></a>。</p>\n<aside class=\"version-note version-changed\" data-version=\"3.1\">\n<p class=\"version-note-title\">Changed in Django 3.1</p><p>增加了对查询表达式的支持。</p>\n</aside>\n</section>\n<section id=\"searchvector\">\n<h2><code class=\"docutils literal notranslate\"><span class=\"pre\">SearchVector</span></code><a class=\"heading-anchor\" href=\"#searchvector\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.postgres.search.SearchVector\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">SearchVector</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">*</span></span><span class=\"n\"><span class=\"pre\">expressions</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">config</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">weight</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.postgres.search.SearchVector\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>对单个字段进行搜索是很好的，但有很大的局限性。我们要搜索的 <code class=\"docutils literal notranslate\"><span class=\"pre\">Entry</span></code> 实例属于 <code class=\"docutils literal notranslate\"><span class=\"pre\">Blog</span></code>，它有一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">tagline</span></code> 字段。要对这两个字段进行查询，使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">SearchVector</span></code>：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.postgres.search</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">SearchVector</span>\n<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=\"s1\">&#39;body_text&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;blog__tagline&#39;</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=\"s1\">&#39;Cheese&#39;</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><code class=\"docutils literal notranslate\"><span class=\"pre\">SearchVector</span></code> 的参数可以是任何 <a class=\"reference internal\" href=\"/zh-hans/3.1/ref/models/expressions/#django.db.models.Expression\" title=\"django.db.models.Expression\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Expression</span></code></a> 或字段名。多个参数将使用空格连接在一起，这样搜索文档就会包含所有参数。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">SearchVector</span></code> 对象可以组合在一起，允许你重复使用它们。例如：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code 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=\"s1\">&#39;body_text&#39;</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"n\">SearchVector</span><span class=\"p\">(</span><span class=\"s1\">&#39;blog__tagline&#39;</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=\"s1\">&#39;Cheese&#39;</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>关于 <code class=\"docutils literal notranslate\"><span class=\"pre\">config</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">weight</span></code> 参数的解释，请参见 <a class=\"reference internal\" href=\"#postgresql-fts-search-configuration\"><span class=\"std std-ref\">更改搜索配置</span></a> 和 <a class=\"reference internal\" href=\"#postgresql-fts-weighting-queries\"><span class=\"std std-ref\">加权查询</span></a>。</p>\n</section>\n<section id=\"searchquery\">\n<h2><code class=\"docutils literal notranslate\"><span class=\"pre\">SearchQuery</span></code><a class=\"heading-anchor\" href=\"#searchquery\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.postgres.search.SearchQuery\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">SearchQuery</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">value</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">config</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">search_type</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">'plain'</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.postgres.search.SearchQuery\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">SearchQuery</span></code> 将用户提供的术语转化为搜索查询对象，数据库将其与搜索向量进行比较。默认情况下，用户提供的所有词语都会通过词干算法，然后寻找所有结果词语的匹配。</p>\n<p>如果 <code class=\"docutils literal notranslate\"><span class=\"pre\">search_type</span></code> 是 <code class=\"docutils literal notranslate\"><span class=\"pre\">'plain'</span></code>，即默认值，则将术语作为单独的关键字处理；如果 <code class=\"docutils literal notranslate\"><span class=\"pre\">search_type</span></code> 是 <code class=\"docutils literal notranslate\"><span class=\"pre\">'phrase'</span></code>，则将术语作为单一的短语处理。如果 <code class=\"docutils literal notranslate\"><span class=\"pre\">search_type</span></code> 是 <code class=\"docutils literal notranslate\"><span class=\"pre\">'phrase'</span></code>，则将术语作为一个单一的短语处理。如果 <code class=\"docutils literal notranslate\"><span class=\"pre\">search_type</span></code> 是 <code class=\"docutils literal notranslate\"><span class=\"pre\">'raw'</span></code>，那么你可以提供一个带有术语和运算符的格式化搜索查询。如果 <code class=\"docutils literal notranslate\"><span class=\"pre\">search_type</span></code> 是 <code class=\"docutils literal notranslate\"><span class=\"pre\">'websearch'</span></code>，那么你可以提供一个格式化的搜索查询，类似于网络搜索引擎使用的格式。<code class=\"docutils literal notranslate\"><span class=\"pre\">'websearch'</span></code> 需要 PostgreSQL ≥ 11。请阅读 PostgreSQL 的 <a class=\"reference external\" href=\"https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES\">全文搜索文档</a> 来了解两者的区别和语法。举例说明。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.postgres.search</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">SearchQuery</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">SearchQuery</span><span class=\"p\">(</span><span class=\"s1\">&#39;red tomato&#39;</span><span class=\"p\">)</span>  <span class=\"c1\"># two keywords</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">SearchQuery</span><span class=\"p\">(</span><span class=\"s1\">&#39;tomato red&#39;</span><span class=\"p\">)</span>  <span class=\"c1\"># same results as above</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">SearchQuery</span><span class=\"p\">(</span><span class=\"s1\">&#39;red tomato&#39;</span><span class=\"p\">,</span> <span class=\"n\">search_type</span><span class=\"o\">=</span><span class=\"s1\">&#39;phrase&#39;</span><span class=\"p\">)</span>  <span class=\"c1\"># a phrase</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">SearchQuery</span><span class=\"p\">(</span><span class=\"s1\">&#39;tomato red&#39;</span><span class=\"p\">,</span> <span class=\"n\">search_type</span><span class=\"o\">=</span><span class=\"s1\">&#39;phrase&#39;</span><span class=\"p\">)</span>  <span class=\"c1\"># a different phrase</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">SearchQuery</span><span class=\"p\">(</span><span class=\"s2\">&quot;&#39;tomato&#39; &amp; (&#39;red&#39; | &#39;green&#39;)&quot;</span><span class=\"p\">,</span> <span class=\"n\">search_type</span><span class=\"o\">=</span><span class=\"s1\">&#39;raw&#39;</span><span class=\"p\">)</span>  <span class=\"c1\"># boolean operators</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">SearchQuery</span><span class=\"p\">(</span><span class=\"s2\">&quot;&#39;tomato&#39; (&#39;red&#39; OR &#39;green&#39;)&quot;</span><span class=\"p\">,</span> <span class=\"n\">search_type</span><span class=\"o\">=</span><span class=\"s1\">&#39;websearch&#39;</span><span class=\"p\">)</span>  <span class=\"c1\"># websearch operators</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">SearchQuery</span></code> 术语可以按逻辑组合，以提供更大的灵活性：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.postgres.search</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">SearchQuery</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">SearchQuery</span><span class=\"p\">(</span><span class=\"s1\">&#39;meat&#39;</span><span class=\"p\">)</span> <span class=\"o\">&amp;</span> <span class=\"n\">SearchQuery</span><span class=\"p\">(</span><span class=\"s1\">&#39;cheese&#39;</span><span class=\"p\">)</span>  <span class=\"c1\"># AND</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">SearchQuery</span><span class=\"p\">(</span><span class=\"s1\">&#39;meat&#39;</span><span class=\"p\">)</span> <span class=\"o\">|</span> <span class=\"n\">SearchQuery</span><span class=\"p\">(</span><span class=\"s1\">&#39;cheese&#39;</span><span class=\"p\">)</span>  <span class=\"c1\"># OR</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"o\">~</span><span class=\"n\">SearchQuery</span><span class=\"p\">(</span><span class=\"s1\">&#39;meat&#39;</span><span class=\"p\">)</span>  <span class=\"c1\"># NOT</span>\n</code></pre></div>\n<p>参见 <a class=\"reference internal\" href=\"#postgresql-fts-search-configuration\"><span class=\"std std-ref\">更改搜索配置</span></a> 对 <code class=\"docutils literal notranslate\"><span class=\"pre\">config</span></code> 参数的解释。</p>\n<aside class=\"version-note version-changed\" data-version=\"3.1\">\n<p class=\"version-note-title\">Changed in Django 3.1</p><p>在 <code class=\"docutils literal notranslate\"><span class=\"pre\">SearchQuery.value</span></code> 中增加了对 <code class=\"docutils literal notranslate\"><span class=\"pre\">'websearch'</span></code> 搜索类型和查询表达式的支持。</p>\n</aside>\n</section>\n<section id=\"searchrank\">\n<h2><code class=\"docutils literal notranslate\"><span class=\"pre\">SearchRank</span></code><a class=\"heading-anchor\" href=\"#searchrank\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.postgres.search.SearchRank\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">SearchRank</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">vector</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">query</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">weights</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">normalization</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">cover_density</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.postgres.search.SearchRank\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>到目前为止，我们已经返回了向量和查询之间可能匹配的结果。很可能你会希望按照某种相关性对结果进行排序。PostgreSQL 提供了一个排序函数，它考虑了查询术语在文档中出现的频率，术语在文档中的相近程度，以及它们出现的部分在文档中的重要性。匹配度越高，排名值越高。要按相关性排序：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.postgres.search</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">SearchQuery</span><span class=\"p\">,</span> <span class=\"n\">SearchRank</span><span class=\"p\">,</span> <span class=\"n\">SearchVector</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">vector</span> <span class=\"o\">=</span> <span class=\"n\">SearchVector</span><span class=\"p\">(</span><span class=\"s1\">&#39;body_text&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">query</span> <span class=\"o\">=</span> <span class=\"n\">SearchQuery</span><span class=\"p\">(</span><span class=\"s1\">&#39;cheese&#39;</span><span class=\"p\">)</span>\n<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><span class=\"n\">rank</span><span class=\"o\">=</span><span class=\"n\">SearchRank</span><span class=\"p\">(</span><span class=\"n\">vector</span><span class=\"p\">,</span> <span class=\"n\">query</span><span class=\"p\">))</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">(</span><span class=\"s1\">&#39;-rank&#39;</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>参见 <a class=\"reference internal\" href=\"#postgresql-fts-weighting-queries\"><span class=\"std std-ref\">加权查询</span></a> 关于 <code class=\"docutils literal notranslate\"><span class=\"pre\">weights</span></code> 参数的解释。</p>\n<p>将 <code class=\"docutils literal notranslate\"><span class=\"pre\">cover_density</span></code> 参数设置为 <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>，启用覆盖密度排序，即考虑匹配的查询词的接近程度。</p>\n<p>为 <code class=\"docutils literal notranslate\"><span class=\"pre\">normalization</span></code> 参数提供一个整数，以控制等级标准化。这个整数是一个位掩码，所以你可以结合多种行为：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Value</span>\n<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\">rank</span><span class=\"o\">=</span><span class=\"n\">SearchRank</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>        <span class=\"n\">vector</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>        <span class=\"n\">query</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>        <span class=\"n\">normalization</span><span class=\"o\">=</span><span class=\"n\">Value</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">bitor</span><span class=\"p\">(</span><span class=\"n\">Value</span><span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">)),</span>\n<span class=\"gp\">... </span>    <span class=\"p\">)</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n</code></pre></div>\n<p>PostgreSQL 文档中有更多关于 <a class=\"reference external\" href=\"https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-RANKING\">不同排序归一化选项</a> 的细节。</p>\n<aside class=\"version-note version-added\" data-version=\"3.1\">\n<p class=\"version-note-title\">New in Django 3.1</p><p>增加了 <code class=\"docutils literal notranslate\"><span class=\"pre\">normalization</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">cover_density</span></code> 参数。</p>\n</aside>\n</section>\n<section id=\"searchheadline\">\n<h2><code class=\"docutils literal notranslate\"><span class=\"pre\">SearchHeadline</span></code><a class=\"heading-anchor\" href=\"#searchheadline\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<aside class=\"version-note version-added\" data-version=\"3.1\">\n<p class=\"version-note-title\">New in Django 3.1</p></aside>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.postgres.search.SearchHeadline\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">SearchHeadline</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">expression</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">query</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">config</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">start_sel</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">stop_sel</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">max_words</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">min_words</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">short_word</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">highlight_all</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">max_fragments</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">fragment_delimiter</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.postgres.search.SearchHeadline\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>接受一个文本字段或一个表达式、一个查询、一个配置和一组选项。返回高亮显示的搜索结果。</p>\n<p>将 <code class=\"docutils literal notranslate\"><span class=\"pre\">start_sel</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">stop_sel</span></code> 参数设置为字符串值，用于在文档中高亮显示查询词。PostgreSQL 的默认值是 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;b&gt;</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;/b&gt;</span></code>。</p>\n<p>为 <code class=\"docutils literal notranslate\"><span class=\"pre\">max_words</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">min_words</span></code> 参数提供整数值，以确定最长和最短的标题。PostgreSQL 的默认值是 35 和 15。</p>\n<p>为 <code class=\"docutils literal notranslate\"><span class=\"pre\">short_word</span></code> 参数提供一个整数值，以便在每个标题中丢弃这个长度或更少的字。PostgreSQL 的默认值是 3。</p>\n<p>将 <code class=\"docutils literal notranslate\"><span class=\"pre\">highlight_all</span></code> 参数设置为 <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>，以使用整个文档来代替片段，并忽略 <code class=\"docutils literal notranslate\"><span class=\"pre\">max_words</span></code>、<code class=\"docutils literal notranslate\"><span class=\"pre\">min_words</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">short_word</span></code> 参数。这在 PostgreSQL 中是默认禁用的。</p>\n<p>为 <code class=\"docutils literal notranslate\"><span class=\"pre\">max_fragments</span></code> 提供一个非零的整数值，以设置要显示的最大片段数。在 PostgreSQL 中默认是禁用的。</p>\n<p>设置 <code class=\"docutils literal notranslate\"><span class=\"pre\">fragment_delimiter</span></code> 字符串参数来配置片段之间的定界符。PostgreSQL 的默认值是 <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;</span> <span class=\"pre\">...</span> <span class=\"pre\">&quot;</span></code>。</p>\n<p>PostgreSQL 文档中有更多关于 <a class=\"reference external\" href=\"https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-HEADLINE\">高亮搜索结果</a> 的细节。</p>\n<p>使用实例：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.postgres.search</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">SearchHeadline</span><span class=\"p\">,</span> <span class=\"n\">SearchQuery</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">query</span> <span class=\"o\">=</span> <span class=\"n\">SearchQuery</span><span class=\"p\">(</span><span class=\"s1\">&#39;red tomato&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">entry</span> <span class=\"o\">=</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\">headline</span><span class=\"o\">=</span><span class=\"n\">SearchHeadline</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>        <span class=\"s1\">&#39;body_text&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>        <span class=\"n\">query</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>        <span class=\"n\">start_sel</span><span class=\"o\">=</span><span class=\"s1\">&#39;&lt;span&gt;&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>        <span class=\"n\">stop_sel</span><span class=\"o\">=</span><span class=\"s1\">&#39;&lt;/span&gt;&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"p\">),</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">entry</span><span class=\"o\">.</span><span class=\"n\">headline</span><span class=\"p\">)</span>\n<span class=\"go\">Sandwich with &lt;span&gt;tomato&lt;/span&gt; and &lt;span&gt;red&lt;/span&gt; cheese.</span>\n</code></pre></div>\n<p>参见 <a class=\"reference internal\" href=\"#postgresql-fts-search-configuration\"><span class=\"std std-ref\">更改搜索配置</span></a> 对 <code class=\"docutils literal notranslate\"><span class=\"pre\">config</span></code> 参数的解释。</p>\n</section>\n<section id=\"changing-the-search-configuration\">\n<span id=\"postgresql-fts-search-configuration\"></span><h2>更改搜索配置<a class=\"heading-anchor\" href=\"#changing-the-search-configuration\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>你可以为 <a class=\"reference internal\" href=\"#django.contrib.postgres.search.SearchVector\" title=\"django.contrib.postgres.search.SearchVector\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SearchVector</span></code></a> 和 <a class=\"reference internal\" href=\"#django.contrib.postgres.search.SearchQuery\" title=\"django.contrib.postgres.search.SearchQuery\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SearchQuery</span></code></a> 指定 <code class=\"docutils literal notranslate\"><span class=\"pre\">config</span></code> 属性，以使用不同的搜索配置。这允许使用数据库定义的不同语言解析器和字典：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.postgres.search</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">SearchQuery</span><span class=\"p\">,</span> <span class=\"n\">SearchVector</span>\n<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=\"s1\">&#39;body_text&#39;</span><span class=\"p\">,</span> <span class=\"n\">config</span><span class=\"o\">=</span><span class=\"s1\">&#39;french&#39;</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=\"n\">SearchQuery</span><span class=\"p\">(</span><span class=\"s1\">&#39;œuf&#39;</span><span class=\"p\">,</span> <span class=\"n\">config</span><span class=\"o\">=</span><span class=\"s1\">&#39;french&#39;</span><span class=\"p\">))</span>\n<span class=\"go\">[&lt;Entry: Pain perdu&gt;]</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">config</span></code> 的值也可以储存在另一列中：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">F</span>\n<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=\"s1\">&#39;body_text&#39;</span><span class=\"p\">,</span> <span class=\"n\">config</span><span class=\"o\">=</span><span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;blog__language&#39;</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=\"n\">SearchQuery</span><span class=\"p\">(</span><span class=\"s1\">&#39;œuf&#39;</span><span class=\"p\">,</span> <span class=\"n\">config</span><span class=\"o\">=</span><span class=\"n\">F</span><span class=\"p\">(</span><span class=\"s1\">&#39;blog__language&#39;</span><span class=\"p\">)))</span>\n<span class=\"go\">[&lt;Entry: Pain perdu&gt;]</span>\n</code></pre></div>\n</section>\n<section id=\"weighting-queries\">\n<span id=\"postgresql-fts-weighting-queries\"></span><h2>加权查询<a class=\"heading-anchor\" href=\"#weighting-queries\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>每个字段在查询中的相关度可能不一样，所以在组合之前可以设置各种向量的权重：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.postgres.search</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">SearchQuery</span><span class=\"p\">,</span> <span class=\"n\">SearchRank</span><span class=\"p\">,</span> <span class=\"n\">SearchVector</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">vector</span> <span class=\"o\">=</span> <span class=\"n\">SearchVector</span><span class=\"p\">(</span><span class=\"s1\">&#39;body_text&#39;</span><span class=\"p\">,</span> <span class=\"n\">weight</span><span class=\"o\">=</span><span class=\"s1\">&#39;A&#39;</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"n\">SearchVector</span><span class=\"p\">(</span><span class=\"s1\">&#39;blog__tagline&#39;</span><span class=\"p\">,</span> <span class=\"n\">weight</span><span class=\"o\">=</span><span class=\"s1\">&#39;B&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">query</span> <span class=\"o\">=</span> <span class=\"n\">SearchQuery</span><span class=\"p\">(</span><span class=\"s1\">&#39;cheese&#39;</span><span class=\"p\">)</span>\n<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><span class=\"n\">rank</span><span class=\"o\">=</span><span class=\"n\">SearchRank</span><span class=\"p\">(</span><span class=\"n\">vector</span><span class=\"p\">,</span> <span class=\"n\">query</span><span class=\"p\">))</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">rank__gte</span><span class=\"o\">=</span><span class=\"mf\">0.3</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">(</span><span class=\"s1\">&#39;rank&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>权重应该是下列字母之一。默认情况下，这些权重分别是指数字 <code class=\"docutils literal notranslate\"><span class=\"pre\">0.1</span></code>、<code class=\"docutils literal notranslate\"><span class=\"pre\">0.2</span></code>、<code class=\"docutils literal notranslate\"><span class=\"pre\">0.4</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">1.0</span></code>。如果你希望以不同的方式对它们进行加权，请将四个浮点数的列表传递给 <a class=\"reference internal\" href=\"#django.contrib.postgres.search.SearchRank\" title=\"django.contrib.postgres.search.SearchRank\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SearchRank</span></code></a> 作为 <code class=\"docutils literal notranslate\"><span class=\"pre\">weights</span></code>，顺序与上述相同：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">rank</span> <span class=\"o\">=</span> <span class=\"n\">SearchRank</span><span class=\"p\">(</span><span class=\"n\">vector</span><span class=\"p\">,</span> <span class=\"n\">query</span><span class=\"p\">,</span> <span class=\"n\">weights</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"mf\">0.2</span><span class=\"p\">,</span> <span class=\"mf\">0.4</span><span class=\"p\">,</span> <span class=\"mf\">0.6</span><span class=\"p\">,</span> <span class=\"mf\">0.8</span><span class=\"p\">])</span>\n<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><span class=\"n\">rank</span><span class=\"o\">=</span><span class=\"n\">rank</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">rank__gte</span><span class=\"o\">=</span><span class=\"mf\">0.3</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">(</span><span class=\"s1\">&#39;-rank&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"performance\">\n<h2>性能<a class=\"heading-anchor\" href=\"#performance\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>使用这些函数都不需要特殊的数据库配置，但是，如果你搜索的记录超过几百条，你很可能会遇到性能问题。例如，全文搜索是一个比比较整数大小更密集的过程。</p>\n<p>如果你要查询的所有字段都包含在一个特定的模型中，你可以创建一个与你希望使用的搜索向量相匹配的功能索引。PostgreSQL 文档中有关于 <a class=\"reference external\" href=\"https://www.postgresql.org/docs/current/textsearch-tables.html#TEXTSEARCH-TABLES-INDEX\">为全文搜索创建索引</a> 的详细介绍。</p>\n<section id=\"searchvectorfield\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">SearchVectorField</span></code><a class=\"heading-anchor\" href=\"#searchvectorfield\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.postgres.search.SearchVectorField\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">SearchVectorField</span></span><a class=\"heading-anchor\" href=\"#django.contrib.postgres.search.SearchVectorField\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>如果这种方法变得太慢，你可以在你的模型中添加一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">SearchVectorField</span></code>。你需要用触发器来填充它，例如，如 <a class=\"reference external\" href=\"https://www.postgresql.org/docs/current/textsearch-features.html#TEXTSEARCH-UPDATE-TRIGGERS\">PostgreSQL 文档</a> 中所述。然后，你可以像查询一个注解的 <code class=\"docutils literal notranslate\"><span class=\"pre\">SearchVector</span></code> 一样查询这个字段：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code 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\">update</span><span class=\"p\">(</span><span class=\"n\">search_vector</span><span class=\"o\">=</span><span class=\"n\">SearchVector</span><span class=\"p\">(</span><span class=\"s1\">&#39;body_text&#39;</span><span class=\"p\">))</span>\n<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\">search_vector</span><span class=\"o\">=</span><span class=\"s1\">&#39;cheese&#39;</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</section>\n</section>\n<section id=\"trigram-similarity\">\n<h2>三元相似度<a class=\"heading-anchor\" href=\"#trigram-similarity\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>另一种搜索方法是三元相似度。trigram 是一组连续的三个字符。除了 <a class=\"reference internal\" href=\"/zh-hans/3.1/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> 查找之外，你还可以使用其他几个表达式。</p>\n<p>要使用它们，你需要激活 PostgreSQL 上的 <a class=\"reference external\" href=\"https://www.postgresql.org/docs/current/pgtrgm.html\">pg_trgm 扩展</a> 。你可以使用 <a class=\"reference internal\" href=\"/zh-hans/3.1/ref/contrib/postgres/operations/#django.contrib.postgres.operations.TrigramExtension\" title=\"django.contrib.postgres.operations.TrigramExtension\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TrigramExtension</span></code></a> 迁移操作来安装它。</p>\n<section id=\"trigramsimilarity\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">TrigramSimilarity</span></code><a class=\"heading-anchor\" href=\"#trigramsimilarity\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.postgres.search.TrigramSimilarity\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">TrigramSimilarity</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">expression</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">string</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">extra</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.postgres.search.TrigramSimilarity\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>接受一个字段名或表达式，以及一个字符串或表达式。返回两个参数之间的三元相似度。</p>\n<p>使用实例：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.postgres.search</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">TrigramSimilarity</span>\n<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\">create</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;Katy Stevens&#39;</span><span class=\"p\">)</span>\n<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\">create</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;Stephen Keats&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">test</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;Katie Stephens&#39;</span>\n<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\">annotate</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">similarity</span><span class=\"o\">=</span><span class=\"n\">TrigramSimilarity</span><span class=\"p\">(</span><span class=\"s1\">&#39;name&#39;</span><span class=\"p\">,</span> <span class=\"n\">test</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\">similarity__gt</span><span class=\"o\">=</span><span class=\"mf\">0.3</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">(</span><span class=\"s1\">&#39;-similarity&#39;</span><span class=\"p\">)</span>\n<span class=\"go\">[&lt;Author: Katy Stevens&gt;, &lt;Author: Stephen Keats&gt;]</span>\n</code></pre></div>\n</section>\n<section id=\"trigramdistance\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">TrigramDistance</span></code><a class=\"heading-anchor\" href=\"#trigramdistance\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.postgres.search.TrigramDistance\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">TrigramDistance</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">expression</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">string</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">extra</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.postgres.search.TrigramDistance\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>接受一个字段名或表达式，以及一个字符串或表达式。返回两个参数之间的三元距离。</p>\n<p>使用实例：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.postgres.search</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">TrigramDistance</span>\n<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\">create</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;Katy Stevens&#39;</span><span class=\"p\">)</span>\n<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\">create</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;Stephen Keats&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">test</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;Katie Stephens&#39;</span>\n<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\">annotate</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">distance</span><span class=\"o\">=</span><span class=\"n\">TrigramDistance</span><span class=\"p\">(</span><span class=\"s1\">&#39;name&#39;</span><span class=\"p\">,</span> <span class=\"n\">test</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\">distance__lte</span><span class=\"o\">=</span><span class=\"mf\">0.7</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">(</span><span class=\"s1\">&#39;distance&#39;</span><span class=\"p\">)</span>\n<span class=\"go\">[&lt;Author: Katy Stevens&gt;, &lt;Author: Stephen Keats&gt;]</span>\n</code></pre></div>\n</section>\n</section>","rootId":"full-text-search","toc":[{"title":"search 查找","anchor":"the-search-lookup","children":[]},{"title":"SearchVector","anchor":"searchvector","children":[]},{"title":"SearchQuery","anchor":"searchquery","children":[]},{"title":"SearchRank","anchor":"searchrank","children":[]},{"title":"SearchHeadline","anchor":"searchheadline","children":[]},{"title":"更改搜索配置","anchor":"changing-the-search-configuration","children":[]},{"title":"加权查询","anchor":"weighting-queries","children":[]},{"title":"性能","anchor":"performance","children":[{"title":"SearchVectorField","anchor":"searchvectorfield","children":[]}]},{"title":"三元相似度","anchor":"trigram-similarity","children":[{"title":"TrigramSimilarity","anchor":"trigramsimilarity","children":[]},{"title":"TrigramDistance","anchor":"trigramdistance","children":[]}]}],"breadcrumbs":[{"docname":"ref/index","title":"API 参考","url":"/zh-hans/3.1/ref/"},{"docname":"ref/contrib/index","title":"contrib 包","url":"/zh-hans/3.1/ref/contrib/"},{"docname":"ref/contrib/postgres/index","title":"django.contrib.postgres","url":"/zh-hans/3.1/ref/contrib/postgres/"}],"prev":{"docname":"ref/contrib/postgres/operations","title":"数据库迁移操作","url":"/zh-hans/3.1/ref/contrib/postgres/operations/"},"next":{"docname":"ref/contrib/postgres/validators","title":"验证器","url":"/zh-hans/3.1/ref/contrib/postgres/validators/"},"formats":{"html":"/zh-hans/3.1/ref/contrib/postgres/search/","markdown":"/zh-hans/3.1/ref/contrib/postgres/search.md","json":"/zh-hans/3.1/ref/contrib/postgres/search.json"},"source":"https://github.com/django/django/blob/stable/3.1.x/docs/ref/contrib/postgres/search.txt","official":"https://docs.djangoproject.com/zh-hans/3.1/ref/contrib/postgres/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"],"inLocales":["en","zh-hans","fr","ja","id","pt-br","ko","es","el","pl"]}