rails - 使用各种匹配搜索两个组合字段

时间:2012-08-22 22:18:22

标签: sql ruby-on-rails ruby-on-rails-3 postgresql

我的用户模型有:

用户(id,fname,lname)

我需要一个查询来按名称搜索用户。我曾经使用过:

@users = User.find( :all,
                      :select => 'users.*',
                      :conditions => ["fname || ' ' || lname LIKE ?", '%'+"James Bond"+'%']
                    )

如果您搜索James,则返回用户(James Bond),但如果您搜索“Bond”,则不会返回任何内容。如何更新此查询以通过fname,lname或fname和lname?

返回用户

由于

1 个答案:

答案 0 :(得分:1)

我不知道你如何在RoR中指定它,但在PostgreSQL级别,听起来你可能想要使用trigram搜索。如果您使用的是PostgreSQL 9.1或更高版本,则可以将其与“K最近邻”(KNN)搜索结合使用,以直接返回K个最佳匹配。对于名称,这通常比其他“模糊”搜索技术快几个数量级。

要安装trigram支持,如果您的计算机上有contrib模块,请键入:

CREATE EXTENSION pg_trgm;

假设两个名称字段都是NOT NULL(只是为了避免使用COALESCE谓词混淆答案),可以使用以下命令创建索引:

CREATE INDEX users_name ON users USING gist
  ((fname || ' ' || lname) gist_trgm_ops);

这是有趣的部分,您可以在几毫秒内找到数百万条记录的近似匹配:

SELECT *
  FROM users
  ORDER BY (fname || ' ' || lname) <-> 'James Bond'
  LIMIT 10;

<->运算符是“距离”运算符。如果将ORDER BY子句用于使用gist_trgm_ops 定义的索引,则使用LIMIT,将在“最佳匹配”中从索引返回行“序列。