Bla*_*ain 5 postgresql activerecord ruby-on-rails
我正在实现一个使用名称,标签和位置的搜索系统.和has_and_belongs_to_many之间有关系.这是我的搜索方法目前的样子:ServerTag
def self.search(params)
@servers = Server.all
if params[:name]
@servers = @servers.where "name ILIKE ?", "%#{params[:name]}%"
end
if params[:tags]
@tags = Tag.find params[:tags].split(",")
# How do I eliminate servers that do not have these tags?
end
# TODO: Eliminate those that do not have the location specified in params.
end
Run Code Online (Sandbox Code Playgroud)
tags参数只是以逗号分隔的ID列表.我的问题在if params[:tags]条件块的注释中说明.如何消除没有指定标签的服务器?
奖金问题:有什么方法可以加快速度吗?所有字段都是可选字段,我只使用Postgres.
编辑
我找到了一种方法来做到这一点,但我有理由相信它的运行速度会非常慢.有什么方法比我做的更快?也许是一种让数据库完成工作的方法?
tags = Tag.find tokens
servers = servers.reject do |server|
missing_a_tag = false
tags.each do |tag|
if server.tags.find_by_id(tag.id).nil?
missing_a_tag = true
end
end
missing_a_tag
end
Run Code Online (Sandbox Code Playgroud)
使用所有给定标签检索服务器
if params[:tags]
tags_ids = params[:tags].split(',')
@tags = Tag.find(tags_ids)
@servers = @servers.joins(:tags).where(tags: {id: tags_ids}).group('servers.id').having("count(*) = #{tags_ids.count}")
end
Run Code Online (Sandbox Code Playgroud)
该group(...).having(...)部件选择具有所有请求标签的服务器.如果您正在寻找至少包含其中一个标签的服务器,请将其删除.
使用此解决方案,搜索在单个SQL请求中完成,因此它将比您的解决方案更好.