PostgreSQL 全文检索之 - 位置匹配 过滤语法 (如 '速度 <1> 激情')

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

标签

PostgreSQL , 全文检索 , 位置过滤


背景

PostgreSQL 的全文检索功能非常的丰富,除了我们说的开放式的parser,字典。同时还支持ranking算法(内置以及扩展)。

那么实际上在搜索的需求中,还有一类位置过滤的需求,例如“速度与激情”这个词,分词后是有位置信息的,我们期望搜到的是“速度”和“激情”之间间隔一个的情况,提高精准度。

PostgreSQL的搜索距离的语法如下:

select * from tbl where ts @@ '速度 <距离值> 激情'::tsquery;  
  
如  
  
select * from tbl where ts @@ '速度 <1> 激情'::tsquery;  

例子

首先需要一个中文分词器,RDS PG自带,无需下载。

https://github.com/jaiminpan/pg_scws

create extension pg_scws;  

1、创建测试表

postgres=# create table ts_test (id int, info text, ts tsvector);  
CREATE TABLE  

2、写入测试数据

postgres=# insert into ts_test values (1, '激情,创新,坚持,速度-- 北京北方创业出租汽车公司优质服务小花絮', to_tsvector('scwscfg', '激情,创新,坚持,速度-- 北京北方创业出租汽车公司优质服务小花絮'));  
INSERT 0 1  
postgres=# insert into ts_test values (1, '电影速度与激情8的票房破亿', to_tsvector('scwscfg', '电影速度与激情8的票房破亿'));  
INSERT 0 1  

3、查看分词结果,其中分词中已经带上了位置信息。

postgres=# select * from ts_test;  
 id |                              info                               |                                                     ts                                                       
----+-----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------  
  1 | 激情,创新,坚持,速度-- 北京北方创业出租汽车公司优质服务小花絮 | '优质服务':9 '公司':8 '出租汽车':7 '创业':6 '创新':2 '北京':5 '坚持':3 '小花':10 '激情':1 '絮':11 '速度':4  
  1 | 电影速度与激情8的票房破亿                                       | '激情':3 '电影':1 '破':5 '票房':4 '速度':2  
(2 rows)  

3、写入更多干扰数据

postgres=# insert into ts_test select 2, '激情,创新,坚持,速度-- 北京北方创业出租汽车公司优质服务小花絮', to_tsvector('scwscfg', '激情,创新,坚持,速度-- 北京北方创业出租汽车公司优质服务小花絮') from generate_series(1,1000000);  
INSERT 0 1000000  

4、创建一个支持位置搜索的索引插件rum。

https://github.com/postgrespro/rum

postgres=# create extension rum;  
CREATE EXTENSION  

5、创建rum分词索引

postgres=# CREATE INDEX rumidx ON ts_test USING rum (ts rum_tsvector_ops);  
CREATE INDEX  

6、接下来见证奇迹,第一个查询是不带位置搜索的,我们看到匹配了所有记录。

postgres=# explain (analyze,verbose,timing,costs,buffers) select * from ts_test where ts @@ '速度 & 激情'::tsquery;  
                                                             QUERY PLAN                                                               
------------------------------------------------------------------------------------------------------------------------------------  
 Index Scan using rumidx on public.ts_test  (cost=9.60..41.24 rows=25 width=68) (actual time=223.602..456.956 rows=1000002 loops=1)  
   Output: id, info, ts  
   Index Cond: (ts_test.ts @@ '''速度'' & ''激情'''::tsquery)  
   Buffers: shared hit=38132  
 Planning time: 0.226 ms  
 Execution time: 541.545 ms  
(6 rows)  

7、第二个查询是带位置了,只匹配了1条记录,也就是我们要的“速度与激情”。

postgres=# explain (analyze,verbose,timing,costs,buffers) select * from ts_test where ts @@ '速度 <1> 激情'::tsquery;  
                                                          QUERY PLAN                                                            
------------------------------------------------------------------------------------------------------------------------------  
 Index Scan using rumidx on public.ts_test  (cost=9.60..41.24 rows=25 width=68) (actual time=270.675..270.677 rows=1 loops=1)  
   Output: id, info, ts  
   Index Cond: (ts_test.ts @@ '''速度'' <-> ''激情'''::tsquery)  
   Buffers: shared hit=1095  
 Planning time: 0.111 ms  
 Execution time: 273.840 ms  
(6 rows)  

PostgreSQL 分词就是这么好用

带距离  
  
postgres=# select * from ts_test where ts @@ '速度 <1> 激情'::tsquery;  
 id |           info            |                     ts                       
----+---------------------------+--------------------------------------------  
  1 | 电影速度与激情8的票房破亿 | '激情':3 '电影':1 '破':5 '票房':4 '速度':2  
(1 row)  
  
不带距离  
  
postgres=# select * from ts_test where ts @@ '速度 & 激情'::tsquery limit 5;  
 id |                              info                               |                                                     ts                                                       
----+-----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------  
  1 | 激情,创新,坚持,速度-- 北京北方创业出租汽车公司优质服务小花絮 | '优质服务':9 '公司':8 '出租汽车':7 '创业':6 '创新':2 '北京':5 '坚持':3 '小花':10 '激情':1 '絮':11 '速度':4  
  1 | 电影速度与激情8的票房破亿                                       | '激情':3 '电影':1 '破':5 '票房':4 '速度':2  
  2 | 激情,创新,坚持,速度-- 北京北方创业出租汽车公司优质服务小花絮 | '优质服务':9 '公司':8 '出租汽车':7 '创业':6 '创新':2 '北京':5 '坚持':3 '小花':10 '激情':1 '絮':11 '速度':4  
  2 | 激情,创新,坚持,速度-- 北京北方创业出租汽车公司优质服务小花絮 | '优质服务':9 '公司':8 '出租汽车':7 '创业':6 '创新':2 '北京':5 '坚持':3 '小花':10 '激情':1 '絮':11 '速度':4  
  2 | 激情,创新,坚持,速度-- 北京北方创业出租汽车公司优质服务小花絮 | '优质服务':9 '公司':8 '出租汽车':7 '创业':6 '创新':2 '北京':5 '坚持':3 '小花':10 '激情':1 '絮':11 '速度':4  
(5 rows)  

参考

《多流实时聚合 - 记录级实时快照 - JSON聚合与json全文检索的功能应用》

《PostgreSQL - 全文检索内置及自定义ranking算法介绍 与案例》

《用PostgreSQL 做实时高效 搜索引擎 - 全文检索、模糊查询、正则查询、相似查询、ADHOC查询》

《HTAP数据库 PostgreSQL 场景与性能测试之 14 - (OLTP) 字符串搜索 - 全文检索》

《HTAP数据库 PostgreSQL 场景与性能测试之 7 - (OLTP) 全文检索 - 含索引实时写入》

《多国语言字符串的加密、全文检索、模糊查询的支持》

《全文检索 不包含 优化 - 阿里云RDS PostgreSQL最佳实践》

《PostgreSQL 10.0 preview 功能增强 - JSON 内容全文检索》

《PostgreSQL 全文检索加速 快到没有朋友 - RUM索引接口(潘多拉魔盒)》

《PostgreSQL 行级 全文检索》

《PostgreSQL chinese full text search 中文全文检索》

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
Web App开发 关系型数据库 数据库
用PostgreSQL 做实时高效 搜索引擎 - 全文检索、模糊查询、正则查询、相似查询、ADHOC查询
用PostgreSQL 做实时高效 搜索引擎 - 全文检索、模糊查询、正则查询、相似查询、ADHOC查询作者digoal 日期2017-12-05 标签PostgreSQL , 搜索引擎 , GIN , ranking , high light , 全文检索 , 模糊查询 , 正则查询 , 相似查询 , ADHOC查询 背景字符串搜索是非常常见的业务需求,它包括: 1、前缀+模糊查询。
10240 1
|
4月前
|
SQL 关系型数据库 MySQL
MySQL【实践 02】MySQL迁移到PostgreSQL数据库的语法调整说明及脚本分享(通过bat命令修改mapper文件内的SQL语法)
MySQL【实践 02】MySQL迁移到PostgreSQL数据库的语法调整说明及脚本分享(通过bat命令修改mapper文件内的SQL语法)
97 0
|
7月前
|
SQL Oracle 关系型数据库
Polar DB-O (兼容 Oracle 语法版本)和Polar DB PostgreSQL 版本概述(二)
Polar DB-O (兼容 Oracle 语法版本)和Polar DB PostgreSQL 版本概述(二)
689 0
|
9月前
|
存储 SQL 自然语言处理
如何使用AnalyticDB PostgreSQL 版实现“一站式全文检索”业务
本文从阿里云用户使用云原生数据仓库AnalyticDB PostgreSQL版(以下简称ADB PG)的实际体验出发,介绍ADB PG如何实现“一站式全文检索”业务,并详细阐述ADB PG使用的优势技术,最后提供对应业务案例分析。
32152 33
|
11月前
|
SQL 安全 关系型数据库
PostgreSQL 12 文档: SQL 语法
SQL 命令 这部分包含PostgreSQL支持的SQL命令的参考信息。每条命令的标准符合和兼容的信息可以在相关的参考页中找到。
104 0
|
存储 关系型数据库 Linux
centos7 postgresql10 安装 zhparser,配置中文全文检索
centos7 postgresql10 安装 zhparser,配置中文全文检索
227 0
centos7 postgresql10 安装 zhparser,配置中文全文检索
|
存储 SQL 人工智能
4 PostgreSQL 索引,全文检索,模糊匹配,近似度匹配(三)
4 PostgreSQL 索引,全文检索,模糊匹配,近似度匹配(三)
888 1
4 PostgreSQL 索引,全文检索,模糊匹配,近似度匹配(三)
|
SQL 存储 移动开发
PostgreSQL psql的使用,SQL语法,数据类型,递归SQL用法(四)|学习笔记
快速学习3 PostgreSQL psql的使用,SQL语法,数据类型,递归SQL用法(四)
376 0
 PostgreSQL psql的使用,SQL语法,数据类型,递归SQL用法(四)|学习笔记
|
SQL 关系型数据库 数据库
3 PostgreSQL psql的使用,SQL语法,数据类型,递归SQL用法(三)|学习笔记
快速学习3 PostgreSQL psql的使用,SQL语法,数据类型,递归SQL用法(三)
303 0
|
SQL 弹性计算 关系型数据库
PostgreSQL 12 preview - CTE 增强,支持用户语法层控制 materialized 优化
标签 PostgreSQL , CTE , materialized , not materialized , push down 背景 PostgreSQL with 语法,能跑非常复杂的SQL逻辑,包括递归,多语句物化计算等。 在12以前的版本中,WITH中的每一个CTE(common table express),都是直接进行物化的,也就是说外层的条件不会推到CTE(物化节点)里
825 0

相关产品

  • 云原生数据库 PolarDB