在ef core中使用postgres數據庫的全文檢索功能實戰之中文支持


前言

有關通用的postgres數據庫全文檢索在ef core中的使用方法,參見我的上一篇文章。

本文實踐了zhparser中文插件進行全文檢索。

准備工作

安裝插件,最方便的方法是直接使用安裝好插件的docker鏡像,比如

docker pull chenxinaz/zhparser

該鏡像的postgres數據庫版本為10,如果你想要更新的版本,可以自行創建dockerfile進行build。

使用如下命令啟動你的容器,偵聽在5432端口。

docker run --name pgcn -p 5432:5432 -e POSTGRES_PASSWORD=123456 -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/10/tsearch_data
#添加文件 
touch chinese.txt
#向文件添加一行自定義詞匯:
echo "阿一土鱉 1 1 n" >> chinese.txt,后面的1 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

再次執行查詢,發現已經能精確匹配到新詞匯。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM