Tire is a rich Ruby API and DSL for the Elasticsearch search engine.
It exposes easy-to-use domain specific language for fluent communication with Elasticsearch.
It easily blends with your ActiveModel/ActiveRecord classes for convenient usage in Rails applications.
总之,Tire 是一个丰富的 Ruby API 工具包,封装了一系列与 ES 进行接口请求,JSON 数据处理的功能。
而且,针对 ActiveRecord 写了很多处理索引,搜索的实现,非常简单方便的与 Model 进行集成。
下面是一个学校模型,它有名称,别名,坐标等属性。 首先,在模型中引入 Tire::Model::Search。
# By including this module, you'll provide the model with facilities to
# perform searches against index, define index settings and mappings,
# access the index object, etc.
设置用于搜索的索引。
关于 ES 索引的配置,可以参考这篇文章:Efficient Elasticsearch indexing configuration。
mapping do
indexes :id, :type => 'integer', :index => 'not_analyzed'
indexes :name, :boost => 100, analyzer: "snowball"
indexes :nick_name, :boost => 50, analyzer: "snowball"
indexes :location, :type => 'geo_point'
end
运行任务,读取数据,建立索引。
rake school:build_indexes
namespace :school do
desc "build school indexes"
task :build_indexes => :environment do
puts "Start build school indexes"
School.where(status: 'active').find_in_batches do |batches|
School.index.import batches
end
puts "End build school indexes"
end
end
查看索引结构,可以在浏览器中,输入:
http://localhost:9200/_mapping
如需重建,可以在命令行执行 curl 命令,先删除索引(非常迅速)。
然后,再次执行建立索引的任务。
curl -XDELETE http://localhost:9200/schools
实现搜索方法。基于用户输入的关键词,针对建立的索引,做全文检索。
如果,客户端获取到了用户的地理坐标数据,则对搜索结构做地理位置排序,否则不排序。
def self.search(params)
longitude = params[:lng].to_f
latitude = params[:lat].to_f
params[:page] ||= 1
params[:per_page] ||= 20
tire.search(page: params[:page], per_page: params[:per_page], load: true) do
query do
boolean do
must { string params[:keyword], default_operator: "AND" } if params[:keyword].present?
end
end
if latitude != 0 && longitude != 0
sort do
by :_geo_distance, { location: [longitude, latitude], order: "asc", unit: 'km' }
end
end
end
end
更新索引。当商户数据变更时,如:名称调整,或者商户下家。则需要实时的同步更新索引。
after_save do
if self.active?
tire.update_index
else
self.index.remove self
end
end
2013-10-10