我有一个小问题,搜索功能对我的RoR为基础的网站。我有许多产品与一些代码。此代码可以是任何字符串,如“AB-123-lHdfj”。现在我使用ILIKE
操作符来查找产品:
Product.where("code ILIKE ?", "%" + params[:search] + "%")
字符串
它工作正常,但它找不到代码为“AB 123-lHdfj”或“AB 123 lHdfj”的产品。
我该怎么办?可能是Postgres有一些字符串规范化函数,或者其他一些方法可以帮助我?
我有一个小问题,搜索功能对我的RoR为基础的网站。我有许多产品与一些代码。此代码可以是任何字符串,如“AB-123-lHdfj”。现在我使用ILIKE
操作符来查找产品:
Product.where("code ILIKE ?", "%" + params[:search] + "%")
字符串
它工作正常,但它找不到代码为“AB 123-lHdfj”或“AB 123 lHdfj”的产品。
我该怎么办?可能是Postgres有一些字符串规范化函数,或者其他一些方法可以帮助我?
2条答案
按热度按时间tjjdgumg1#
Postgres提供了一个模块,其中包含几个字符串比较函数,例如soundex和metaphone。但是你需要使用levenshtein编辑距离功能。
字符串
2
是两个单词之间的编辑距离。当您对许多单词应用此方法并按编辑距离结果进行排序时,您将获得要查找的模糊匹配类型。试试这个查询示例:(当然,使用您自己的对象名称和数据)
型
这个查询说:
给予我some_table中所有数据的前10个结果,其中代码值和输入'AB 123-lHdfj'之间的编辑距离小于3。您将返回代码值与'AB 123-lHdfj'相差3个字符以内的所有行。
注意:如果你得到一个错误,比如:
型
使用以下命令安装
fuzzystrmatch
扩展:型
qcbq4gxm2#
保罗告诉你
levenshtein()
的事了。这是一个非常有用的工具,但它在大表上也非常慢。它必须从每一行的搜索项中计算Levenshtein distance。这是昂贵的,不能使用索引。“加速”变体levenshtein_less_equal()
对于长字符串更快,但在没有索引支持的情况下仍然很慢。如果您的需求像示例所示的那样简单,您仍然可以使用
LIKE
。只需将搜索词中的任何-
替换为WHERE
子句中的%
。因此,而不是:字符串
用途:
型
或者,动态地:
型
LIKE
模式中的%
代表0-n个字符。或者只对一个字符使用_
。或者使用正则表达式进行更智能的匹配:型
.?
... 0或1个字符或者:
型
\-?
... 0或1个破折号您可能希望转义
LIKE
或regexp模式中的特殊字符。请参阅:如果您的实际问题更复杂,并且您需要更快的解决方案,那么根据您的要求,有各种选择:
可以与
LIKE
、ILIKE
、~
或~*
组合使用,自PostgreSQL 9.1起。在这方面也很有趣:该模块的
similarity()
函数或%
运算符。AB1-23-lHdfj
-->ab123lhdfj
,将其保存在一个附加列中,并使用以相同方式转换的术语进行搜索。或者使用index on the expression代替冗余列。(涉及的函数必须是
IMMUTABLE
。)可以将其与上面的pg_tgrm
组合。模式匹配技术概述: