你好世界轮胎 (在Rails中引入tire)

在Ruby 2.0和Rails 4上进行确认。

Tire是一个用于在Ruby中使用elasticsearch全文搜索引擎的宝石。

[注意事项] 根据tire官方网站的说明,由于2013年9月出现了elasticserach的官方gem“elasticsearch / elasticsearch-ruby”,tire已经退休了。尽管tire仍然可用,但在使用ruby调用elasticsearch时,建议使用elasticsearch-ruby。

由于在我使用tire之前elasticsearch-ruby还没有出现,所以我这次将整理关于tire的内容。

请查看此处以获取更详细的内容。

最初的设定

    アプリ作成
rails new tire_sample
    Gemfile追加
gem 'tire'
gem 'kaminari' # 検索結果のページャに使用します
    bundle install
./bin/bundle install --path=vendor/bundler
    initializer設定
config/initializers/tire.rb
Tire.configure do
  url "http://0.0.0.0:9200" # elasticsearchのurlを設定
end

建立模型

    Topicモデル作成
./bin/rails g model topic title:string body:text
    migrate
./bin/rake db:migrate
    seed登録
Topic.create(title: 'Rubyでhello world', body: 'おはようございます。サンプルです')
Topic.create(title: 'Perlでhello world', body: 'こんにちは。サンプルです')
Topic.create(title: 'PHPでhello world', body: 'こんばんわ。サンプルです')
Topic.create(title: 'Rubyでhello world no.2', body: 'おはようございます。サンプルです')
Topic.create(title: 'Perlでhello world no.2', body: 'こんにちは。サンプルです')
Topic.create(title: 'PHPでhello world no.2', body: 'こんばんわ。サンプルです')
    seed流し込み
./bin/rake db:seed
    Topicモデル編集
class Topic < ActiveRecord::Base
  # tireモジュール読み込み
  include Tire::Model::Search

  after_save :index_update
  after_destroy :index_remove

  # elasticsearchのindex名を設定、環境に応じてindexを変更できるようにしておく
  index_name("#{Rails.env}-search-topics")

  # idとtitleとbodyをマッピング対象に設定
  mapping do
    indexes :id
    indexes :title, analyzer: :kuromoji # kuromoji日本語形態素解析器を使用する
    indexes :body, analyzer: :kuromoji # kuromoji日本語形態素解析器を使用する
  end

  # save後にindexを更新
  def index_update
    self.index.store self
  end

  # destroy後にindexから削除
  def index_remove
    self.index.remove self
  end

  # 検索
  def self.search(params)
    tire.search(load: true, :page => params[:page], per_page: params[:limit]) do
      # titleとbodyから複合検索
      query {
        boolean do
          should { string 'title:' + params[:keyword].gsub('!', '\!').gsub('"', '\\"'), default_operator: "AND" }
          should { string 'body:' + params[:keyword].gsub('!', '\!').gsub('"', '\\"'), default_operator: "AND" }
        end
      } if params[:keyword].present?
      sort do
        by params[:order], 'desc'
      end
    end
  end
end

如果指定了`include Tire::Model::Callbacks`,就不需要单独设置添加和删除索引,但是为了以后允许Resque执行索引重建操作,我们进行了单独设置。

另外,当进行搜索时,如果输入”会导致elasticsearch发生错误,因此我们进行了转义处理。

2014年1月6日 补充说明

由于出现错误,我进行了转义处理。

请参考以下链接:https://github.com/karmi/retire/issues/828

    indexの再構築コマンド

由于在本次操作中首先创建了种子,因此需要重新构建索引。

如果要重新构建主题模型的索引,您可以按以下方式指定主题并执行命令。

./bin/rake environment tire:import CLASS='Topic' FORCE=true

创建控制器

我将尝试创建一个关于主题搜索的API。

    Topicコントローラ作成
./bin/rails g controller topic index
    routing設定
root "topic#index"
get "topic/index"
    indexアクション編集
class TopicController < ApplicationController
  def index
    limit = params[:limit].presence || 3
    if limit.to_i == 0
      limit = 3
    elsif limit.to_i > 10
      limit = 10
    end

    current_page = params[:page].presence || 1
    if current_page.to_i == 0
      current_page = 1
    end
    keyword = params[:keyword].presence

    begin
      topics = Topic.search({
        keyword: keyword,
        order: :id,
        limit: limit,
        page: current_page,
      })
    rescue => e
      logger.error(e.message)
      logger.error(e.backtrace.join("\n"))
      return render json: { error: 500 }
    end

    paging = {
      total: topics.total_count,
      total_pages: topics.num_pages,
      per_page: limit,
      current_page: current_page,
    }

    render json: { topics: topics, paging: paging }
  end
end

确认

当通过浏览器访问 http://localhost:3000 时,将会以JSON的形式返回结果。

{
  "paging": {
    "current_page": 1,
    "per_page": 3,
    "total_pages": 2,
    "total": 6
  },
  "topics": [
    {
      "updated_at": "2013-12-01T17:21:49.953Z",
      "created_at": "2013-12-01T17:21:49.953Z",
      "body": "こんばんわ。サンプルです",
      "title": "PHPでhello world no.2",
      "id": 6
    },
    {
      "updated_at": "2013-12-01T17:21:49.941Z",
      "created_at": "2013-12-01T17:21:49.941Z",
      "body": "こんにちは。サンプルです",
      "title": "Perlでhello world no.2",
      "id": 5
    },
    {
      "updated_at": "2013-12-01T17:21:49.931Z",
      "created_at": "2013-12-01T17:21:49.931Z",
      "body": "おはようございます。サンプルです",
      "title": "Rubyでhello world no.2",
      "id": 4
    }
  ]
}

在指定参数后,可以进行筛选。

http://localhost:300的/?keyword=ruby 早上好

{
  "paging": {
    "current_page": 1,
    "per_page": 3,
    "total_pages": 1,
    "total": 2
  },
  "topics": [
    {
      "updated_at": "2013-12-01T17:21:49.931Z",
      "created_at": "2013-12-01T17:21:49.931Z",
      "body": "おはようございます。サンプルです",
      "title": "Rubyでhello world no.2",
      "id": 4
    },
    {
      "updated_at": "2013-12-01T17:21:49.869Z",
      "created_at": "2013-12-01T17:21:49.869Z",
      "body": "おはようございます。サンプルです",
      "title": "Rubyでhello world",
      "id": 1
    }
  ]
}

总结

通过使用轮胎,可以方便地嵌入全文搜索引擎。

下次尝试将索引重建处理通过resque投放。

请看,
这是一个巨大的机会。

    • Hello World Tire (Railsにtireを導入する)

 

    • elasticsearch での Kuromoji の使い方

 

    • railsから全文検索エンジンelasticsearchを利用する

 

    • elasticsearchを日本語も扱えるようにRailsで使うメモ(Mongoid+Tire)

 

    • elasticsearchのGUI「elasticsearch-head」がとても便利

 

    • elasticsearchとkuromojiプラグインで日本語の全文検索

 

    • elasticsearch version0.20.6の設定

 

    • ElasitcSearch ことはじめ

 

    • Elasticsearch入門 pyfes 201207

 

    • 日本語Wikipediaをインデクシング(Kuromojiバージョン)

 

    • Elasticsearchで日本語(kuromoji)を使う

 

    • SolrとElasticsearchの比較

 

    • karmi/tire

 

    • 第1回ElasticSearch勉強会を開催しました! #elasticsearchjp

 

    • Elastic searchをrailsから使ってみた

 

    • Can tire callbacks be put into a resque job?

 

    • Configuring the port for Tire

 

    elasticsearch/elasticsearch-servicewrapper
广告
将在 10 秒后关闭
bannerAds