我正在一个Postgres表中搜索几百万个名字和地址。我想用pg_trgm进行快速模糊搜索。
我的应用程序与( trgm + gin索引)中的应用程序非常相似,答案也相当不错。
我的问题是相关性排名不是很好。有两个问题:
我在想,如果我能得到一个简单地返回记录中匹配的三叉数的分数,而不是按目标字符串长度缩放的曲线图数,我会得到一个更好的结果。这是大多数搜索引擎(比如弹性搜索引擎)的工作方式--它们按点击次数的加权排列,不会对长文档进行惩罚。
是否有可能在pg_trgm中做到这一点,并获得良好的(亚秒级)性能?我可以对结果进行任意排序,但是如果ORDER子句与索引不匹配,那么性能就会很差。
发布于 2022-07-13 12:01:19
我知道这是一个老问题,但这可能对其他人有用。
如果要搜索的文本位于ascii表中(字符在a-zA-Z0-9和其他符号范围内),那么您可能希望使用Full Text Search功能(阅读正式文档全文搜索)。
因为它不仅使您能够按关联进行排序,而且还能够定制诸如text steming (使用snowball算法)之类的东西,后者映射诸如连接、连接和连接之类的单词(请阅读更多关于雪球柄的信息)。这使您的应用程序在搜索方面表现更好。
但是,如果您的要求是搜索超出ascii表范围的文本,比如unicode,如果您尝试支持日语、泰语、韩语等亚洲语言,那么使用pg_trgm是非常好的。
要进行不偏袒问题中提到的较短文本的搜索,可以使用word_similarity()而不是similarity()。
根据正式文件:
word_similarity( text,text )返回一个数字,该数字指示第一个字符串中的trigrams集与第二个字符串中排序的trigrams集的任何连续范围之间最大的相似性。有关详细信息,请参见下面的解释。
例如:
postgres=# SELECT word_similarity('white cat', 'white dog and black cat') as "similarity 1", word_similarity('white cat', 'I have a white dog and a black cat') as "similarity 2", word_similarity('white cat', 'I have a lovely white dog and a cute big black cat in a house') as "similarity 3";
similarity 1 | similarity 2 | similarity 3
--------------+--------------+--------------
0.6 | 0.6 | 0.6
(1 row)如上文所示,它们都有相同的分数。
当您想在查询中使用它时:
SELECT col, word_similarity('some query', col) from my_table where col <% 'some query';根据该文件:
如果第一个参数中的trigram集与第二个参数中有序trigram集的连续范围之间的相似度大于由参数设置的当前单词相似性阈值,则文本<% text→布尔值返回真。
要想在更大的数据集上计算命中分数、关联权重/升压和更快的响应时间等更复杂的事情,您应该使用弹性,但请记住,弹性实例至少需要2GB的ram和更多的内存,因此为此您需要专用的EC2实例。但是对于中小型应用程序来说,pg_trgm在节省服务器成本的同时工作得很好。
希望你觉得这有帮助。
https://stackoverflow.com/questions/66233734
复制相似问题