xan*_*ngr 17 postgresql full-text-search pattern-matching
我想通过查询得到结果:
SELECT * FROM (
SELECT id, subject
FROM mailboxes
WHERE tsv @@ plainto_tsquery('avail')
) AS t1 ORDER by id DESC;
Run Code Online (Sandbox Code Playgroud)
这有效并返回tsv
包含包含的行Available
。但是如果我使用avai
(dropped lable
) 它找不到任何东西。
所有查询都必须在字典中吗?我们不能只查询这样的字母吗?我有一个包含电子邮件正文(内容)的数据库,我希望随着它每秒增长而使其快速增长。目前我正在使用
... WHERE content ~* 'letters`
Run Code Online (Sandbox Code Playgroud)
Erw*_*ter 29
所有查询都必须在字典中吗?
不。因为只有词干(根据使用的文本搜索配置)在索引中开始。但更重要的是:
这会起作用:
SELECT id, subject
FROM mailboxes
WHERE tsv @@ to_tsquery('simple', 'avail:*')
ORDER BY id DESC;
Run Code Online (Sandbox Code Playgroud)
注意3点:
在这种情况下使用to_tsquery()
,而不是plainto_tsquery()
,因为(引用手册):
...
plainto_tsquery
不会识别tsquery
其输入中的运算符、权重标签或前缀匹配标签
使用'simple'
文本搜索配置生成 ,tsquery
因为您显然希望按原样使用“avail”一词而不应用词干提取。
附加:*
以使其成为前缀搜索,即查找所有以 'avail' 开头的词素。
重要提示:这是对文档中词素(词干)的前缀搜索。没有通配符 ( content ~* 'avail'
) 的正则表达式匹配并不完全相同!后者不是左锚定的(到词素的开头),也会找到 'FOOavail' 等。
目前还不清楚您是想要查询中概述的行为还是添加的正则表达式的等价物。pg_trgm
像@Evan 已经建议的 Trigram索引 ( )是正确的工具。dba.SE 上有很多相关的问题,试着搜索一下。
概述:
SELECT *
FROM (
VALUES
('Zend has no framework')
, ('Zend Framework')
) sub(t), to_tsvector(t) AS tsv
WHERE tsv @@ to_tsquery('zend <-> fram:*');
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)id | t | tsv ----+----------------+------------------------ 2 | Zend Framework | 'framework':2 'zend':1
相关答案(请参阅“优化搜索的不同方法”一章):
由于您提到了电子邮件,请注意文本搜索解析器会识别电子邮件,并且不会将它们拆分为单独的单词/词素。考虑:
SELECT ts_debug('english', 'xangr@some.domain.com')
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)(email,"Email address",xangr@some.domain.com,{simple},simple,{xangr@some.domain.com})
我会用空格 ( )替换您的电子邮件中的分隔符@
和索引以索引包含的单词。.
' '
此外,由于您正在处理电子邮件中的姓名,而不是英语(或其他语言)单词,我将使用'simple'
文本搜索配置来禁用词干提取和其他语言功能:
使用以下命令构建ts_vector
列:
SELECT to_tsvector('simple', translate('joe.xangr@some.domain.com', '@.', ' ')) AS tsv;
Run Code Online (Sandbox Code Playgroud)