在ef core中使用postgres数据库的全文检索功能实战之中文支持
前言
有关通用的postgres数据库全文检索在ef core中的使用方法,参见我的上一篇文章。
本文实践了zhparser中文插件进行全文检索。
准备工作
安装插件,最方便的方法是直接使用安装好插件的docker镜像,比如
docker pull chenxinaz/zhparser
该镜像的postgres数据库版本为10,如果你想要更新的版本,可以自行创建dockerfile进行build。
使用如下命令启动你的容器,侦听在5432端口。
docker run --name pgcn -p : -e POSTGRES_PASSWORD= -d chenxinaz/zhparser
修改migration文件
找到上篇文章添加触发器的代码,在其之前加入代码,注册组件。
migrationBuilder.Sql(@"CREATE EXTENSION zhparser;");
migrationBuilder.Sql(@"CREATE TEXT SEARCH CONFIGURATION chinese_zh (PARSER = zhparser);");
migrationBuilder.Sql(@"ALTER TEXT SEARCH CONFIGURATION chinese_zh ADD MAPPING FOR n,v,a,i,e,l WITH simple;"); migrationBuilder.Sql(
@"CREATE TRIGGER article_title_search_vector_update BEFORE INSERT OR UPDATE
ON articles FOR EACH ROW EXECUTE PROCEDURE
tsvector_update_trigger(title_vector, 'public.chinese_zh', title);");
migrationBuilder.Sql(
@"CREATE TRIGGER article_abst_search_vector_update BEFORE INSERT OR UPDATE
ON articles FOR EACH ROW EXECUTE PROCEDURE
tsvector_update_trigger(abst_vector, 'public.chinese_zh', abst);");
注意触发器使用的插件名称前面的public。
修改完毕后,执行`dotnet ef database update`,创建数据库。
修改查询代码
var query = "阿一土鳖";
var config = "chinese_zh"; var data = db.Articles
.Where(p => p.TitleVector.Matches(EF.Functions.ToTsQuery(config, query)) ||
p.AbstVector.Matches(EF.Functions.ToTsQuery(config, query)))
.OrderByDescending(p => p.TitleVector.Rank(EF.Functions.ToTsQuery(config, query)) * 2.0 +
p.AbstVector.Rank(EF.Functions.ToTsQuery(config, query)))
.Select(p => new Article
{
Title = p.Title,
Abst = p.Abst,
TitleHL = EF.Functions.ToTsQuery(config, query).GetResultHeadline(config, p.Title, ""),
AbstHL = EF.Functions.ToTsQuery(config, query).GetResultHeadline(config, p.Abst, ""),
});
注意所有的地方都要加config,声明使用的parser类型;如果漏掉了一些config,可能导致查询结果不准或者无法高亮等问题。
代码不停的重复ToTsQuery,不知道是否有便捷的写法?
查询发现,能够命中数据库表中的“阿一土鳖”记录,但是词向量字段只有“土鳖”,其他都被当作停止词过滤了,为了更精确的查询,识别“阿一土鳖”这个词语,需要引入自定义词典。
自定义词典
这里为了简单,直接在容器内添加和修改文件,大家可以自行采用更高效率的方法更新字典和配置。
#进入容器:
docker exec -it <容器名称> /bin/bash
#进入目录:
cd /usr/share/postgresql//tsearch_data
#添加文件
touch chinese.txt
#向文件添加一行自定义词汇:
echo "阿一土鳖 1 1 n" >> chinese.txt,后面的1 n,分别是TF/IDF/词性。
#修改conf文件,引入自定义词典:
echo "zhparser.extra_dicts = 'chinese.txt'" >> /var/lib/postgresql/data/postgresql.conf
#退出容器。
exit
#重启容器:
docker restart <容器名称>
重新索引数据
自定义词典更新后,如果需要重建索引,只需要执行sql更新相关字段,就会触发更新索引的操作,从而更新vectors字段。
update articles set title = title
再次执行查询,发现已经能精确匹配到新词汇。
在ef core中使用postgres数据库的全文检索功能实战之中文支持的更多相关文章
- 在ef core中使用postgres数据库的全文检索功能实战
起源 之前做的很多项目都使用solr/elasticsearch作为全文检索引擎,它们功能全面而强大,但是对于较小的项目而言,构建和维护成本显然过高,尤其是从关系数据库/文档数据库到全文检索引擎的数据 ...
- EF Core中如何设置数据库表自己与自己的多对多关系
本文的代码基于.NET Core 3.0和EF Core 3.0 有时候在数据库设计中,一个表自己会和自己是多对多关系. 在SQL Server数据库中,现在我们有Person表,代表一个人,建表语句 ...
- EF Core中,通过实体类向SQL Server数据库表中插入数据后,实体对象是如何得到数据库表中的默认值的
我们使用EF Core的实体类向SQL Server数据库表中插入数据后,如果数据库表中有自增列或默认值列,那么EF Core的实体对象也会返回插入到数据库表中的默认值. 下面我们通过例子来展示,EF ...
- EF Core 中多次从数据库查询实体数据,DbContext跟踪实体的情况
使用EF Core时,如果多次从数据库中查询一个表的同一行数据,DbContext中跟踪(track)的实体到底有几个呢?我们下面就分情况讨论下. 数据库 首先我们的数据库中有一个Person表,其建 ...
- EF Core中怎么实现自动更新实体的属性值到数据库
我们在开发系统的时候,经常会遇到这种需求数据库表中的行被更新时需要自动更新某些列. 数据库 比如下面的Person表有一列UpdateTime,这列数据要求在行被更新后自动更新为系统的当前时间. Pe ...
- [小技巧]EF Core中如何获取上下文中操作过的实体
原文地址:https://www.cnblogs.com/lwqlun/p/10576443.html 作者:Lamond Lu 源代码:https://github.com/lamondlu/EFC ...
- EF Core中避免贫血模型的三种行之有效的方法(翻译)
Paul Hiles: 3 ways to avoid an anemic domain model in EF Core 1.引言 在使用ORM中(比如Entity Framework)贫血领域模型 ...
- EF Core中DbContext可以被Dispose多次
我们知道,在EF Core中DbContext用完后要记得调用Dispose方法释放资源.但是其实DbContext可以多次调用Dispose方法,虽然只有第一次Dispose会起作用,但是DbCon ...
- 9.翻译系列:EF 6以及EF Core中的数据注解特性(EF 6 Code-First系列)
原文地址:http://www.entityframeworktutorial.net/code-first/dataannotation-in-code-first.aspx EF 6 Code-F ...
随机推荐
- MVC-路由扩展-限制浏览器
根据路由原理,MVC每次都会走获取路由上下文数据. 自定义Route 调用,以及完善其他代码 运行结果,当在谷浏览器执行时:
- Trie树-提高海量数据的模糊查询性能
今天这篇文章源于上周在工作中解决的一个实际问题,它是个比较普遍的问题,无论做什么开发,估计都有遇到过.具体是这样的,我们有一份高校的名单(2657个),需要从海量的文章标题中找到包含这些高校的标题,其 ...
- Android 开发技术周报 Issue#277
新闻 Android 11界面再调整:加入快速截屏.多任务向国产ROM看齐 最新版Android 11推送 谷歌Pixel 5被曝光:支持反向充电 4月Android系统版本分布:8.0 Oreo最主
- 什么是LVM
LVM是逻辑盘卷管理(Logical Volume Manager)的简称,它是Linux环境下对磁盘分区进行管理的一种机制,LVM是建立在硬盘和分区之上的一个逻辑层,来提高磁盘分区管理的灵活性.前面 ...
- 五分钟学会Python装饰器,看完面试不再慌
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Python专题的第12篇文章,我们来看看Python装饰器. 一段囧事 差不多五年前面试的时候,我就领教过它的重要性.那时候我Pyt ...
- 3、flink架构,资源和资源组
一.flink架构 1.1.集群模型和角色 如上图所示:当 Flink 集群启动后,首先会启动一个 JobManger 和一个或多个的 TaskManager.由 Client 提交任务给 JobMa ...
- git在用https进行push时候免输账密的方法
先新建一个文件 $ touch ~/.git-credentials $ vim ~/.git-credentials 进去添加内容(github为github.com,码云为gitee.com) h ...
- Windows 版本 Enterprise、Ultimate、Home、Professional
关于Windows 的安装光盘版本很多种,很多人不知道选择哪些. Ultimate 旗舰版,VISTA开始有了这个级别,是最全最高级的,一般程序开发的电脑,玩游戏的电脑,建议用它,不过对配置稍有一些要 ...
- Spring5参考指南:容器扩展
文章目录 BeanPostProcessor自定义bean BeanFactoryPostProcessor自定义配置元数据 使用FactoryBean自定义实例化逻辑 Spring提供了一系列的接口 ...
- mac OS 卸载node.js及npm
通过homebrew安装的 输入卸载命令 brew uninstall node 通过官网下载pkg安装包的 输入卸载命令 sudo rm -rf /usr/local/{bin/{node,npm} ...