这两天项目要求,把现有的搜索改成 ElasticSearch(后面简称 es)。之前接触 过一些 es,后来就开始捣鼓。记得 railcasts 上面有讲过相关视频,重温了下就 开始弄,没弄多久发现上面用的tire已经 retire 了。为了让更多的朋友们不走冤枉路,所以才有了此文。
大致说下什么是 es,详细的Wikipedia有介绍。es 其实就是一个搜索的引擎,从开源项目 lucene 出来,lucene 是 java 编写的,比较复杂,要使用它必须了解核心一大堆东西。es 就是包装了一层,然后提供 RESTFUL API 调用,从而让全文搜索变得更加简单。
在安装 es 之前,先安装 jdk。
Mac 环境,运行 brew install elasticsearch
, 然后运行elasticsearch --config=/usr/local/opt/elasticsearch/config/elasticsearch.yml
启动,访问 http://localhost:9200,访问成功就表示安装完成了。
其他环境,访问官网相关安装包下载。
在 Gemfile 中加入
gem 'elasticsearch-model'
gem 'elasticsearch-rails'
注意:es-model 自带了分页插件,如果你在 gemfile 中有分页,如will_paginate
或者 kaminari
,要把他们放到 es-model 和 es-rails 的前面。
在需要添加搜索的 model 添加以下代码:
class University < ActiveRecord::Base
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks
end
完成引用后,我们可以编写 search 方法了:
def self.search(search)
response = __elasticsearch__.search(search)
end
这是一个很简单的 search,通过传入的参数直接进行检索。我们可以使用 DSL 来使我们的检索语句更加满足我们的业务需要,以下是我需要检索一个状态为 1,并且从栏目名为 name 的一个检索:
def self.search_filter(params)
response = __elasticsearch__.search(
"query": {
"filtered": {
"filter": {
"bool": {
"must": { "term": { "status": 1 }},
"must": {
"query": {
"match": { "name": params }
}
}
}
}
}
}
)
end
关于 es 的 DSL 更多写法,大家可以访问这里。里面详细的讲解了 query,filter 等一些常用查询,大家可以根据业务需要自行改装。
然后我们为 model 创建 index, 主要给 es 使用:
mapping dynamic: false do
indexes :name
indexes :tag
end
我们继续往下走,model 是可以 serialized 成 json 的,我们使用as_indexed_json
这个方法。我们可以这样写:
def as_indexed_json(options={})
self.as_json(
only: [:id, :name, :description, :status],
include: { tags: { only: [:name]}}
)
end
include
的部分是处理 association 的,only
是 model 本身的字段属性。完成了以上调整,我们的 model 搜索基本完成了。如果你现在使用搜索,我估计还是搜索不出数据。我们要把数据导入给 es,使用这个命令
rake environment elasticsearch:import:model CLASS='your_model_name' FORCE=y
好啦。基本就完成。es 默认自带中文分词,但是有些 posts 反馈说不大好用,可以使用es-rtf,集成了中文的分词插件,下载直接可以用。必须要安装 jdk,里面有详尽的使用方法。
gem 的README,有耐心慢慢看可以了解很多
一些快速的 tutorial
http://www.sitepoint.com/full-text-search-rails-elasticsearch/ http://aaronvb.com/articles/intro-to-elasticsearch-ruby-on-rails-part-1.html http://www.spacevatican.org/2012/6/3/fun-with-elasticsearch-s-children-and-nested-documents/
可以了解,railcast 的 es 介绍 http://railscasts.com/episodes/306-elasticsearch-part-1