前言

有关通用的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数据库的全文检索功能实战之中文支持的更多相关文章

  1. 在ef core中使用postgres数据库的全文检索功能实战

    起源 之前做的很多项目都使用solr/elasticsearch作为全文检索引擎,它们功能全面而强大,但是对于较小的项目而言,构建和维护成本显然过高,尤其是从关系数据库/文档数据库到全文检索引擎的数据 ...

  2. EF Core中如何设置数据库表自己与自己的多对多关系

    本文的代码基于.NET Core 3.0和EF Core 3.0 有时候在数据库设计中,一个表自己会和自己是多对多关系. 在SQL Server数据库中,现在我们有Person表,代表一个人,建表语句 ...

  3. EF Core中,通过实体类向SQL Server数据库表中插入数据后,实体对象是如何得到数据库表中的默认值的

    我们使用EF Core的实体类向SQL Server数据库表中插入数据后,如果数据库表中有自增列或默认值列,那么EF Core的实体对象也会返回插入到数据库表中的默认值. 下面我们通过例子来展示,EF ...

  4. EF Core 中多次从数据库查询实体数据,DbContext跟踪实体的情况

    使用EF Core时,如果多次从数据库中查询一个表的同一行数据,DbContext中跟踪(track)的实体到底有几个呢?我们下面就分情况讨论下. 数据库 首先我们的数据库中有一个Person表,其建 ...

  5. EF Core中怎么实现自动更新实体的属性值到数据库

    我们在开发系统的时候,经常会遇到这种需求数据库表中的行被更新时需要自动更新某些列. 数据库 比如下面的Person表有一列UpdateTime,这列数据要求在行被更新后自动更新为系统的当前时间. Pe ...

  6. [小技巧]EF Core中如何获取上下文中操作过的实体

    原文地址:https://www.cnblogs.com/lwqlun/p/10576443.html 作者:Lamond Lu 源代码:https://github.com/lamondlu/EFC ...

  7. EF Core中避免贫血模型的三种行之有效的方法(翻译)

    Paul Hiles: 3 ways to avoid an anemic domain model in EF Core 1.引言 在使用ORM中(比如Entity Framework)贫血领域模型 ...

  8. EF Core中DbContext可以被Dispose多次

    我们知道,在EF Core中DbContext用完后要记得调用Dispose方法释放资源.但是其实DbContext可以多次调用Dispose方法,虽然只有第一次Dispose会起作用,但是DbCon ...

  9. 9.翻译系列:EF 6以及EF Core中的数据注解特性(EF 6 Code-First系列)

    原文地址:http://www.entityframeworktutorial.net/code-first/dataannotation-in-code-first.aspx EF 6 Code-F ...

随机推荐

  1. vue2.x学习笔记(五)

    接着前面的内容:https://www.cnblogs.com/yanggb/p/12571062.html. 计算属性 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.如果在模板中放入太 ...

  2. Java 基础讲解

    Hello,老同学们,又见面啦,新同学们,你们好哦! 在看完本人的<数据结构与算法>专栏的博文的老同学,恭喜你们在学习本专栏时,你们将会发现好多知识点都讲解过,都易于理解,那么,没看过的同 ...

  3. SpringMVC Spring Mybatis整合篇

    1.创建WEB项目 创建项目:(ssmbuild)步骤略........ 给项目添加lib文件夹,用于存放jar包: 在WEB-INF目录下创建lib文件夹: 创建完成:运行项目时需要把jar导入到l ...

  4. tensorflow1.0 数据队列FIFOQueue的使用

    import tensorflow as tf #模拟一下同步先处理数据,然后才能取数据训练 #tensorflow当中,运行操作有依赖性 #1.首先定义队列 Q = tf.FIFOQueue(3,t ...

  5. 集合-ArrayList 源码解析

    ArrayList是一种以数组实现的List,与数组相比,它具有动态扩展的能力,因此也可称之为动态数组. 类图 ArrayList实现了List, RandomAccess, Cloneable, j ...

  6. centos 7 安装更新php5.6

    epel  remi 什么的把我弄晕了 不深研这东西了,直接按步骤操作更新了. # yum install epel-release # rpm -ivh http://rpms.famillecol ...

  7. Ubuntu 安装 Qt, 安装辅助软件

    sudo apt-get install libgl1-mesa-dev libglu1-mesa-dev sudo apt-get install gcc g++ sudo apt-get inst ...

  8. [Qt] QProcess::startDetached() 避免弹窗,或者窗口一闪而过

    主动宣告setProcessState(QProcess::NotRunning)   或者在堆上new一个QProcess.     出处:  https://stackoverflow.com/q ...

  9. 深入理解TCP建立和关闭连接

    建立连接: 理解:窗口和滑动窗口TCP的流量控制TCP使用窗口机制进行流量控制什么是窗口?连接建立时,各端分配一块缓冲区用来存储接收的数据,并将缓冲区的尺寸发送给另一端 接收方发送的确认信息中包含了自 ...

  10. C++-doctest-测试框架

    C++-doctest-测试框架 C++UnitTestDoctest 测试框架 doctest 是用过的最简单好用的的单元测试框架, 只需要引用 一个头文件即可 无main 函数的测试样例 #def ...