我有一个字段,我使用Jquery TokenInput来自动完成一个产品。查找我正在做的产品:
def token
@products = Product.order(:name)
respond_to do |format|
format.html
format.json { render json: @products.where("name ILIKE ?", "%#{params[:q]}%").limit(10).order('name DESC') }
end
end
如果我有一个名为Rice
的产品,并在字段上进行搜索,输入"r"、"ri"one_answers"ric",我希望最接近的结果是与查询匹配的结果。相反,如果我在数据库中有超过10种不同类型的rice,那么结果将是"无序的",Rice
在10个建立的rice中被放置在第6或第9位左右。对我来说,米饭应该排在第一位,而不是饭团或蛋糕,但我得到的却是这样的东西:
Brown Rice # First result in Tokeninput
Rice Cake
Yellow Rice
Long Grain Rice
Rice Ball
Chinese Rice
Super Rice
Rice
New Rice
The Super Rice Game
即使我输入"Rice",我也会得到类似于上面的结果。如果输入r, ri, ric or rice
,我希望它是第一选择,但我的结果不相信秩序,他们只想要混乱。如何做到这一点呢?
您可以在Product
模型中添加以下方法:
def self.good_search(criteria)
regexp = /#{criteria}/i; # case-insensitive regexp based on your string
result = order(:name).where("name ILIKE ?", "%#{criteria}%").limit(10)
result.sort{|x, y| (x =~ regexp) <=> (y =~ regexp) }
end
这里我使用匹配运算符(=~),它返回regexp匹配的位置。越早遇到"rice"就越靠近结果数组字符串的顶部。对于大数组,这个方法可能不太好,但是对于10个元素,它是可以的。
这是你的控制器:
def token
respond_to do |format|
format.html
format.json { render json: Product.good_search(params[:q]) }
end
end
祝你好运!
全文搜索
我们已经做了这样的事情-你正在寻找全文搜索
我们已经做了一些类似于你在http://firststopcosmeticshop.co.uk上寻找的东西——我们做的方式是这样的:
#config/routes.rb
match 'search(/:search)', :to => 'products#search', :as => :search, via: [:get, :post]
#app/controllers/products_controller.rb
def search
@products = Product.search(params[:search])
respond_to do |format|
format.js { render :partial => "elements/livesearch", :locals => {:search => @products, :query => params[:search]} }
format.html { render :index }
end
end
#app/models/product.rb
def self.search(search)
basic_search(name: search, description: search).take(5) #-> uses textacular gem
end
这使用了PGSQL的文本gem,但希望能给你一些关于如何加载执行搜索的想法
对于您,我建议像这样执行搜索:
def token
@products = Product.where(name: "%#{params[:q]}%").order(name: :desc)
respond_to do |format|
format.html
format.json { render json: @products.to_json }
end
end
虽然这不能直接回答你的问题,但我希望它能给你一些关于效率等方面的信息
我用这个查询解决了我的搜索,我认为你也可以使用它,这会使你的搜索结果更好。给定一个query
字符串作为输入,我使用以下sql:
select items.*
from items
where lower(items.name) like 'query%' or items.name like '% query%'
order by case when lower(items.name) like 'query%' then 1 else 2 end,
items.name ASC
这将返回至少有一个工作与首先开始匹配的工作的结果匹配的所有项目。
在Rails中应该是这样的:
Item.where("lower(items.name) like '#{downcase_query}%' or
lower(items.name) like '% #{downcase_query}%'").
order("case when lower(items.name) like '#{downcase_query}%' then 1 else 2 end,
items.name ASC")
一般来说,ruby中排序的关键是使用。sort或。sort_by
例如:
%w{香蕉苹果梨无花果}。Sort_by {|word| word。长度}# =>["无花果"、"梨"、"苹果"、"香蕉")
现在,在您的示例中,您需要指定您希望使用的标准。
假设您希望首先返回Rice,然后返回Rice Ball,我建议添加一个排序方法,优先首先返回Rice,然后处理其余的结果。