首页
随机页面
分类
查看“Django/docs/3.2.x/ref/contrib/postgres/search”的源代码
来自菜鸟教程
Django/docs/3.2.x/ref/contrib/postgres/search / ←
全文搜索 — Django 文档
跳转至:
导航
、
搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
{{DISPLAYTITLE:全文检索}} <div id="full-text-search" class="section"> = 全文检索 = <code>django.contrib.postgres.search</code>模块中的数据库函数简化了PostgreSQL的[https://www.postgresql.org/docs/current/textsearch.html 全文搜索引擎]的使用。 对于本文档中的示例,我们将使用 [[../../../../topics/db/queries|进行查询]] 中定义的模型。 <div class="admonition seealso"> 也可以看看 有关搜索的高级概述,请参阅 [[../../../../topics/db/search|主题文档]] 。 </div> <div id="the-search-lookup" class="section"> == search 查找 == 使用全文搜索的一种常见方法是针对数据库中的单个列搜索单个术语。 例如: <div class="highlight-default notranslate"> <div class="highlight"> <syntaxhighlight lang="python">>>> Entry.objects.filter(body_text__search='Cheese') [<Entry: Cheese on Toast recipes>, <Entry: Pizza Recipes>]</syntaxhighlight> </div> </div> 这将在数据库中的 <code>body_text</code> 字段中创建一个 <code>to_tsvector</code>,并从搜索词 <code>'Cheese'</code> 中创建一个 <code>plainto_tsquery</code>,两者都使用默认的数据库搜索配置。 通过匹配查询和向量获得结果。 要使用 <code>search</code> 查找,<code>'django.contrib.postgres'</code> 必须在您的 [[#id1|:setting:`INSTALLED_APPS`]] 中。 <div class="versionchanged"> <span class="versionmodified changed"> 3.1 版更改: </span> 添加了对查询表达式的支持。 </div> </div> <div id="searchvector" class="section"> == SearchVector == ; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">SearchVector</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">expressions</span></span>'', ''<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>'', ''<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>''<span class="sig-paren">)</span> : 针对单个字段进行搜索很好,但也很有限。 我们正在搜索的 <code>Entry</code> 实例属于 <code>Blog</code>,它有一个 <code>tagline</code> 字段。 要查询这两个字段,请使用 <code>SearchVector</code>: <div class="highlight-default notranslate"> <div class="highlight"> <syntaxhighlight lang="python">>>> from django.contrib.postgres.search import SearchVector >>> Entry.objects.annotate( ... search=SearchVector('body_text', 'blog__tagline'), ... ).filter(search='Cheese') [<Entry: Cheese on Toast recipes>, <Entry: Pizza Recipes>]</syntaxhighlight> </div> </div> <code>SearchVector</code> 的参数可以是任何 [[../../../models/expressions#django.db.models|Expression]] 或字段的名称。 多个参数将使用空格连接在一起,以便搜索文档将它们全部包含在内。 <code>SearchVector</code> 对象可以组合在一起,允许您重复使用它们。 例如: <div class="highlight-default notranslate"> <div class="highlight"> <syntaxhighlight lang="python">>>> Entry.objects.annotate( ... search=SearchVector('body_text') + SearchVector('blog__tagline'), ... ).filter(search='Cheese') [<Entry: Cheese on Toast recipes>, <Entry: Pizza Recipes>]</syntaxhighlight> </div> </div> 有关 <code>config</code> 和 <code>weight</code> 参数的说明,请参阅 [[#postgresql-fts-search-configuration|更改搜索配置]] 和 [[#postgresql-fts-weighting-queries|加权查询]] 。 </div> <div id="searchquery" class="section"> == SearchQuery == ; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">SearchQuery</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">value</span></span>'', ''<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>'', ''<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>''<span class="sig-paren">)</span> : <code>SearchQuery</code> 将用户提供的术语转换为搜索查询对象,数据库将其与搜索向量进行比较。 默认情况下,用户提供的所有单词都会通过词干算法,然后它会查找所有结果术语的匹配项。 如果 <code>search_type</code> 是 <code>'plain'</code>(这是默认值),则将这些术语视为单独的关键字。 如果 <code>search_type</code> 是 <code>'phrase'</code>,则将这些术语视为单个短语。 如果 <code>search_type</code> 是 <code>'raw'</code>,那么您可以提供带有术语和运算符的格式化搜索查询。 如果 <code>search_type</code> 是 <code>'websearch'</code>,那么您可以提供格式化的搜索查询,类似于网络搜索引擎使用的查询。 <code>'websearch'</code> 需要 PostgreSQL ≥ 11。 阅读 PostgreSQL 的 [https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES 全文搜索文档] 以了解差异和语法。 例子: <div class="doctest highlight-default notranslate"> <div class="highlight"> <syntaxhighlight lang="python">>>> from django.contrib.postgres.search import SearchQuery >>> SearchQuery('red tomato') # two keywords >>> SearchQuery('tomato red') # same results as above >>> SearchQuery('red tomato', search_type='phrase') # a phrase >>> SearchQuery('tomato red', search_type='phrase') # a different phrase >>> SearchQuery("'tomato' & ('red' | 'green')", search_type='raw') # boolean operators >>> SearchQuery("'tomato' ('red' OR 'green')", search_type='websearch') # websearch operators</syntaxhighlight> </div> </div> <code>SearchQuery</code> 项可以逻辑组合以提供更大的灵活性: <div class="highlight-default notranslate"> <div class="highlight"> <syntaxhighlight lang="python">>>> from django.contrib.postgres.search import SearchQuery >>> SearchQuery('meat') & SearchQuery('cheese') # AND >>> SearchQuery('meat') | SearchQuery('cheese') # OR >>> ~SearchQuery('meat') # NOT</syntaxhighlight> </div> </div> 有关 <code>config</code> 参数的说明,请参阅 [[#postgresql-fts-search-configuration|更改搜索配置]] 。 <div class="versionchanged"> <span class="versionmodified changed"> 3.1 版更改: </span> 增加了对 <code>SearchQuery.value</code> 中的 <code>'websearch'</code> 搜索类型和查询表达式的支持。 </div> </div> <div id="searchrank" class="section"> == SearchRank == ; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">SearchRank</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">vector</span></span>'', ''<span class="n"><span class="pre">query</span></span>'', ''<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>'', ''<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>'', ''<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>''<span class="sig-paren">)</span> : 到目前为止,我们已经返回了向量和查询之间可能存在任何匹配的结果。 您可能希望按某种相关性对结果进行排序。 PostgreSQL 提供了一个排序功能,它考虑了查询词在文档中出现的频率、词在文档中的接近程度以及文档中出现的部分的重要性。 匹配越好,排名的值就越高。 按相关性排序: <div class="highlight-default notranslate"> <div class="highlight"> <syntaxhighlight lang="python">>>> from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector >>> vector = SearchVector('body_text') >>> query = SearchQuery('cheese') >>> Entry.objects.annotate(rank=SearchRank(vector, query)).order_by('-rank') [<Entry: Cheese on Toast recipes>, <Entry: Pizza recipes>]</syntaxhighlight> </div> </div> 有关 <code>weights</code> 参数的说明,请参阅 [[#postgresql-fts-weighting-queries|加权查询]] 。 将 <code>cover_density</code> 参数设置为 <code>True</code> 以启用覆盖密度排名,这意味着将匹配查询词的邻近性考虑在内。 为 <code>normalization</code> 参数提供一个整数以控制等级归一化。 这个整数是一个位掩码,因此您可以组合多种行为: <div class="highlight-default notranslate"> <div class="highlight"> <syntaxhighlight lang="python">>>> from django.db.models import Value >>> Entry.objects.annotate( ... rank=SearchRank( ... vector, ... query, ... normalization=Value(2).bitor(Value(4)), ... ) ... )</syntaxhighlight> </div> </div> PostgreSQL 文档有更多关于 [https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-RANKING 不同等级规范化选项] 的详细信息。 <div class="versionadded"> <span class="versionmodified added"> 3.1 新功能: </span> 增加了 <code>normalization</code> 和 <code>cover_density</code> 参数。 </div> </div> <div id="searchheadline" class="section"> == SearchHeadline == <div class="versionadded"> <span class="versionmodified added">3.1 版中的新功能。</span> </div> ; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">SearchHeadline</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">expression</span></span>'', ''<span class="n"><span class="pre">query</span></span>'', ''<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>'', ''<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>'', ''<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>'', ''<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>'', ''<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>'', ''<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>'', ''<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>'', ''<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>'', ''<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>''<span class="sig-paren">)</span> : 接受单个文本字段或表达式、查询、配置和一组选项。 返回突出显示的搜索结果。 将 <code>start_sel</code> 和 <code>stop_sel</code> 参数设置为用于在文档中包装突出显示的查询词的字符串值。 PostgreSQL 的默认值是 <code><b></code> 和 <code></b></code>。 为 <code>max_words</code> 和 <code>min_words</code> 参数提供整数值以确定最长和最短的标题。 PostgreSQL 的默认值是 35 和 15。 为 <code>short_word</code> 参数提供一个整数值以丢弃每个标题中此长度或更少的单词。 PostgreSQL 的默认值为 3。 将 <code>highlight_all</code> 参数设置为 <code>True</code> 以使用整个文档代替片段并忽略 <code>max_words</code>、<code>min_words</code> 和 <code>short_word</code> 参数. 这在 PostgreSQL 中默认是禁用的。 为 <code>max_fragments</code> 提供一个非零整数值以设置要显示的最大片段数。 这在 PostgreSQL 中默认是禁用的。 设置 <code>fragment_delimiter</code> 字符串参数以配置分片之间的分隔符。 PostgreSQL 的默认值是 <code>" ... "</code>。 PostgreSQL 文档有更多关于 [https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-HEADLINE 突出显示搜索结果] 的细节。 用法示例: <div class="highlight-default notranslate"> <div class="highlight"> <syntaxhighlight lang="python">>>> from django.contrib.postgres.search import SearchHeadline, SearchQuery >>> query = SearchQuery('red tomato') >>> entry = Entry.objects.annotate( ... headline=SearchHeadline( ... 'body_text', ... query, ... start_sel='<span>', ... stop_sel='</span>', ... ), ... ).get() >>> print(entry.headline) Sandwich with <span>tomato</span> and <span>red</span> cheese.</syntaxhighlight> </div> </div> 有关 <code>config</code> 参数的说明,请参阅 [[#postgresql-fts-search-configuration|更改搜索配置]] 。 </div> <div id="changing-the-search-configuration" class="section"> <span id="postgresql-fts-search-configuration"></span> == 更改搜索配置 == 您可以将 <code>config</code> 属性指定给 [[#django.contrib.postgres.search.SearchVector|SearchVector]] 和 [[#django.contrib.postgres.search.SearchQuery|SearchQuery]] 以使用不同的搜索配置。 这允许使用数据库定义的不同语言解析器和字典: <div class="highlight-default notranslate"> <div class="highlight"> <syntaxhighlight lang="python">>>> from django.contrib.postgres.search import SearchQuery, SearchVector >>> Entry.objects.annotate( ... search=SearchVector('body_text', config='french'), ... ).filter(search=SearchQuery('œuf', config='french')) [<Entry: Pain perdu>]</syntaxhighlight> </div> </div> <code>config</code> 的值也可以存储在另一列中: <div class="highlight-default notranslate"> <div class="highlight"> <syntaxhighlight lang="python">>>> from django.db.models import F >>> Entry.objects.annotate( ... search=SearchVector('body_text', config=F('blog__language')), ... ).filter(search=SearchQuery('œuf', config=F('blog__language'))) [<Entry: Pain perdu>]</syntaxhighlight> </div> </div> </div> <div id="weighting-queries" class="section"> <span id="postgresql-fts-weighting-queries"></span> == 加权查询 == 每个字段在查询中可能不具有相同的相关性,因此您可以在组合它们之前设置各种向量的权重: <div class="highlight-default notranslate"> <div class="highlight"> <syntaxhighlight lang="python">>>> from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector >>> vector = SearchVector('body_text', weight='A') + SearchVector('blog__tagline', weight='B') >>> query = SearchQuery('cheese') >>> Entry.objects.annotate(rank=SearchRank(vector, query)).filter(rank__gte=0.3).order_by('rank')</syntaxhighlight> </div> </div> 重量应为以下字母之一:D、C、B、A。 默认情况下,这些权重分别指代数字 <code>0.1</code>、<code>0.2</code>、<code>0.4</code> 和 <code>1.0</code>。 如果您希望对它们进行不同的加权,请按照上述相同的顺序将四个浮点数的列表作为 <code>weights</code> 传递给 [[#django.contrib.postgres.search.SearchRank|SearchRank]]: <div class="highlight-default notranslate"> <div class="highlight"> <syntaxhighlight lang="python">>>> rank = SearchRank(vector, query, weights=[0.2, 0.4, 0.6, 0.8]) >>> Entry.objects.annotate(rank=rank).filter(rank__gte=0.3).order_by('-rank')</syntaxhighlight> </div> </div> </div> <div id="performance" class="section"> == 性能 == 使用这些功能中的任何一个都不需要特殊的数据库配置,但是,如果您搜索的记录超过几百条,则可能会遇到性能问题。 例如,全文搜索是一个比比较整数大小更密集的过程。 如果您查询的所有字段都包含在一个特定模型中,您可以创建一个与您希望使用的搜索向量相匹配的功能索引。 PostgreSQL 文档详细介绍了 [https://www.postgresql.org/docs/current/textsearch-tables.html#TEXTSEARCH-TABLES-INDEX 为全文搜索创建索引] 。 <div id="searchvectorfield" class="section"> === SearchVectorField === ; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">SearchVectorField</span></span> : 如果这种方法变得太慢,您可以向模型添加 <code>SearchVectorField</code>。 例如,您需要使用触发器填充它,如 [https://www.postgresql.org/docs/current/textsearch-features.html#TEXTSEARCH-UPDATE-TRIGGERS PostgreSQL 文档] 中所述。 然后,您可以查询该字段,就像它是带注释的 <code>SearchVector</code>: <div class="highlight-default notranslate"> <div class="highlight"> <syntaxhighlight lang="python">>>> Entry.objects.update(search_vector=SearchVector('body_text')) >>> Entry.objects.filter(search_vector='cheese') [<Entry: Cheese on Toast recipes>, <Entry: Pizza recipes>]</syntaxhighlight> </div> </div> </div> </div> <div id="trigram-similarity" class="section"> == 三元组相似度 == 另一种搜索方法是三元组相似性。 三元组是一组三个连续的字符。 除了 [[#id3|:lookup:`trigram_similar`]] 查找之外,您还可以使用其他几个表达式。 要使用它们,您需要在 PostgreSQL 上激活 [https://www.postgresql.org/docs/current/pgtrgm.html pg_trgm 扩展] 。 您可以使用 [[../operations#django.contrib.postgres.operations|TrigramExtension]] 迁移操作安装它。 <div id="trigramsimilarity" class="section"> === TrigramSimilarity === ; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">TrigramSimilarity</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">expression</span></span>'', ''<span class="n"><span class="pre">string</span></span>'', ''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">extra</span></span>''<span class="sig-paren">)</span> : 接受字段名称或表达式,以及字符串或表达式。 返回两个参数之间的三元组相似度。 用法示例: <div class="highlight-default notranslate"> <div class="highlight"> <syntaxhighlight lang="python">>>> from django.contrib.postgres.search import TrigramSimilarity >>> Author.objects.create(name='Katy Stevens') >>> Author.objects.create(name='Stephen Keats') >>> test = 'Katie Stephens' >>> Author.objects.annotate( ... similarity=TrigramSimilarity('name', test), ... ).filter(similarity__gt=0.3).order_by('-similarity') [<Author: Katy Stevens>, <Author: Stephen Keats>]</syntaxhighlight> </div> </div> </div> <div id="trigramdistance" class="section"> === TrigramDistance === ; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">TrigramDistance</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">expression</span></span>'', ''<span class="n"><span class="pre">string</span></span>'', ''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">extra</span></span>''<span class="sig-paren">)</span> : 接受字段名称或表达式,以及字符串或表达式。 返回两个参数之间的三元组距离。 用法示例: <div class="highlight-default notranslate"> <div class="highlight"> <syntaxhighlight lang="python">>>> from django.contrib.postgres.search import TrigramDistance >>> Author.objects.create(name='Katy Stevens') >>> Author.objects.create(name='Stephen Keats') >>> test = 'Katie Stephens' >>> Author.objects.annotate( ... distance=TrigramDistance('name', test), ... ).filter(distance__lte=0.7).order_by('distance') [<Author: Katy Stevens>, <Author: Stephen Keats>]</syntaxhighlight> </div> </div> </div> </div> </div> <div class="clearer"> </div> [[Category:django 3.2.x 文档]]
返回至“
全文搜索 — Django 文档
”。