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索引。另外,如果你想使用词组搜索,这种方式不是一个好主意,因为重新检查会很慢。
我正在使用 PostgreSQL 11,在列 search_fields.
上创建了带有 gin 索引的 tsvectortable测试中的数据
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索引。另外,如果你想使用词组搜索,这种方式不是一个好主意,因为重新检查会很慢。