我有一个像这样的Postgres LIKE
声明:
@favorites.find_each do |profiles|
@related_profiles = Profile.where('name LIKE ?', '%' + profiles.name + '%')
end
我要做的是遍历favourites
变量,找到contain
名称中某些字符的所有配置文件。
例如,如果名称包含"jasson jackson"
或"jackson"
"jasson"
答案 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('|'))