postgresql - 如何在 PostgreSQL 11.8 全文搜索中搜索带连字符的整个单词?

标签 postgresql

我使用 PostgreSQL 11.8。我有查询返回我不期望的结果。我想将整个单词与 OR 条件与我的类别和太阳类别中的 key_words 进行比较。为此,我创建了这个查询,当我面对带有连字符的单词时,它在某种程度上运行得很好。在这种情况下,我的行为是错误的,我的单词 longlong-sleevedt-shirt 匹配,这是不正确的

        SELECT             
        DISTINCT ca.id
            ,ca.category_name            
            ,cc.key_words AS main_keywords
            ,ts_rank_cd(to_tsvector('pg_catalog.swedish',cc.key_words),to_tsquery('pg_catalog.swedish', :main_search_parial_category)) AS  main_runk

            ,cr_main.sub_category_id AS sub_ctegory_id
                ,crsub.key_words AS sub_keywords
                ,ts_rank_cd(to_tsvector('pg_catalog.swedish',crsub.key_words),to_tsquery('pg_catalog.swedish', :sub_main_search)) AS  sub_runk

            FROM category as ca

        INNER JOIN category_relations as cr_ca_main ON cr_ca_main.sub_category_id != ca.id
        INNER JOIN category_configurations as cc ON cc.category_id_id = ca.id

            INNER JOIN category_relations as cr_main ON cr_main.main_category_id = ca.id
            INNER JOIN category_configurations as crsub ON crsub.category_id_id = cr_main.sub_category_id

            WHERE to_tsvector('pg_catalog.swedish',cc.key_words) @@ to_tsquery('pg_catalog.swedish', :main_search_parial_category)

            AND to_tsvector('pg_catalog.swedish',crsub.key_words) @@ to_tsquery('pg_catalog.swedish', :sub_main_search)

        ORDER BY
            ca.id
            ,cc.key_words

                ,cr_main.sub_category_id
                    ,crsub.key_words
id |category_name|main_keywords|main_runk|sub_ctegory_id|sub_keywords|sub_runk
1  |Barn         |Barn,barn    |0.2      |2             |t-shirt,kortärmad,tee,shortsleve,piké,pike,långärmadt-shirt,t-shirt,short-sleeved,tee,shortsleve,piké,girl,long-sleevedt-shirt|0.1

sub_runk = 0.1 看起来像 longlong-sleevedt-shirt 关键字匹配,但这是不正确的我想要整个表达式 long-sleevedt-shirt, 'long' 不应该与这个关键词匹配。我分别测试了

    select
                to_tsvector('pg_catalog.swedish','t-shirt,kortärmad,tee,shortsleve,piké,pike,långärmadt-shirt,t-shirt,short-sleeved,tee,shortsleve,piké,girl,long-sleevedt-shirt') 
                @@ to_tsquery('pg_catalog.swedish', 'Millou|Bunny|long|ears|liten|rainbow|apples|fuchsia') as match;

match = t

当我删除long时,我的f为假,这是正确的

并且面对相同的结果,macth 在单词 long 上等于 true,如果整个表达式 long-sleevedt-shirt 对于某些搜索部分相等,则应该是数学计算,这是不正确的.

当我将 to_tsquery 更改为 phraseto_tsquery 时,当我将 long-sleevedt-shirt 设置为 phraseto_tsquery< 时,我遇到了另一个问题 结果应该是 true,但我面临 false,为什么或者这可能是错误的方法?

select
            to_tsvector('pg_catalog.swedish','t-shirt,kortärmad,tee,shortsleve,piké,pike,långärmadt-shirt,t-shirt,short-sleeved,tee,shortsleve,piké,girl,long-sleevedt-shirt') 
            @@ phraseto_tsquery('pg_catalog.swedish', 'Millou|Bunny|long-sleevedt-shirt|ears|liten|rainbow|apples|fuchsia') as match;

如何设置一些严格模式或类似的模式,仅在整个表达式匹配时进行检查?

符号

关于 GIN 索引的一件事,应该将其更改(或创建新索引)为新的文本搜索配置

create index kw_my_swedish_custom_index on category_configurations
using GIN(to_tsvector('my_swedish', key_words))

最佳答案

全文解析器解析连字符的单词,以便整个单词及其连字符的部分成为标记:

SELECT * FROM ts_debug('swedish', 'long-sleevedt-shirt');

      alias      |           description           |        token        |  dictionaries  |  dictionary  |        lexemes        
-----------------+---------------------------------+---------------------+----------------+--------------+-----------------------
 asciihword      | Hyphenated word, all ASCII      | long-sleevedt-shirt | {swedish_stem} | swedish_stem | {long-sleevedt-shirt}
 hword_asciipart | Hyphenated word part, all ASCII | long                | {swedish_stem} | swedish_stem | {long}
 blank           | Space symbols                   | -                   | {}             |              | 
 hword_asciipart | Hyphenated word part, all ASCII | sleevedt            | {swedish_stem} | swedish_stem | {sleeved}
 blank           | Space symbols                   | -                   | {}             |              | 
 hword_asciipart | Hyphenated word part, all ASCII | shirt               | {swedish_stem} | swedish_stem | {shirt}
(6 rows)

我可以想象摆脱 hword_asciipart 标记的一种方法是创建一个不处理它们的文本搜索配置:

CREATE TEXT SEARCH CONFIGURATION my_swedish (
   COPY = swedish
);
ALTER TEXT SEARCH CONFIGURATION my_swedish
   DROP MAPPING FOR hword_asciipart;
ALTER TEXT SEARCH CONFIGURATION my_swedish
   DROP MAPPING FOR hword_part;

然后使用该文本搜索配置:

SELECT to_tsvector('my_swedish','t-shirt,kortärmad,tee,shortsleve,piké,pike,långärmadt-shirt,t-shirt,short-sleeved,tee,shortsleve,piké,girl,long-sleevedt-shirt')
       @@ to_tsquery('my_swedish', 'Millou|Bunny|long|ears|liten|rainbow|apples|fuchsia');

关于postgresql - 如何在 PostgreSQL 11.8 全文搜索中搜索带连字符的整个单词?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62393584/

相关文章:

postgresql - 消除 Ubuntu 10.04 上不工作的 PostgreSQL 安装并重新开始

sql - sql中多对多关系的外键

sql - Postgres 使用窗口函数计算差异

sql - 使用postgresql格式化时间戳和数字的两个问题

mysql - NodeJS/Sequelize/MySQL - 为什么需要 postgres 依赖项?

postgresql - 使用没有密码的 psql 命令运行批处理文件

postgresql - 选择直到 postgresql 中的行匹配?

java - 将密码传递给 Runtime.getRuntime().exec

sql - jOOQ - CTE 和 INSERT

postgresql - 无法加载驱动程序 org.postgresql 的模块