我有一个简单的表单,我在其中设置了一个我想浏览的查询,例如panasonic viera。这是关于我如何在数据库中搜索该术语的:
Product.where("name ilike ?", "%#{params[:q]}%").order('price')
查询看起来像%panasonic viera%,但我需要以这种方式搜索查询:%panasonic%viera% - 我需要查找所有产品,标题中的单词panasonic或viera ... 但是如何制作这个查询?
我有一个简单的表单,我在其中设置了一个我想浏览的查询,例如panasonic viera。这是关于我如何在数据库中搜索该术语的:
Product.where("name ilike ?", "%#{params[:q]}%").order('price')
查询看起来像%panasonic viera%,但我需要以这种方式搜索查询:%panasonic%viera% - 我需要查找所有产品,标题中的单词panasonic或viera ... 但是如何制作这个查询?
一种解决方案是将您的查询分解为单独的术语,并构建一组通过OR
.
terms = params[:q].split
query = terms.map { |term| "name like '%#{term}%'" }.join(" OR ")
Product.where(query).order('price')
如果您使用的是 PostgreSQL,则可以使用pg_search
gem。它支持全文搜索,带有选项any_word
:
Setting this attribute to true will perform a search which will return all models containing any word in the search terms.
示例来自pg_search
:
class Number < ActiveRecord::Base
include PgSearch
pg_search_scope :search_any_word,
:against => :text,
:using => {
:tsearch => {:any_word => true}
}
pg_search_scope :search_all_words,
:against => :text
end
one = Number.create! :text => 'one'
two = Number.create! :text => 'two'
three = Number.create! :text => 'three'
Number.search_any_word('one two three') # => [one, two, three]
Number.search_all_words('one two three') # => []
通过ARel怎么样
def self.search(query)
words = query.split(/\s+/)
table = self.arel_table
predicates = []
words.each do |word|
predicates << table[:name].matches("%#{word}%")
end
if predicates.size > 1
first = predicates.shift
conditions = Arel::Nodes::Grouping.new(predicates.inject(first) {|memo, expr| Arel::Nodes::Or.new(memo, expr)})
else
conditions = predicates.first
end
where(conditions).to_a
end
这不工作?
WHERE name LIKE "panasonic" OR name LIKE "viera"