sil*_*rry 2 postgresql full-text-search
我观察到在我看来 Postgres 的 to_tsvector 函数的奇怪行为。
SELECT to_tsvector('english', 'abc-xyz');
Run Code Online (Sandbox Code Playgroud)
返回
'abc':2 'abc-xyz':1 'xyz':3
Run Code Online (Sandbox Code Playgroud)
然而,
SELECT to_tsvector('english', 'abc-001');
Run Code Online (Sandbox Code Playgroud)
返回
'-001':2 'abc':1
Run Code Online (Sandbox Code Playgroud)
为什么不是这样的?
'abc':2 'abc-001':1 '001':3
Run Code Online (Sandbox Code Playgroud)
我应该怎么做才能仅通过数字部分进行搜索,而无需连字符?
似乎文本搜索解析器将连字符后跟数字标识为有符号整数的符号。调试ts_debug():
SELECT * FROM ts_debug('english', 'abc-001');
alias | description | token | dictionaries | dictionary | lexemes
-----------+-----------------+-------+--------------+------------+---------
asciiword | Word, all ASCII | abc | {simple} | simple | {abc}
int | Signed integer | -001 | {simple} | simple | {-001}
Run Code Online (Sandbox Code Playgroud)
其他文本搜索配置(如“简单”而不是“英语”)将无济于事,因为解析器本身在这里“有问题”(有争议)。
解决它的一个简单方法(除了修改解析器,我从未尝试过)是预处理字符串并将连字符替换为 m-dash ( —) 或只是空格以确保它们被标识为"Space symbols"。(实际有符号整数在此过程中会丢失负号。)
SELECT to_tsvector('english', translate('abc-001', '-', '—'))
@@ to_tsquery ('english', '001'); -- true now
Run Code Online (Sandbox Code Playgroud)
db<>在这里摆弄
这可以通过 PG13 的 dict-int 插件absval选项来规避。请参阅官方文档。
但如果您坚持使用早期的 PG 版本,这里是查询中“数字或负数”解决方法的通用版本。
select regexp_replace($$'test' & '1':* & '2'$$::tsquery::text,
'''([.\d]+''(:\*)?)', '(''\1 | ''-\1)', 'g')::tsquery;
Run Code Online (Sandbox Code Playgroud)
这导致:
'test' & ( '1':* | '-1':* ) & ( '2' | '-2' )
Run Code Online (Sandbox Code Playgroud)
它将看起来像正数的词素替换为“数字或负数”类型的子查询。
双重强制转换::tsquery::text只是为了展示如何将 tsquery 强制转换为文本。
请注意,它也处理前缀匹配的数字词位。
| 归档时间: |
|
| 查看次数: |
665 次 |
| 最近记录: |