我正在使用续集与prostgres和Sinatra。我想做一个自动完成搜索。我已经验证了我发送GET的jQuery工作正常。
Ruby代码是:
get '/search' do
search = params[:search]
DB[:candidates].select(:last).where('last LIKE ?', '_a_').each do |row|
l = row[:last]
end
end
问题是续集查询:
我已经尝试了所有可能的查询配置,我可以想到没有运气。
因此,例如,在上面的查询中,我得到所有姓氏中都有“a”的人,但是当我将查询更改为:
DB[:candidates].select(:last).where('last LIKE ?', 'search')
或
DB[:candidates].select(:last).where('last LIKE ?', search) # (without '')
我一无所获。
我已完成warn params.inspect
,表示正在传递参数搜索,所以我被卡住了。
任何想法应该如何编写查询?
最后,结果问题的第二部分(当它与'_a_'
一起使用时)呈现为{:last=>"Yao"}
我想要姚明,我该怎么做?
我尝试了很多不同类型的查询,包括原始SQL,但没有运气。或者这种方法是否完全错误?
答案 0 :(得分:1)
刚刚安装了Sequel
并做了一个工作示例:
require "rubygems"
require "sequel"
# connect to an in-memory database
DB = Sequel.sqlite
# create an items table
DB.create_table :items do
primary_key :id
String :name
Float :price
end
# create a dataset from the items table
items = DB[:items]
# populate the table
items.insert(:name => 'abc', :price => rand * 100)
items.insert(:name => 'def', :price => rand * 100)
items.insert(:name => 'ghi', :price => rand * 100)
items.insert(:name => 'gui', :price => rand * 100)
# print out the number of records
puts "Item count: #{items.count}"
# print out the average price
puts "The average price is: #{items.avg(:price)}"
recs = items.select(:name).where(Sequel.like(:name, 'g%'))
recs.each do |rec|
puts rec.values
end
我想你会明白这一点。
已更新
所以在你的情况下你应该试试这个:
DB[:candidates]
.select(:last)
.where(Sequel.like(:last, "#{search}%"))
.map{|rec| rec.values}.flatten
它应该返回找到的字符串数组。
答案 1 :(得分:0)
从the Sequel documentation复制/粘贴:
您可以使用
Sequel.like
方法以区分大小写的方式搜索SQL字符串:items.where(Sequel.like(:name, 'Acme%')).sql #=> "SELECT * FROM items WHERE (name LIKE 'Acme%')"
您可以使用
Sequel.ilike
方法以不区分大小写的方式搜索SQL字符串:items.where(Sequel.ilike(:name, 'Acme%')).sql #=> "SELECT * FROM items WHERE (name ILIKE 'Acme%')"
您可以将Regexp指定为类似的参数,但这可能仅适用于PostgreSQL和MySQL:
items.where(Sequel.like(:name, /Acme.*/)).sql #=> "SELECT * FROM items WHERE (name ~ 'Acme.*')"
喜欢也可以采取多个论点:
items.where(Sequel.like(:name, 'Acme%', /Beta.*/)).sql #=> "SELECT * FROM items WHERE ((name LIKE 'Acme%') OR (name ~ 'Beta.*'))"
Open up a Sequel console(不是您的Sinatra应用)并使用查询,直到您获得结果。由于您说您只想要last
列,因此您的查询应该是:
# Search anywhere inside the last name
DB[:candidates].where( Sequel.ilike(:last, "%#{search}%") ).select_map(:last)
# Find last names starting with the search string
DB[:candidates].where( Sequel.ilike(:last, "#{search}%") ).select_map(:last)
Uglier替代方案:
DB[:candidates]
.select(:last)
.where( Sequel.ilike(:last, "%#{search}%") )
.all
.map{ |hash| hash[:last] }
DB[:candidates]
.select(:last)
.where( Sequel.ilike(:last, "%#{search}%") )
.map( :last )
如果您想按最佳匹配对搜索结果进行排名,可能对我的免费LiqrrdMetal library感兴趣。您可以将所有姓氏的完整列表提取到Ruby中,然后使用LiqrrdMetal搜索它们,而不是搜索数据库。这将允许“pho”的搜索字符串匹配“Phong”和“Phrogz”,前者的得分在排名中更高。