postgresql - Postgresql tsvector不搜索几个字符串
问题描述
我正在使用 PostgreSQL 11,在 search_fields 列上创建了带有 gin 索引的 tsvector。
表格测试中的数据
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”或“咨询”传递时,它会返回正确的输出。
任何想法,为什么它不搜索“正在进行的”单词?
之后,我使用函数 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
这一次,当我运行传递“正在进行的”字符串的查询时,它会按照预期的结果输出。
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
根据上述实验,将 trigger 和 default_text_search_config 设置为 'pg_catalog.simple' 有助于实现结果。
现在,我不知道它不能使用 default_text_search_config 到 'pg_catalog.english' 的原因是什么。
使用tsvector时是否总是需要触发?
任何有助于理解两者之间差异的帮助将不胜感激。
谢谢,尼西特
解决方案
您没有描述最初是如何创建 search_fields 的。它构造不正确。因为我们不知道你做了什么,所以我们不知道你做错了什么。如果您正确重建它,那么它将开始工作。当您将 default_text_search_config 更改为“简单”时,您似乎已经正确地重新填充了 search_fields,这就是它起作用的原因。如果您改回“英语”并正确重新填充 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 index就用不上了。此外,如果您想使用短语搜索,这种方式也不是一个好主意,因为重新检查会很慢。
推荐阅读
- xml - 解析 xml 文件并尝试仅返回值 > 0。基数为 10 的 int() 的无效文字:'201806-111-01471'
- mongodb - 在 Spark 中创建分层 JSON
- java - JPA - 从实例变量中提取值时引发 NullPointerException
- mysql - 在 MySQL 中创建存储函数/过程 - 新用户
- mysql - 在使用连接和多表/字段 ORDER BY 的查询中,如何设置 LIMIT 偏移量以从唯一 id 字段标识的特定行开始?
- python - 如何在 google colab 中提取带有密码的 Rar 文件?
- apache-spark - 有什么方法可以运行 spark 脚本并与 oozie 并行存储输出?
- c# - 存储文件夹获取或创建
- javascript - foo === +bar 是什么意思?
- typescript - TypeScript 中的破折号问号语法是什么?