Postgresql tsvector 不搜索几个字符串

Postgresql tsvector not searching few strings

我正在使用 PostgreSQL 11,在列 search_fields.

上创建了带有 gin 索引的 tsvector

table测试中的数据

id   |           name           |         search_fields          
-------+--------------------------+--------------------------------

19973 | Ongoing 10x consultation | '10x' 'Ongoing' 'consultation'

19974 |  5x marketing | '5x' 'marketing'

19975 | Ongoing 15x consultation | '15x' 'Ongoing' 'consultation'

默认文本搜索配置设置为 'pg_catalog.english'。

下面两个查询输出 0 行。

select id, name, search_fields from test where search_fields @@ to_tsquery('ongoing');

id | name | search_fields 
----+------+---------------
(0 rows)


select id, name, search_fields from test where search_fields @@ to_tsquery('simple','ongoing');

id | name | search_fields 
----+------+---------------
(0 rows)

但是当我将字符串作为“10x”或 'consultation' 传递时,它 returns 正确的输出。

知道吗,为什么它不搜索 'ongoing' 个词?

之后,我使用函数 tsvector_update_trigger() 创建了触发器并更新了 search_fields 并且还在 postgresql.conf 文件中将 default_text_search_config 设置为 'pg_catalog.simple' ,然后我用 search_fields 更新了 search_fields 并输出为

select id, name, search_fields from test where search_fields @@ to_tsquery('ongoing');
 id |              name               |              search_fields              
----+---------------------------------+-----------------------------------------
  19973  | Ongoing 10x consultation | '10x':2 'consultation':3 'ongoing':1

这次当我 运行 查询传递 'ongoing' 字符串时,它按照预期结果输出。

select id, name, search_fields from test where search_fields @@ to_tsquery('ongoing');

id   |           name           |         search_fields          
-------+--------------------------+--------------------------------

19973 | Ongoing 10x consultation | '10x':2 'consultation':3 'ongoing':1

19975 | Ongoing 15x consultation | '15x':2 'consultation':3 'ongoing':1

根据上面的实验,将触发器和 default_text_search_config 设置为 'pg_catalog.simple' 有助于实现结果。

现在,我不知道 default_text_search_config 到 'pg_catalog.english' 不工作的原因是什么。

使用 tsvector 时是否总是需要触发器?

如能帮助理解两者之间的区别,我们将不胜感激。

谢谢, 尼希特

您没有描述您最初是如何创建 search_fields 的。它的构造不正确。因为我们不知道你做了什么,所以我们不知道你做错了什么。如果您正确重建它,那么它将开始工作。当您将 default_text_search_config 更改为 'simple' 时,您似乎已经正确地重新填充了 search_fields,这就是它起作用的原因。如果您改回 'english' 并 正确地重新填充 search_fields 那么它也会起作用。

您并不总是需要触发器。触发器是一种方式。另一种方法是在每次更新文本列时手动更新 tsvector 列。我通常最喜欢的方法是根本不存储 tsvector,只是动态地导出它:

select id, name, search_fields from test where 
    to_tsvector('english',name) @@ to_tsquery('english','ongoing');

如果要这样做,需要指定配置,不能依赖default_text_search_config,否则不会使用表达式的gin索引。另外,如果你想使用词组搜索,这种方式不是一个好主意,因为重新检查会很慢。