整合 ElasticSearch 到现有 Rails 项目

导言

这两天项目要求,把现有的搜索改成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


你可能感兴趣的:(整合 ElasticSearch 到现有 Rails 项目)