当前位置: 首页 > news >正文

pgsql_全文检索_使用空间换时间的方法支持中文搜索

pgsql_全文检索_使用空间换时间的方法支持中文搜索

一、环境

  • PostgreSQL 14.2, compiled by Visual C++ build 1914, 64-bit

二、引言

提到全文检索首先想到的就是ES(ElasticSearch)和Lucene,专业且强大。对于一些小众场景对于搜索要求不高,数据量也不大的情况,
上ES等有些繁重,增加工作量还增加了后期运维成本。
PgSql也支持全文检索原理和ES一样,支持分词和反向索引(倒排索引),比如数据量只有几十万时,可以考虑直接使用DB去做查询。

三、帮助文档

  • 全文检索
  • 控制文本搜索
  • 文本搜索类型

四、概念

ES执行全文检索的逻辑是:

  1. 需要对目标内容(文档)做分词,分词是将内容拆分成各个独立的词,每个词会有词频和在内容中的位置等信息;
  2. 使用分词后的内容生成索引文件,这个就是生成倒排索引的阶段,是每个词关联到不同的文档;
  3. 查询时需要对查询关键词进行分词,跟第一步很像只带分词的文档长度小了很多;
  4. 使用查询关键词匹配索引文件,按照词频、相似度、权重等指标对目标文档检索并按得分对文档排序;
  5. 返回最终匹配的文档(记录);

五、PgSQL全文检索基础

PgSQL全局检索前需要了解三个基础概念:文档、查询、操作符。
tsvector类型表示一个为文本搜索优化的形式下的文档,tsquery类型表示一个文本查询。

  • tsvector(文档)类型

    tsvector是一个数据类型,和varchar、integer类似。一个tsvector值是一个排序的可区分词位的列表,记录了分词后的词条、词频、词位、权重信息。
SELECT to_tsvector('hello word!hello word!');
------
'hello':1,3 'word':2,4

其中hello是词条后边的数据是词位,逗号分割的是多个词条在文档中的位置,词位的数量可以反应该词在文档中的词频。

  • tsquery(查询)类型

    对多个查询关键词做与或非逻辑表达,支持的逻辑操作符有:&(与)、|(或)和!(非);
select to_tsquery('hello & word');
------
'hello' & 'word'
  • 匹配操作符@@

    使用"查询"检索"文档",返回一个true/false的结果,标记操作是否匹配;
SELECTto_tsvector('hello word!') @@ query q1,to_tsvector('hello word1!') @@ query q2,to_tsvector('hello word2!') @@ query q3
from to_tsquery('hello & word') query;
------
q1      q2      q3
true	false	false

六、排序&计算匹配得分

  • 排序有两个函数支持:ts_rank()、ts_rank_cd()
    他们都会参考词频、相似度,但ts_rank_cd()会计算覆盖密度排名。
-- 计算文档中同时包含hello和word的文档得分
SELECT ts_rank_cd(to_tsvector('hello word!'), to_tsquery('hello & word'));
SELECT ts_rank(to_tsvector('hello word!'), to_tsquery('word & word'));
-- 
SELECT ts_rank_cd (to_tsvector('hello word!'), query),ts_rank (to_tsvector('hello word!'),query)
from  to_tsquery('hello & word') query;

七、控制权重

tsvector是一个标准的DB类型,是类型就可以做显示转换,在pgsql中类型显示转换的操作符是两个冒号(:😃。
前面用到的to_tsvector()函数,默认会按照英文的语法使用空格对文档进行分词,把文档分词后做词频统计。
pgsql支持的权重值有四个,按照权重从大到小分别是:A、 B、C、D。

  • 将字符串转tsvector类型
    • 原始文档“hello word! hello word!”
    • 分词 select to_tsvector(‘hello word! hello word!’);
    • 自定义权重:select ‘hello:1A,3B word:2C,4D’::tsvector;
      • 其中的权重值A、B、C、D是人为加的,需要满足下列格式要求;
      • 1.多个词条用空格分隔;
      • 2.每个词条后用冒号(:)分隔,冒号左边是词右边是词位、词频、权重信息;
--文档分词
select to_tsvector('hello word! hello word!');
select 'hello:1A,3B word:2C,4D'::tsvector;
--词频影响得分
SELECTts_rank(to_tsvector('hello word!'),query) rank1,ts_rank(to_tsvector('hello word! hello word!'),query) rank2
from to_tsquery('hello & word') query;
----
rank1       rank2
0.09910322	0.34000534

rank2中word出现两次,所以在计算得分时rank2比rank1高。

--权重影响得分
SELECTts_rank('hello:1,3 word:2,4'::tsvector,query) rank1,ts_rank('hello:1A word:2A'::tsvector,query) rank2
from to_tsquery('word') query;
----------
rank1       rank2
0.075990885	0.6079271

word词条在rank1的词频,比rank2词频高,但通过权重控制,最终词频低的得分变高了。

八、高亮显示

高亮显示比较简单使用 tsquery 类型对文档内的关键字加上html的b标签。

--高亮
SELECT 'ts_headline',ts_headline ('hello word!hello word!',query)
from  to_tsquery('word') query;
------
hello <b>word</b>!hello <b>word</b>!

九、提高性能使用 GIN 和 GiST 索引

有两种索引可以被用来加速全文搜索。注意全文搜索并非一定需要索引,但是在一个定期会被搜索的列上,通常需要有一个索引。

  • CREATE INDEX name ON table USING GIN(column);
    • 创建一个基于 GIN(通用倒排索引)的索引。column必须是tsvector类型。
  • CREATE INDEX name ON table USING GIST(column);
    • 创建一个基于 GiST(通用搜索树)的索引。column可以是tsvector或tsquery类型。

GIN 索引是更好的文本搜索索引类型。作为倒排索引,每个词(词位)在 其中都有一个索引项,其中有压缩过的匹配位置的列表。多词搜索可以找到 第一个匹配,然后使用该索引移除缺少额外词的行。GIN 索引只存储 tsvector值的词(词位),并且不存储它们的权重标签。因此, 在使用涉及权重的查询时需要一次在表行上的重新检查。

一个 GiST 索引是有损的,这表示索引可能产生假匹配,并且有必要检查真实的表行来消除这种假匹配(PostgreSQL在需要时会自动做这一步)。GiST 索引之所以是有损的,是因为每一个文档在索引中被表示为一个定长的签名。该签名通过哈希每一个词到一个 n 位串中的一个单一位来产生,通过将所有这些位 OR 在一起产生一个 n 位的文档签名。当两个词哈希到同一个位位置时就会产生假匹配。如果查询中所有词都有匹配(真或假),则必须检索表行查看匹配是否正确。

GiST 索引可以被覆盖,例如使用INCLUDE子句。 包含的列可以具有没有任何 GiST 操作符类的数据类型。 包含的属性将非压缩存储。

有损性导致的性能下降归因于不必要的表记录(即被证实为假匹配的记录)获取。因为表记录的随机访问是较慢的,这限制了 GiST 索引的可用性。假匹配的可能性取决于几个因素,特别是唯一词的数量,因此推荐使用词典来缩减这个数量。

总结

对于简单的全文检索场景,使用pgsql就可以实现,对于检索的基础概念如文档、查询和操作符,词频、权重、排序、高亮都简单说明。

pgsql默认的to_tsvector()函数只支持使用空格进行分词,对于中文这个函数就不好用了。

对于中文分词有两个方案解决:1>使用pgsql的中文分词插件;2>利用空间换时间的方法,在记录写入db前利用java的jieba等分词组件对文档分词,并按
tsvector格式拼接,独立一列记录分词后的类型。如果需要提高检索效率,考虑在tsvector字段上添加GIN类型索引。

两种方法各有利弊,使用是权衡考虑。

相关文章:

pgsql_全文检索_使用空间换时间的方法支持中文搜索

pgsql_全文检索_使用空间换时间的方法支持中文搜索 一、环境 PostgreSQL 14.2, compiled by Visual C build 1914, 64-bit 二、引言 提到全文检索首先想到的就是ES(ElasticSearch)和Lucene&#xff0c;专业且强大。对于一些小众场景对于搜索要求不高&#xff0c;数据量也不…...

OpenGL_Learn10(颜色)

1. 颜色 我们在现实生活中看到某一物体的颜色并不是这个物体真正拥有的颜色&#xff0c;而是它所反射的(Reflected)颜色。换句话说&#xff0c;那些不能被物体所吸收(Absorb)的颜色&#xff08;被拒绝的颜色&#xff09;就是我们能够感知到的物体的颜色。例如&#xff0c;太阳光…...

使用Go语言抓取酒店价格数据的技术实现

目录 一、引言 二、准备工作 三、抓取数据 四、数据处理与存储 五、数据分析与可视化 六、结论与展望 一、引言 随着互联网的快速发展&#xff0c;酒店预订已经成为人们出行的重要环节。在选择酒店时&#xff0c;价格是消费者考虑的重要因素之一。因此&#xff0c;抓取酒…...

设计模式1

![在这里插入图片描述](https://img-blog.csdnimg.cn/c9fbecf1ae89436095885722380ea460.png)一、设计模式分类&#xff1a; 1、创建型模式&#xff1a;创建与使用分离&#xff0c;单例、原型、工厂、抽象、建造者。 2、结构型模式&#xff1a;用于描述如何将对象按某种更大的…...

数字人部署之VITS+Wav2lip数据流转处理问题

一、模型 VITS模型训练教程VITS-从零开始微调&#xff08;finetune&#xff09;训练并部署指南-支持本地云端 Wav2lip是2D数字人&#xff0c;可参考训练嘴型同步模型Wav2Lip PS:以上模型都是开源可用。 二. VITS数据处理问题 VITS模型的输出为一维的numpy类型数据&#xff…...

RK3568笔记五:基于Yolov5的训练及部署

若该文为原创文章&#xff0c;转载请注明原文出处。 一. 部署概述 环境&#xff1a;Ubuntu20.04、python3.8 芯片&#xff1a;RK3568 芯片系统&#xff1a;buildroot 开发板&#xff1a;ATK-DLRK3568 开发主要参考文档&#xff1a;《Rockchip_Quick_Start_RKNN_Toolkit2_C…...

VR虚拟现实:VR技术如何进行原型制作

VR虚拟现实原型制作 利用VR虚拟现实软件进行原型制作可以用于增强原型测试期间的沉浸感&#xff0c;减少产品设计迭代次数&#xff0c;并将与产品原型制作相关的成本降低40-65%。 VR虚拟现实原型制作市场规模 用于原型制作的虚拟现实 (VR) 市场在 2017 年估计为 2.104 亿美元…...

51单片机入门

一、单片机以及开发板介绍 写在前面&#xff1a;本文为作者自学笔记&#xff0c;课程为哔哩哔哩江协科技51单片机入门教程&#xff0c;感兴趣可以看看&#xff0c;适合普中A2开发板或者HC6800-ESV2.0江协科技课程所用开发板。 工具安装请另行搜索&#xff0c;这里不做介绍&…...

notes_质谱蛋白组学数据分析基础知识

目录 1. 蛋白组学方法学1.1 液相-质谱法1) 基本原理2) bottom-up策略的基本流程 1.2 PEA/Olink 2. 质谱数据分析2.1 原始数据格式2.2 分析过程1&#xff09;鉴定搜索引擎&#xff08;质谱组学&#xff09;重难点/潜在的研究方向 2&#xff09;定量3&#xff09;预处理 2.3 下游…...

【Python基础】一个简单的TCP通信程序

&#x1f308;欢迎来到Python专栏 &#x1f64b;&#x1f3fe;‍♀️作者介绍&#xff1a;前PLA队员 目前是一名普通本科大三的软件工程专业学生 &#x1f30f;IP坐标&#xff1a;湖北武汉 &#x1f349; 目前技术栈&#xff1a;C/C、Linux系统编程、计算机网络、数据结构、Mys…...

算法之双指针

双指针算法的作用 双指针算法是一种使用2个变量对线性结构(逻辑线性/物理线性)&#xff0c;进行操作的算法&#xff0c;双指针可以对线性结构进行时间复杂度优化&#xff0c;可以对空间进行记忆或达到某种目的。 双指针算法的分类 1.快慢指针 2.滑动窗口 3.左右指针 4.前后指…...

Redis被攻击纪实

一、前言 声明&#xff1a;本文仅供技术交流使用&#xff0c;严禁采用本文的方法进行任何非法活动。 上周新来的同事分享Redis的原理和机制&#xff0c;想起2017年的时候测试环境Redis被攻击&#xff0c;最后只能重新安装服务器&#xff0c;今天试验一把利用Redis漏洞进行攻击…...

AI工具-PPT-SlidesAI

SlidesAI 使用手册 https://tella.video/get-started-with-slidesai-tutorial-18yq 简介 SlidesAI 是一款快速创建演示文稿的AI工具&#xff0c;适用于无设计经验的用户。 开始使用 1. **安装与设置** - 访问 [SlidesAI官网](https://www.slidesai.io/zh)。 - 完成简单的设置…...

原型链污染攻击

想要很清楚了理解原型链污染我们首先必须要弄清楚原型链这个概念 可以看这篇文章&#xff1a;对象的继承和原型链 目录 prototype和__proto__分别是什么&#xff1f; 原型链继承 原型链污染是什么 哪些情况下原型链会被污染&#xff1f; 例题1&#xff1a;Code-Breaking 2…...

Android Glide transform圆形图CircleCrop动态代码描边绘制外框线并rotateImage旋转,Kotlin

Android Glide transform圆形图CircleCrop动态代码描边绘制外框线并rotateImage旋转&#xff0c;Kotlin <?xml version"1.0" encoding"utf-8"?> <FrameLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app&q…...

【ruoyi】微服务关闭登录验证码

登录本地的nacos服务&#xff0c;修改&#xff1a;配置管理-配置列表-ruoyi-gateway-dev.yml 将验证码的enabled设置成false&#xff0c;即可...

AI:78-基于深度学习的食物识别与营养分析

🚀 本文选自专栏:人工智能领域200例教程专栏 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的代码,详细讲解供大家学习,希望可以帮到大家。欢迎订阅支持,正在不断更新中,…...

日本it培训班,如何选择靠谱的赴日IT培训班?

随着科技的发展&#xff0c;信息技术行业在全球范围内迅速发展&#xff0c;并呈现出蓬勃的发展态势&#xff0c;在日本&#xff0c;IT行业也成为一种极为热门的职业选择。日本专门学校在这个领域内培养了许多IT从业者&#xff0c;成为了众多IT公司的培养基地。如果你对IT产业感…...

51单片机PCF8591数字电压表LCD1602液晶显示设计( proteus仿真+程序+设计报告+讲解视频)

51单片机PCF8591数字电压表LCD1602液晶设计 ( proteus仿真程序设计报告讲解视频&#xff09; 仿真图proteus7.8及以上 程序编译器&#xff1a;keil 4/keil 5 编程语言&#xff1a;C语言 设计编号&#xff1a;S0060 51单片机PCF8591数字电压表LCD1602液晶设计 1.主要功能&a…...

缅因州政府通知130万人MOVEit数据泄露事件

大家好&#xff0c;今天我要向大家通报一个令人震惊的消息&#xff1a;缅因州政府的系统遭到了入侵&#xff0c;黑客利用MOVEit文件传输工具的漏洞&#xff0c;获取了约130万人的个人信息&#xff0c;这几乎相当于该州的整个人口数量。 MOVEit攻击是Clop勒索软件团伙进行的一次…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

Web后端基础(基础知识)

BS架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构模式。客户端只需要浏览器&#xff0c;应用程序的逻辑和数据都存储在服务端。 优点&#xff1a;维护方便缺点&#xff1a;体验一般 CS架构&#xff1a;Client/Server&#xff0c;客户端/服务器架构模式。需要单独…...

AxureRP-Pro-Beta-Setup_114413.exe (6.0.0.2887)

Name&#xff1a;3ddown Serial&#xff1a;FiCGEezgdGoYILo8U/2MFyCWj0jZoJc/sziRRj2/ENvtEq7w1RH97k5MWctqVHA 注册用户名&#xff1a;Axure 序列号&#xff1a;8t3Yk/zu4cX601/seX6wBZgYRVj/lkC2PICCdO4sFKCCLx8mcCnccoylVb40lP...