如何在数据库表列中搜索多个字符串?

时间:2012-05-21 05:55:43

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

我正在使用Rails 3.2.2和MySQL。我按用户名(例如,JohnAnthonyMark)搜索数据库表列:

# User controller
User.search_by_name(params[:search]).order(:name)

# User model
def self.search_by_name(search)
  if search
    where('users.name LIKE ?', "%#{search}%")
  else
    scoped
  end
end

但是,由于名称可以由两个或更多字符串组成(例如,John HenryHenry JohnAnthony MariaMaria AnthonyMark AlfredAlfred Mark),我想在params[:search]提供多个名称时搜索用户。我试着用

def self.search_by_name(search)
  if search
    search.split(' ').each do |string|
      where('users.name LIKE ?', "%#{string}%")
    end
  else
    scoped
  end
end

但是我收到以下错误(例如,鉴于我正在搜索John Henry):

NoMethodError (undefined method `order' for ["John", "Henry"]:Array).

如何正确搜索多个名称?

2 个答案:

答案 0 :(得分:1)

我完全认为你应该做以下其中一项,

Mysql全文搜索:

http://devzone.zend.com/26/using-mysql-full-text-searching/

SphinxSearch:

http://www.ibm.com/developerworks/library/os-php-sphinxsearch/

  • 我推荐使用sphinxsearch,因为我使用了各种很酷的功能 内置它。
  • 对狮身人面像的支持也很棒!

答案 1 :(得分:1)

使用squeel gem。

def self.search_by_name(search)
  if search
    where(name.like_any search.split)
  else
    scoped
  end
end

请注意,这不会通过匹配级别来排序。为此你需要一个搜索引擎实现,比如sphinx,solr,xapian的宝石

另请注意,由于您的意图是“或”条件,因此您对每种方法的原始用法都是无用的。如果你不介意发出与搜索词一样多的数据库查询,你甚至可以伪造匹配级别的顺序。

def self.search_by_name(search)
  if search
    results = search.split.map do |string|
      where('users.name LIKE ?', "%#{string}%").all
    end.flatten
    ids = results.map(&:id)
    # desc order by count of matches
    ordered_results = results.uniq.order { |result| -ids.count(result.id) }
  else
    scoped.all
  end
end

这不是一个可以进一步限定的Arel关系,而是一个普通的数组。 注意'all'调用,所以甚至不要在大数据库上尝试这个。 另请注意,如果搜索为'a b',则不会在'b a'上方命令'a b'。 所以我有点玩得开心。