0

我正在使用带有 prostgres 和 Sinatra 的 Sequel。我想做一个自动完成搜索。我已经验证了发送 GET 的 jQuery 工作正常。

红宝石代码是:

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"}我想要的只是 Yao,我该怎么做?

我尝试了许多不同类型的查询,包括原始 SQL,但没有运气。还是这种方法完全错误?

4

2 回答 2

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

它应该返回找到的字符串数组。

于 2013-06-14T12:10:49.187 回答
0

从Sequel 文档中复制/粘贴:

您可以使用以下方法以区分大小写的方式搜索 SQL 字符串Sequel.like

items.where(Sequel.like(:name, 'Acme%')).sql
#=> "SELECT * FROM items WHERE (name LIKE 'Acme%')"

您可以使用以下方法以不区分大小写的方式搜索 SQL 字符串Sequel.ilike

items.where(Sequel.ilike(:name, 'Acme%')).sql
#=> "SELECT * FROM items WHERE (name ILIKE 'Acme%')"

您可以将 Regexp 指定为 like 参数,但这可能仅适用于 PostgreSQL 和 MySQL:

items.where(Sequel.like(:name, /Acme.*/)).sql
#=> "SELECT * FROM items WHERE (name ~ 'Acme.*')"

Like 也可以接受多个参数:

items.where(Sequel.like(:name, 'Acme%', /Beta.*/)).sql
#=> "SELECT * FROM items WHERE ((name LIKE 'Acme%') OR (name ~ 'Beta.*'))"

打开一个 Sequel 控制台(不是你的 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)

更丑的替代品:

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 库感兴趣。您无需在数据库中搜索,而是将所有姓氏的完整列表拉入 Ruby 并使用 LiqrrdMetal 搜索它们。这将允许搜索字符串“pho”同时匹配“Phong”和“Phrogz”,前者在排名中得分更高。

于 2013-06-15T04:25:35.470 回答