Pg trgm
From PostgreSQL 中文维基, PostgreSQL 中文站, PostgreSQL 中国社区, PostgreSQL Chinese community
[编辑] pg_trgm
pg_trgm 模块提供了基于 trigram 匹配的算法计算文本相似性的函数和操作符,以及支持快速查找类似字串的操作符表。
[编辑] Trigram(或者说 Trigraph)概念
trigram 是从一个字串里取出来的一组三个连续的字符。我们可以通过计算两个字串共享的 trigram 的个数来判断它们的相似性。这个简单的概念在测量许多自然语言的相似性的时候具有相当高的效率。
- 注意:在判断包含字串的 trigram 的时候,一个字串被认为是前缀两个空白,后缀一个空白。比如,字串 "cat" 里面的 trigram 集合是 " c"," ca", "cat", 和 "at "。
[编辑] 函数和操作符
| 函数 | 返回 | 描述 |
| similarity(text, text) | real | 返回一个数值表示的两个参数的相似性。结果范围是 0 (表示两个字串完全不同)到 1 (表示两个字串相等)。 |
| show_trgm(text) | text[] | 返回给出字串里的所有 trigram 的数组(实际上这个函数除了调试之外很少有用。) |
| show_limit() | real | 返回 % 操作符使用的当前的相似性阈值。这个阈值设置两个词之间的最小相似性,以决定诸如是否为相互的拼写错误这样的情况。 |
| set_limit(real) | real | 设置 % 操作符使用的当前的相似性阈值。阈值必须在 0 和 1 之间(缺省是 0.3)。返回传递进去的同样的数值。 |
| 操作符 | 返回 | 描述 |
| text % text | boolean | 如果它的参数的相似性比 set_limit 设置的当前的相似性阈值大,则返回真。 |
[编辑] 索引支持
pg_trgm 模块提供了 GiST 和 GIN 索引操作符表,允许你在一个文本字段上创建一个索引用于非常快的相似性搜索。这些索引类型支持 % 相似性操作符(没有其它操作符了,所以你可能还需要正则的 btree 索引)。
例子:
CREATE TABLE test_trgm (t text); CREATE INDEX trgm_idx ON test_trgm USING gist (t gist_trgm_ops);
或者
CREATE INDEX trgm_idx ON test_trgm USING gin (t gin_trgm_ops);
在这一点上,你在 t 字段上就有了一个可用于相似性搜索的索引。常用的查询类似:
SELECT t, similarity(t, 'word') AS sml FROM test_trgm WHERE t % 'word' ORDER BY sml DESC, t;
这个查询会返回在文本字段里与 word 足够接近所有数值,以最接近向最差排序。索引可以让这个操作变得很快,即使在非常大的数据集上也会相当快。
GiST 和 GIN 索引之间的选择一来与 GiST 和 GIN 的性能特征的区别,我们在其它地方讨论这些。就拇指定律而言,GIN 索引搜索的速度比 GiST 索引快,但是创建和更新的速度满,因此 GIN 更适用于静态数据,而 GiST 适用于常更新的数据。
[编辑] 文本搜索集成
在和全文索引结合使用的时候,trigram 匹配是非常有用的工具。特别是它可以帮助识别输入的拼写错误,而错误的拼写会直接和全文搜索极致进行匹配。
第一步是生成一个包含文档中所有唯一词的辅助表:
CREATE TABLE words AS SELECT word FROM
ts_stat('SELECT to_tsvector(''simple'', bodytext) FROM documents');
这里的 document 是一个有文本字段 bodytext 的表,我们希望搜索 bodytext 这个字段。在 to_tsvector 函数中使用 simple 配置,而不用语言相关的配置的原因是我们希望一个原始(未词根化)的词的列表。
然后,在 word 字段上创建 trigram 索引:
CREATE INDEX words_idx ON words USING gin(word gin_trgm_ops);
现在,就可以在用户搜索的项上,用一个类似前面例子的 SELECT 查询来给出拼写建议和拼写纠错了。一个额外的有用的测试是选出的词和拼写错误的词的长度也类似。
- 注意:因为 words 表是独立生成的、静态的表,所以,我们需要周期性的重新生成它,以保持它和文档集合之间的合理的同步。让它保持在精确的当前状态通常是没用的。
[编辑] 引用
GiST 开发站点 http://www.sai.msu.su/~megera/postgres/gist/
Tsearch2 开发站点 http://www.sai.msu.su/~megera/postgres/gist/tsearch/V2/
[编辑] 作者
Oleg Bartunov <oleg@sai.msu.su>, Moscow, Moscow University, Russia
Teodor Sigaev <teodor@sigaev.ru>, Moscow, Delta-Soft Ltd.,Russia
文档:Christopher Kings-Lynne
这个模块是由 Delta-Soft Ltd., Moscow, Russia 赞助开发的。
