Postgres LIKE在rails应用程序中

时间:2016-06-14 18:49:11

标签: ruby-on-rails ruby postgresql ruby-on-rails-4 rails-activerecord

我有一个像这样的Postgres LIKE声明:

@favorites.find_each do |profiles|
  @related_profiles = Profile.where('name LIKE ?', '%' + profiles.name + '%')
end

我要做的是遍历favourites变量,找到contain名称中某些字符的所有配置文件。

例如,如果名称包含"jasson jackson""jackson"

,则应找到名称"jasson"

3 个答案:

答案 0 :(得分:5)

您正在寻找的查询将是:

Profile.where("name LIKE ?", "%#{profiles.name}%")

但请注意,您的@related_profiles可能未正确分配,因为结果与说明相同:

Profile.where("name LIKE ?", "%#{@favorites.last.name}%")

然而,我怀疑这是否是你需要的。 另请注意,它将是一个ActiveRecord :: Collection,一个类似于object的数组。

解决这个问题的一种方法是初始化@related_profiles = [],然后在循环的每个点上,你可以这样做:

@related_profiles += 
Profile.where("name LIKE ?", "%#{profiles.name}%")

或其他方式是:

names = @favorites.map(&:name)
query = names.map{|name| "name LIKE '%#{name}%'"}.join(" OR ")

OR

query = @favorites.map{|favorite| "name LIKE '%#{favorite.name}%'" }.join(" OR ")

THEN

profiles = Profile.where(query)

<强>更新 基于@joshrumbut的评论,我决定使用bind参数重新实现。 但是,代码清晰度有点丢失,但这是一种可行的方法:

names = @favorites.map(&:name)
query = names.map{|favorite| "name LIKE ?" }.join(" OR ")
profiles = Profile.where(query, *names.map{|name| ("%#{name}%")})

基于@muistooshort的评论,我从前两个查询中删除了引号,我认为这种方法看起来更清晰,正如他所说的那样。来自docs

Profile.where('name like any(array[?])', names.map { |s| "%#{s}%" })

答案 1 :(得分:1)

为了使用此类搜索获得更好的结果,您可以尝试使用FTS(全文搜索)。

Rails有一个实现此功能的宝石:

https://github.com/Casecommons/pg_search

  

PgSearch构建了利用PostgreSQL全文搜索的命名范围。

在您的项目上安装此gem,只需使用此语句进行搜索:

PgSearch.multisearch("jasson")

其他选项是 Elasticsearch ,与他一起,您可以索引您的注册表以获得更好的文本搜索。

希望有所帮助:)

答案 2 :(得分:1)

我会尝试使用Postgres模式和&#34; OR&#34;运算符 - postgres doc

names = @favorites.map(&:name)
Profile.where('name LIKE %(?)%', names.join('|'))