使用PostgreSQL全文搜索排名的最佳方式

2024-02-20

继从这个答案 https://stackoverflow.com/a/4014625/265521如果我想按排名排序,我想知道使用 PostgreSQL 内置全文搜索的最佳方法是什么,and限制为仅匹配查询。

让我们假设一个非常简单的表。

CREATE TABLE pictures (
  id SERIAL PRIMARY KEY,
  title varchar(300),
  ...
)

管他呢。现在我想搜索title场地。首先我创建一个索引:

CREATE INDEX pictures_title ON pictures 
  USING gin(to_tsvector('english', title));

现在我想寻找'small dog'。这有效:

SELECT pictures.id, 
       ts_rank_cd(
         to_tsvector('english', pictures.title), 'small dog'
       ) AS score
FROM pictures
ORDER BY score DESC

但我真正想要的是这样的:

SELECT pictures.id, 
       ts_rank_cd(
         to_tsvector('english', pictures.title), to_tsquery('small dog')
       ) AS score
FROM pictures 
WHERE to_tsvector('english', pictures.title) @@ to_tsquery('small dog')
ORDER BY score DESC

或者这(这不起作用 - 不能使用score in the WHERE条款):

SELECT pictures.id, 
       ts_rank_cd(
         to_tsvector('english', pictures.title), to_tsquery('small dog')
       ) AS score
FROM pictures WHERE score > 0
ORDER BY score DESC

最好的方法是什么?我的问题有很多:

  1. 如果我使用重复的版本to_tsvector(...)它会调用两次,还是足够聪明以某种方式缓存结果?
  2. 有没有一种方法可以做到不重复to_ts...函数调用?
  3. 有没有办法使用score in the WHERE条款根本吗?
  4. 如果有的话,过滤一下会不会更好score > 0或使用@@ thing?

使用@@操作员将利用全文 GIN 索引,而测试score > 0不会。

我创建了一个如问题中所示的表,但添加了一个名为title_tsv:

CREATE TABLE test_pictures (
  id        BIGSERIAL,
  title     text,
  title_tsv tsvector
);

CREATE INDEX ix_pictures_title_tsv ON test_pictures 
    USING gin(title_tsv);

我用一些测试数据填充了表:

INSERT INTO test_pictures(title, title_tsv)
SELECT T.data, to_tsvector(T.data) 
FROM   some_table T;

然后我运行了之前接受的答案explain analyze:

EXPLAIN ANALYZE 
SELECT  score, id, title
FROM (
    SELECT ts_rank_cd(P.title_tsv, to_tsquery('address & shipping')) AS score
        ,P.id        
        ,P.title
    FROM test_pictures as P
) S
WHERE score > 0
ORDER BY score DESC;

并得到以下内容。请注意执行时间为 5,015 毫秒

QUERY PLAN                                                                                                                                    |
----------------------------------------------------------------------------------------------------------------------------------------------|
Gather Merge  (cost=274895.48..323298.03 rows=414850 width=60) (actual time=5010.844..5011.330 rows=1477 loops=1)                             |
  Workers Planned: 2                                                                                                                          |
  Workers Launched: 2                                                                                                                         |
  ->  Sort  (cost=273895.46..274414.02 rows=207425 width=60) (actual time=4994.539..4994.555 rows=492 loops=3)                                |
        Sort Key: (ts_rank_cd(p.title_tsv, to_tsquery('address & shipping'::text))) DESC                                                      |
        Sort Method: quicksort  Memory: 131kB                                                                                                 |
        ->  Parallel Seq Scan on test_pictures p  (cost=0.00..247776.02 rows=207425 width=60) (actual time=17.672..4993.997 rows=492 loops=3) |
              Filter: (ts_rank_cd(title_tsv, to_tsquery('address & shipping'::text)) > '0'::double precision)                                 |
              Rows Removed by Filter: 497296                                                                                                  |
Planning time: 0.159 ms                                                                                                                       |
Execution time: 5015.664 ms                                                                                                                   |

现在将其与@@操作员:

EXPLAIN ANALYZE
SELECT ts_rank_cd(to_tsvector(P.title), to_tsquery('address & shipping')) AS score
    ,P.id
    ,P.title
FROM    test_pictures as P
WHERE P.title_tsv @@ to_tsquery('address & shipping')
ORDER BY score DESC;

结果出来了执行时间约29毫秒:

QUERY PLAN                                                                                                                                       |
-------------------------------------------------------------------------------------------------------------------------------------------------|
Gather Merge  (cost=13884.42..14288.35 rows=3462 width=60) (actual time=26.472..26.942 rows=1477 loops=1)                                        |
  Workers Planned: 2                                                                                                                             |
  Workers Launched: 2                                                                                                                            |
  ->  Sort  (cost=12884.40..12888.73 rows=1731 width=60) (actual time=17.507..17.524 rows=492 loops=3)                                           |
        Sort Key: (ts_rank_cd(to_tsvector(title), to_tsquery('address & shipping'::text))) DESC                                                  |
        Sort Method: quicksort  Memory: 171kB                                                                                                    |
        ->  Parallel Bitmap Heap Scan on test_pictures p  (cost=72.45..12791.29 rows=1731 width=60) (actual time=1.781..17.268 rows=492 loops=3) |
              Recheck Cond: (title_tsv @@ to_tsquery('address & shipping'::text))                                                                |
              Heap Blocks: exact=625                                                                                                             |
              ->  Bitmap Index Scan on ix_pictures_title_tsv  (cost=0.00..71.41 rows=4155 width=0) (actual time=3.765..3.765 rows=1477 loops=1)  |
                    Index Cond: (title_tsv @@ to_tsquery('address & shipping'::text))                                                            |
Planning time: 0.214 ms                                                                                                                          |
Execution time: 28.995 ms                                                                                                                        |

正如您在执行计划中看到的,索引ix_pictures_title_tsv在第二个查询中使用,但在第一个查询中没有使用,因此使用@@运算速度快了 172 倍!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用PostgreSQL全文搜索排名的最佳方式 的相关文章

  • 如何比较表中最后一个和倒数第二个条目的值?

    我在 Oracle 中有一个名为quotes 的表 其中包含两列 date 和value 我想比较表中最后一个条目和倒数第二个条目的值 在此示例中 我想获取日期13 1 和 11 1在一行中以及每个日期的值之间的差异 10 5 5 报价表
  • Heroku 上的 Python 入门 - 未找到 pg_config 可执行文件

    我一直在关注文档 直到安装requirements txt 文件 尝试安装第 6 行 psycopg2 2 5 3 时总是失败 这是消息 Downloading unpacking psycopg2 2 5 3 from r require
  • 规范“毒”方式真的值得吗? (3NF)

    我正处于数据库设计的早期阶段 所以还没有最终的结果 并且我正在为具有可选标签的线程使用 TOXI 3表设计 但我忍不住觉得加入是并不是真的必要 也许我只需要依赖我的简单标签列posts我可以在其中存储类似 varchar 的表
  • 如何更改 Amazon Redshift 中的默认时区?

    默认情况下将时间戳列设置为 SYSDATE 将其存储为UTC 是否可以更改时区 以便 SYSDATE 将日期和时间存储到不同的时区 到目前为止 我已经检查了SET http docs aws amazon com redshift late
  • 尝试使用 Rails 和 PostgreSQL 生成模型时,命令挂起且没有错误

    使用该命令时 rails generate model Event name string 什么也没发生 我必须按 CTRL c 我使用的版本是 红宝石 2 1 1p76 导轨4 1 0 PostgreSQL 9 3 4 Mac OS X
  • 当我耗尽 bigint 生成的密钥时会发生什么?怎么处理呢?

    我自己无法想象一个好的答案 所以我想在这里问 在我心里 我总是想知道 如果AUTO INCREMENT PRIMARY ID我的专栏MySQL表用完了吗 举例来说 我有一个有两列的表 一个ID auto increment primary
  • JOOQ 查询 JOIN ON WITH 子句

    如何编写 JOOQ 查询来连接 with 子句中的字段 例如 我尝试过 create with a as select val 1 as x val a as y select from tableByName a join ANOTHER
  • Linq 到自定义 SQL

    好的 我有一个带有巨大表的数据库 超过 100 万条记录和 50 多个列 我知道它不是最佳的 但它是我必须处理的 所以我需要运行限制返回数据量的查询 现在我的问题是这样的 我有一些运行并返回数据的自定义查询 用户可以通过选择将生成谓词模板并
  • 将数据从 MS SQL 导入 MySQL

    我想从 MS SQL Server 导入数据 通过某种正则表达式运行它以过滤掉内容 然后将其导入 MySQL 然后 对于每个查询 我希望显示来自第三个数据库的相关图像 明智地导入和链接 最简单的方法是什么 谢谢 澄清 它是一个 PHP 应用
  • 如何将特定行保留为查询(T-SQL)的第一个结果?

    我正在编写一个 SQL 查询来获取 Report Builder 3 0 中报表的参数列表 我需要在结果中添加一个带有值 All 的额外行 如下所示 SELECT All UNION SELECT DISTINCT Manager FROM
  • 确定一个范围是否完全被一组范​​围覆盖

    如何检查范围是否为完全覆盖由一组范围 在以下示例中 WITH ranges id a b AS SELECT 1 0 40 UNION SELECT 2 40 60 UNION SELECT 3 80 100 UNION SELECT 4
  • MySQL - 替换列中的字符

    作为一个自学成才的新手 我给自己制造了一个大问题 在将数据插入数据库之前 我将字符串中的撇号 转换为双引号 而不是 MySQL 实际需要的反斜杠和撇号 在我的表增长到超过 200 000 行之前 我认为最好立即纠正此问题 所以我做了一些研究
  • SQL 查询在多用户环境中返回错误值

    一段时间以来 我们在我们的一个客户站点上发现了奇怪的数据完整性问题 经过大量调查后 我们现在已将其隔离为数据库调用 如果两个用户同时调用同一个存储过程 有时一个用户会得到另一个用户的结果 我们设置了一个测试来验证这一点 并且我们有一个循环
  • 如何使用 WHERE x IN 子句编写PreparedStatement 的SQL?

    我有一个如下所示的查询 SELECT last name first name middle initial FROM names WHERE last name IN smith jones brown 我需要能够对 IN 子句中的列表进
  • 寻找免费的 GUI 工具来使用 PostgreSQL [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 目前 我正在使用独立的 GUI 工具DbSchema http www dbschema com 设计
  • 如何对主索引重新编号

    我有一个简单的 MySQL 表 主索引 id 不是一一编号的 1 31 35 100 等 我希望它们的编号如 1 2 3 4 请告诉我该怎么做 我还想指出的是 我知道该操作可能产生的后果 但我只是想整理一下表格 我同意其他方法也可以 但我只
  • VB SQL 语句未选择正确的行

    我试图使用 SELECT 语句在我的数据库中 选择 一个人 但它没有选择正确的人 我也不确定为什么 我正在使用访问数据库 数据库连接代码 Imports System Data OleDb Module Database Connectio
  • Java/Hibernate - 异常:内部连接池已达到其最大大小,当前没有可用的连接

    我第一次在大学项目中使用 Hibernate 而且我还是个新手 我想我遵循了我的教授和我阅读的一些教程给出的所有指示 但我不断收到标题中的异常 Exception in thread main org hibernate Hibernate
  • MySQL:查询中周数的周日期范围

    我有一个看起来像这样的数据库表 id clock info 1 1262556754 some info 2 1262556230 some other info 3 1262556988 and another 4 1262555678
  • 如何从主机连接到 Docker Postgres 容器

    我按照以下说明搭建了一个 Rails 开发环境https docs docker com compose rails https docs docker com compose rails 它可以工作 但我无法从主机连接到 Postgres

随机推荐

  • Lua 中的 OOP - 创建类?

    我知道这个网站上有一些关于在 Lua 中实现 OOP 的问题 但是 这个问题有点不同 至少与我发现的相比 我正在尝试创建一个名为 human 并使其使用 人类 的 新 构造函数创建的对象继承人类内部的所有内容 除了它的构造函数 但是 我也不
  • 如何使用 TypeScript 定义 DynamoDB get 的返回类型?

    I have let resItem Schema resItem await dynamoClient get TableName Key uuid request body uuid promise 但我得到 Type PromiseR
  • WPF 弹出窗口 IsOpen 问题

    使用发现的概念在 StackOverflow 上 https stackoverflow com a 8946055 24399 请注意 ToggleButton IsHitTestVisible一定会Popup IsOpen with S
  • Objective-C ARC:强与保留,弱与分配

    ARC 引入了两个新的内存管理属性 strong and weak 除了copy 这显然是完全不同的东西 之间有什么区别吗strong vs retain and weak vs assign 根据我的理解 这里唯一的区别是weak将分配n
  • 如何扩展Nutch进行文章爬取

    我正在寻找一个框架来抓取文章 然后我找到了Nutch 2 1 这是我的计划和每个计划的问题 1 将文章列表页面添加到 url seed txt 这里有一个问题 我真正想要索引的是文章页面 而不是文章列表页面 但是 如果我不允许列表页面被索引
  • 如何在 Scala 的 Swing 表中嵌入(工作)按钮?

    我正在尝试使用 Scala Swing 创建一个表 其中一列由以下内容填充Buttons 我的出发点是SCells 电子表格示例 http my safaribooksonline com book programming scala 97
  • Java System.getProperty(“user.timezone”) 不起作用

    当我启动java程序时java Duser timezone UTC System out println System getProperty user timezone System out println new Date print
  • 为什么.Net Framework和.Net Core中的ComputeSignature会产生不同的结果

    我有问题 var contentInfo new ContentInfo message var signedCms new SignedCms contentInfo var cmsSigner new CmsSigner certifi
  • 如何在 C++ 中禁用 CodeSonar 警告

    标题说明了一切 我有一个项目需要对 MISRA 2004 进行清理 公司被告知 CodeSonar 是进行静态分析的好工具 在其他静态分析工具上 您可以添加魔术注释来禁用对下一行 代码块的分析 PC Lint 是 lint esym 42
  • 如何通过shell脚本激活python虚拟环境[重复]

    这个问题在这里已经有答案了 我写了一个shell脚本作为 source ve bin activate 当我使用命令运行脚本时 将其保存为 activate shell sh bash activate shell sh 脚本运行时没有错误
  • 如何获取将用于计算操作的对象的值?

    我试图得到我的每一个对象data矩阵 因为那一刻它完全打印了我的值data我只需要获得一个对象 calculo impuesto cantidad factura pivote costo factura pivote from data
  • 如何在 Access 的查询编辑器中执行多个 SQL 语句?

    我有一个文本文件 其中包含一些我想要运行的 SQL 语句 在 Access 数据库上 我认为这应该可以通过 Access 查询编辑器 因此 我进入该编辑器并粘贴以下语句 insert into aFewYears yr values 200
  • 循环函数在回归函数中添加大量预测变量

    我想改进在回归函数中插入预测变量的方法 fm lt lm formula df dependent variable df 2 df 3 df 4 data df df 数据 frame 在此示例中 我仅放置 4 个预测变量和 1 个 de
  • 选择下拉选项时在表单中添加输入字段

    如何动态添加表单字段 所以我的表格看起来像
  • C# 数据表小数精度

    我有以下代码将新列添加到数据表 DataColumn col new DataColumn column typeof decimal col Caption Column mytable Columns Add col 如何为此列指定小数
  • mysql 更新 - 跳过空白字段?

    我需要知道执行此操作的正确方法 我有一个表格 人们可以在其中填写 3 个不同的输入来更新他们的数据 如果他们愿意 可以将一项留空 只更新其他两项或仅更新一项 任何 所以如果我更新为 mysql query UPDATE table SET
  • 获取 java.lang.ClassNotFoundException: com.google.gson.Gson for maven 项目

    我是 maven 新手 我正在使用 apache maven 3 2 2 来构建我的项目 它是一个简单的项目 它将从客户端接收 json 数据 在服务器端它将将此 json 数据转换为其类似的 java 类 用于转换我们使用google的G
  • 如何设置没有@id元素的@entity?

    我有这个豆子 Entity Table name accesos public class Acceso implements Serializable Column name idUser private String idUser Ma
  • 群体行为问题

    昨天我看到了克雷格雷诺兹的Boids http www red3d com cwr boids 随后我想尝试一下用 Java 实现一个简单的 2D 版本 我已经根据以下内容整理了一个相当基本的设置康拉德 帕克的笔记 http www ver
  • 使用PostgreSQL全文搜索排名的最佳方式

    继从这个答案 https stackoverflow com a 4014625 265521如果我想按排名排序 我想知道使用 PostgreSQL 内置全文搜索的最佳方法是什么 and限制为仅匹配查询 让我们假设一个非常简单的表 CREA