Mysql 如何在数据库表列中搜索多个字符串?
我正在使用Rails3.2.2和MySQL。我正在按用户名(例如,Mysql 如何在数据库表列中搜索多个字符串?,mysql,sql,ruby-on-rails,ruby,ruby-on-rails-3,Mysql,Sql,Ruby On Rails,Ruby,Ruby On Rails 3,我正在使用Rails3.2.2和MySQL。我正在按用户名(例如,John,Anthony,Mark)以以下方式搜索数据库表列: # 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 sc
John
,Anthony
,Mark
)以以下方式搜索数据库表列:
# 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 Henry
或Henry John
,Anthony Maria
或Maria Anthony
,Mark Alfred
或Alfred 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
但是我得到了以下错误(例如,假设我正在搜索johnhenry
):
如何正确搜索多个名称?我完全认为您应该执行以下操作之一: Mysql全文搜索: 斯芬克斯研究:
- 我推荐sphinxsearch,因为我将它与各种很酷的功能一起使用 内置的李>
- 对狮身人面像的支持也是惊人的李>
def self.search_by_name(search)
if search
where(name.like_any search.split)
else
scoped
end
end
请注意,这不会按匹配级别排序。为此,您需要一个搜索引擎实现,比如gems For sphinx、solr、xapian
还请注意,您最初使用的每一个都是不相关的,因为您的意思是“或”条件。如果您不介意发出与搜索词一样多的db查询,您甚至可以伪造匹配级别的顺序
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”调用,因此不要在大型数据库上尝试此操作。
另外请注意,如果搜索为“AB”等,则不会将“AB”置于“BA”之上。
所以我只是在玩 如果数据库中有“约翰·亨利”,而有人在搜索“约翰”,它是否匹配?如果名字是“Mark Anthony”,有人搜索“Maria Anthony”?@mu太短了-a)如果数据库中有“John Henry”,有人搜索“John”,那么应该匹配吗?是的,应该是这样。b) 如果名字是“马克·安东尼”,有人在搜索“玛丽亚·安东尼”怎么办?在这种情况下,它应该返回匹配“Maria”或“Anthony”的记录(因此,在您的示例中,它应该包括“Mark Anthony”),但应该根据匹配的“级别”对记录进行排序(也就是说,应该由那些匹配“better”和“Maria Anthony”的记录排序)——我不知道直接使用MySQL查询是否可行).看一看。本例中的最后一个功能--与其他功能类似,必须是您的案例。您可以使用类似以下内容:names=params[:search].split@users=User.where{name.like_any(name)}
。
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