10

解决PostgreSQL + MyBatis中文全文检索:Error querying database Cause: org.postgre...

 2 years ago
source link: https://blog.skyju.cc/post/mybatis-postgres-text-search-parser-name-does-not-exist/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

网事

解决PostgreSQL + MyBatis中文全文检索:Error querying database Cause: org.postgresql.util.PSQLException: ERROR: text search configuration 'parser_name' does not exist

在使用Java + Spring Boot + MyBatis + PostgreSQL之过程中,使用中文建好了全文检索的索引。在Navicat或命令行中使用tsquery/tsvector查询均无问题,但在代码中调用出现无法找到parser的问题:Error querying database Cause: org.postgresql.util.PSQLException: ERROR: text search configuration 'parser_name' does not exist。本文记录解决此问题的方法。

Apr 14, 2023   By  居正

阅读时长: 2 分钟

postgresql被称为「最现代的关系型数据库」,其支持倒排索引,可用于全文检索。在数据量不大的情况下,即使不使用elasticsearch也能达到不错的性能。

postgresql默认的分词器以空格分词,不支持中文。为使其支持中文,可参考以下两篇文章的做法,安装和应用zhparser:

https://www.cnblogs.com/zhenbianshu/p/7795247.html

https://www.cnblogs.com/Amos-Turing/p/14174614.html

其中添加分词配置的代码为:

CREATE TEXT SEARCH CONFIGURATION parser_name (PARSER = zhparser);
ALTER TEXT SEARCH CONFIGURATION parser_name ADD MAPPING FOR n,v,a,i,e,l,j WITH simple;

我在数据库recipe中建立了名为recipe的schema,使用recipe账户登录。在title || ' ' || description字段上建立索引,使用Navicat查询效果如下图:

03e3c9b259442a62.jpg

在Java中的SelectProvider中定义的方法如下:

public String findAllRecipes(RecipeFilter recipeFilter) {
        return new SQL(){{
            SELECT("*");
            FROM("recipes");
            if (!recipeFilter.getFlavor().isEmpty()) {
                WHERE("flavor=#{flavor}");
            }
            if (!recipeFilter.getCraft().isEmpty()) {
                WHERE("craft=#{craft}");
            }
            if (!recipeFilter.getTimeConsuming().isEmpty()) {
                WHERE("time_consuming=#{timeConsuming}");
            }
            if (!recipeFilter.getDifficulty().isEmpty()) {
                WHERE("difficulty=#{difficulty}");
            }
            if(!recipeFilter.getSearch().isEmpty()){
                WHERE("to_tsvector('parser_name', title || ' ' || description) " +
                        " @@ to_tsquery('parser_name',#{search})");
            }
            ORDER_BY("id desc");
            OFFSET("#{offset}");
            LIMIT("#{limit}");
        }}.toString();
    }

遇到报错:

org.springframework.jdbc.BadSqlGrammarException: 
### Error querying database.  Cause: org.postgresql.util.PSQLException: ERROR: text search configuration "parser_name" does not exist

parser_name是已经定义的parser,在Navicat中查询没有问题,但在程序中查询却出现问题了。

这是由于分词器是建立在public的schema上的:

0f62604c388cd2bc.jpg

解决方法:在parser名字前添加public

WHERE("to_tsvector('parser_name', title || ' ' || description) " +
                        " @@ to_tsquery('parser_name',#{search})");
WHERE("to_tsvector('public.parser_name', title || ' ' || description) " +
                        " @@ to_tsquery('public.parser_name',#{search})");

这样就成功在MyBatis中查询了。

详细分析有待后续补充。

Licensed under CC BY-NC-SA 4.0

</article


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK