前言

我们在工作中遇到一个字段存储jsonb 类型,并需要对这个字段进行全文索引。由于对postgres 一些字段类型不清楚,走了一些弯路这里讲解。

实践

一、postgres 和 zhparser 的安装

前面两步postgres 的安装网上挺多资料,可以省略。
zhparser 的安装网上资料比较杂乱,后续做一下补充。

二、全文索引的实践

2、1 jsonb 类型

(1)表结构的初始化,插入初始化数据

create table test2(id int,doc jsonb
);--针对jsonb 插入部分值
insert into test2 values(1,'{"nickname": "gs", "tags": ["python", "golang", "db"]}')
insert into test2 values(2,'{"num":2,"nickname": "gs", "tags": ["python", "golang", "db"]}')

(2)查询部分doc 中的查询修改

查询jsonb中部分值

--扩展字段提取相应属性的值(test2 表中doc 字段 中的 nickname 属性)select  id,doc :: json->>'nickname' from test2

修改

--扩展字段提取相应属性的值 修改 doc 字段中 nickname 为 nickValue1"'update test2 set doc = jsonb_set(doc,'{nickname}','"nickValue1"'::jsonb, false) where id = '2';--添加整个字段的值update test2 set doc = jsonb_set(doc, '{platform}','"baidu"') where id=1--修改整个字段的值update test2 set doc ='{"num":2,"nickname":"nick"}' where id=1

针对jsonb 中的部分字段进行筛选

--筛选出doc 中num=2 的值
select * from test2 where  doc :: json->>'num'='2'

2、2 针对jsonb 实现全文索引(依赖于 zhparser插件,需要postgres 10 以上,该测试基于PostgreSQL 10.16 on x86_64-pc-linux-gnu)

--创建extension
create extension zhparser;
CREATE TEXT SEARCH CONFIGURATION zh (PARSER = zhparser);
ALTER TEXT SEARCH CONFIGURATION zh ADD MAPPING FOR n,v,a,i,e,l,j WITH simple;
select to_tsvector('zh','十九大精神');

1、创建name_age 设置初始化数据

--创建name_age表
create table name_age(name jsonb,tsvector tsvector
)insert into name_age values ('{"nickname": "hello", "tags": ["java", "golang", "db"]}','Sleep deprivation curing depression')insert into name_age values ('{"nickname": "中国台湾是中国的一部分", "tags": ["java", "golang", "db"]}','Sleep deprivation curing depression')

2、插入创建jsonb的索引

create index idx_name_index on name_age using gin(to_tsvector('zh', name));

3、针对jsonb 进行字段进行全文筛选

to_tsvector(‘zh’,name) 为全文索引的分词,下面一句是有golang进行查询

 SELECT name,to_tsvector('zh',name)FROM name_age where to_tsvector('zh',name) @@ to_tsquery('zh','golang')

2、3 关于jsonb 全文索引的优化

(1)我们上文通过这种方式来处理来处理查询,每次搜索都需要对name 字段进行分词、然后再进行索引,那么有办法省略这一步吗?

SELECT name,to_tsvector('zh',name)FROM name_age where to_tsvector('zh',name) @@ to_tsquery('zh','golang')

我们创建一个新的字段

ALTER TABLE name_age ADD COLUMN tsv_column tsvector;           // 添加一个分词字段
UPDATE name_age SET tsv_column = to_tsvector('zh', coalesce(name,'{}'));   // 将字段的分词向量更新到新字段中(这里是jsonb 类型故使用‘{}’,文本可以直接使用‘’)
CREATE INDEX idx_gin_zhcn ON name_age USING GIN(tsv_column);   // 在新字段上创建索引

我们到这一步,基本达到我们要求了,但每次更新、新增 name_age 都需要单独更新变量tsv_column 这个字段,我们如果需要减少这一步。

CREATE TRIGGER trigger_name BEFORE INSERT OR UPDATE  ON name_age FOR EACH ROW EXECUTE PROCEDURE
tsvector_update_trigger(tsv_column, 'public.zh', name); // 创建一个更新分词触发器insert into name_age (name) values('{"tags": ["java", "golang", "db"], "nickname": "aa"}');

然后报错

ERROR: column “name” is not of a character type

tsvector_update_trigger 这个是postgres 自定义的函数并不支持 jsonb 类型的操作,这个时候我们是不是可以自己写一个一个函数代替postgres 自定义函数来进行操作呢?

DROP TRIGGER trigger_name ON name_age ;  // 删除name_age 之前创建trigger_name  触发器// 创建一个 jsonb_insert_update_trigger 的函数(由于自身对function 了解比较少,写得很定制化,如果有大佬指导可以写一个 像tsvector_update_trigger 这样通用的函数)
create or replace function jsonb_insert_update_trigger()
returns trigger
language plpgsql as
$BODY$BEGINNEW.tsv_column := to_tsvector ('public.zh',NEW.name);return NEW;END;
$BODY$;CREATE TRIGGER trigger_name BEFORE INSERT OR UPDATE  ON name_age FOR EACH ROW EXECUTE PROCEDURE
jsonb_insert_update_trigger(); // 直接采用自己写的函数来创建insert into name_age (name) values('{"tags": ["java", "golang", "db"], "nickname": "aa"}');   //插入数据

插入数据之后,tsv_column 自动创建了tsvector 类型的值

对部分字段进行更新查看效果

update  name_age set name='{"tags": ["java", "golang", "db"], "nickname": "中国台湾是中国的一部分"}' where name :: json->>'nickname'='aa'

发现tsv_column 字段也自动更新了

postgres 通过zhparser实现全文搜索功能相关推荐

  1. Cloud Studio全文搜索功能介绍

    使用全文搜索功能可以在整个项目文件中进行关键字搜索.点击左侧的搜索按钮,或者使用快捷键 cmd+shift+f(Windows 下是 cmd+shift+f),就可以打开全文搜索面板. 输入关键词回车 ...

  2. mysql scws_php利用scws实现mysql全文搜索功能的方法,_PHP教程

    php利用scws实现mysql全文搜索功能的方法, 本文实例讲述了php利用scws实现mysql全文搜索功能的方法.分享给大家供大家参考.具体方法如下: scws这样的中文分词插件比较不错,简单的 ...

  3. MongoDB 核心将支持全文搜索功能 (2.3.2)

    来自 MongoDB 官方 JIRA 的一个新特性报告称 MongoDB 将在 2.3.2 版本中增加全文搜索功能.该功能还是体验到阶段,使用方法包括: db.adminCommand( { setP ...

  4. 使用Microsoft SQL Server 2000全文搜索功能构建Web搜索应用程序 --作者:Andrew B. Cencini...

    [摘要]了解如何充分利用SQL Server 2000的全文搜索功能.本文包含有关实现最大吞吐量和最佳性能的几点提示和技巧. 概述 使用Microsoft© SQL Server 2000的全文搜索功 ...

  5. mysql scws_php利用scws实现mysql全文搜索功能的方法

    本文实例讲述了php利用scws实现mysql全文搜索功能的方法.分享给大家供大家参考.具体方法如下: scws这样的中文分词插件比较不错,简单的学习了一下,它包涵一些专有名称.人名.地名.数字年代等 ...

  6. mysql的全文搜索功能

    12.7. 全文搜索功能 12.7.1. 布尔全文搜索 12.7.2. 全文搜索带查询扩展 12.7.3. 全文停止字 12.7.4. 全文限定条件 12.7.5. 微调MySQL全文搜索 MATCH ...

  7. Javascript实现博客全文搜索功能

    摘要 搜索是一个在购物网站.论文检索网站.社交网站等相关网站中被广泛使用的功能.为了不借助后台代码实现本人博客的搜索功能,本文使用Javascript代码对其进行简单实现.该搜索功能的亮点包括:使用纯 ...

  8. 集成Elastic Search实现文档的全文搜索功能实战

    技术选型 该领域已被Lucene独占,几乎无竞争对手. 但是直接使用Lucene非常复杂,因此出现了两个组件,一是solr,二是elastic search,elastic search流行度更高,但 ...

  9. 使用ElasticSearch6.0快速实现全文搜索功能

    本文不涉及ElasticSearch具体原理,只记录如何快速的导入mysql中的数据进行全文检索. 工作中需要实现一个搜索功能,并且导入现有数据库数据,组长推荐用ElasticSearch实现,网上翻 ...

最新文章

  1. 完美的代价 c语言,蓝桥杯基础练习 完美的代价
  2. linux设备模型之Class
  3. 设计模式6---代理模式(Proxy Pattern)
  4. WebSocket教程
  5. 高通平台音频调试常见问题点归纳
  6. wps中的相交_如何在wps中添加交叉引用 - 卡饭网
  7. JanusGraph详解
  8. 企业网站建设方案策划书
  9. 阿里五月将推智能路由器天猫魔筒:野心昭然
  10. OSChina 周五乱弹——岂能说走就能走
  11. 捷太格特PC10G与三菱MR-J4的SSCNETⅢ通讯
  12. Cisco(GNS3) - 路由器接口类型
  13. Ant Design + react-drag-listview实现Table拖拽变换列位置
  14. 2口kvm切换器使用方法简述
  15. Zabbix优化深信服AC的设备运行时间监控项
  16. MacBook Air M1 Centos7 安装linux系统安装
  17. SAR成像处理算法_RD算法_基本原理
  18. codeblocks全屏模式怎么退出_极速PDF安卓版如何翻页、阅读模式修改等操作详解...
  19. 什么是DTO ,DTO 有什么作用
  20. Android手机获取运营商

热门文章

  1. Dedecms TAG中文标签改成英文+数字地址的方法
  2. 微信加好友方法有哪些?
  3. 稀释消费次元壁,华为的移动生活新范式
  4. 无情刀永不知错,无缘分只叹奈何
  5. 三星手机和计算机如何连接打印机,三星打印机连接到电脑没反应怎么办
  6. C语言万年历输出月份,C语言输出万年历
  7. vue html模板递归,vue使用递归组件实现多级列表
  8. Android之获取手机内部及sdcard存储空间
  9. 阿里、百度、美团都在用的‘’高并发秒杀系统‘’;抢红包、秒杀活动、微博热搜、12306抢票等高并发场景
  10. 【转载】软件爱好者必备的优秀软件网站分享收藏