Commit 80ffae451ba9399f6e3ea8f1b98688fdb1896324

Authored by Andrew Kane
1 parent 3bfdc4a1

Start moving to elasticsearch gem

lib/searchkick.rb
1   -require "tire"
  1 +require "elasticsearch"
2 2 require "searchkick/version"
  3 +require "searchkick/index"
3 4 require "searchkick/reindex"
4 5 require "searchkick/results"
5 6 require "searchkick/search"
6 7 require "searchkick/similar"
7 8 require "searchkick/model"
8 9 require "searchkick/tasks"
9   -require "searchkick/logger" if defined?(Rails)
  10 +# TODO add logger
  11 +# require "searchkick/logger" if defined?(Rails)
10 12  
11 13 module Searchkick
  14 +
  15 + def self.client
  16 + @client ||= Elasticsearch::Client.new log: true
  17 + end
  18 +
12 19 @callbacks = true
13 20  
14 21 def self.enable_callbacks
... ... @@ -24,6 +31,8 @@ module Searchkick
24 31 end
25 32 end
26 33  
  34 +require "active_record" # TODO remove
  35 +
27 36 # TODO find better ActiveModel hook
28   -ActiveModel::Callbacks.send(:include, Searchkick::Model)
  37 +ActiveModel::Callbacks.send(:include, Searchkick::Model) if defined?(ActiveModel)
29 38 ActiveRecord::Base.send(:extend, Searchkick::Model) if defined?(ActiveRecord)
... ...
lib/searchkick/index.rb 0 → 100644
... ... @@ -0,0 +1,32 @@
  1 +module Searchkick
  2 + class Index
  3 + attr_reader :name
  4 +
  5 + def initialize(name)
  6 + @name = name
  7 + end
  8 +
  9 + def create(options = {})
  10 + Searchkick.client.indices.create index: name, body: options
  11 + end
  12 +
  13 + def delete
  14 + Searchkick.client.indices.delete index: name
  15 + end
  16 +
  17 + def exists?
  18 + Searchkick.client.indices.exists index: name
  19 + end
  20 +
  21 + def refresh
  22 + Searchkick.client.indices.refresh index: name
  23 + end
  24 +
  25 + def store(model)
  26 + end
  27 +
  28 + def remove(model)
  29 + end
  30 +
  31 + end
  32 +end
... ...
lib/searchkick/model.rb
... ... @@ -13,7 +13,7 @@ module Searchkick
13 13 # set index name
14 14 # TODO support proc
15 15 index_name = options[:index_name] || [options[:index_prefix], model_name.plural, searchkick_env].compact.join("_")
16   - class_variable_set :@@searchkick_index, Tire::Index.new(index_name)
  16 + class_variable_set :@@searchkick_index, Searchkick::Index.new(index_name)
17 17  
18 18 extend Searchkick::Search
19 19 extend Searchkick::Reindex
... ...
lib/searchkick/reindex.rb
... ... @@ -2,36 +2,29 @@ module Searchkick
2 2 module Reindex
3 3  
4 4 # https://gist.github.com/jarosan/3124884
  5 + # http://www.elasticsearch.org/blog/changing-mapping-with-zero-downtime/
5 6 def reindex
6 7 alias_name = searchkick_index.name
7 8 new_index = alias_name + "_" + Time.now.strftime("%Y%m%d%H%M%S%L")
8   - index = Tire::Index.new(new_index)
  9 + index = Searchkick::Index.new(new_index)
9 10  
10 11 clean_indices
11 12  
12 13 success = index.create searchkick_index_options
13 14 raise index.response.to_s if !success
14 15  
15   - if a = Tire::Alias.find(alias_name)
  16 + # check if alias exists
  17 + if Searchkick.client.indices.exists_alias name: alias_name
16 18 searchkick_import(index) # import before swap
17 19  
18   - a.indices.each do |i|
19   - a.indices.delete i
20   - end
21   -
22   - a.indices.add new_index
23   - response = a.save
24   -
25   - if response.success?
26   - clean_indices
27   - else
28   - raise response.to_s
29   - end
  20 + # get existing indices to remove
  21 + old_indices = Searchkick.client.indices.get_alias(name: alias_name).keys
  22 + actions = old_indices.map{|name| {remove: {index: name, alias: alias_name}} } + [{add: {index: new_index, alias: alias_name}}]
  23 + Searchkick.client.indices.update_aliases body: {actions: actions}
  24 + clean_indices
30 25 else
31 26 searchkick_index.delete if searchkick_index.exists?
32   - response = Tire::Alias.create(name: alias_name, indices: [new_index])
33   - raise response.to_s if !response.success?
34   -
  27 + Searchkick.client.indices.update_aliases body: {actions: [{add: {index: new_index, alias: alias_name}}]}
35 28 searchkick_import(index) # import after swap
36 29 end
37 30  
... ... @@ -42,10 +35,10 @@ module Searchkick
42 35  
43 36 # remove old indices that start w/ index_name
44 37 def clean_indices
45   - all_indices = JSON.parse(Tire::Configuration.client.get("#{Tire::Configuration.url}/_aliases").body)
  38 + all_indices = Searchkick.client.indices.get_aliases
46 39 indices = all_indices.select{|k, v| v["aliases"].empty? && k =~ /\A#{Regexp.escape(searchkick_index.name)}_\d{14,17}\z/ }.keys
47 40 indices.each do |index|
48   - Tire::Index.new(index).delete
  41 + Searchkick::Index.new(index).delete
49 42 end
50 43 indices
51 44 end
... ...
lib/searchkick/results.rb
1 1 module Searchkick
2   - class Results < Tire::Results::Collection
  2 + class Results
3 3  
4 4 def suggestions
5 5 if @response["suggest"]
... ...
lib/searchkick/search.rb
... ... @@ -328,10 +328,9 @@ module Searchkick
328 328  
329 329 tire_options = {load: load, payload: payload, size: per_page, from: offset}
330 330 tire_options[:type] = document_type if self != searchkick_klass
331   - search = Tire::Search::Search.new(index_name, tire_options)
332 331 begin
333   - response = search.json
334   - rescue Tire::Search::SearchRequestFailed => e
  332 + response = Searchkick.client.search index: index_name, body: payload
  333 + rescue => e
335 334 status_code = e.message[0..3].to_i
336 335 if status_code == 404
337 336 raise "Index missing - run #{searchkick_klass.name}.reindex"
... ...
searchkick.gemspec
... ... @@ -18,8 +18,7 @@ Gem::Specification.new do |spec|
18 18 spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19 19 spec.require_paths = ["lib"]
20 20  
21   - spec.add_dependency "tire"
22   - spec.add_dependency "tire-contrib"
  21 + spec.add_dependency "elasticsearch"
23 22  
24 23 spec.add_development_dependency "bundler", "~> 1.3"
25 24 spec.add_development_dependency "rake"
... ...
test/index_test.rb
... ... @@ -3,8 +3,8 @@ require_relative &quot;test_helper&quot;
3 3 class TestIndex < Minitest::Unit::TestCase
4 4  
5 5 def test_clean_indices
6   - old_index = Tire::Index.new("products_test_20130801000000000")
7   - different_index = Tire::Index.new("items_test_20130801000000000")
  6 + old_index = Searchkick::Index.new("products_test_20130801000000000")
  7 + different_index = Searchkick::Index.new("items_test_20130801000000000")
8 8  
9 9 # create indexes
10 10 old_index.create
... ... @@ -18,7 +18,7 @@ class TestIndex &lt; Minitest::Unit::TestCase
18 18 end
19 19  
20 20 def test_clean_indices_old_format
21   - old_index = Tire::Index.new("products_test_20130801000000")
  21 + old_index = Searchkick::Index.new("products_test_20130801000000")
22 22 old_index.create
23 23  
24 24 Product.clean_indices
... ...
test/test_helper.rb
... ... @@ -6,10 +6,7 @@ require &quot;minitest/pride&quot;
6 6 ENV["RACK_ENV"] = "test"
7 7  
8 8 File.delete("elasticsearch.log") if File.exists?("elasticsearch.log")
9   -Tire.configure do
10   - logger "elasticsearch.log", :level => "debug"
11   - pretty true
12   -end
  9 +Searchkick.client.transport.logger = Logger.new("elasticsearch.log")
13 10  
14 11 if defined?(Mongoid)
15 12 Mongoid.configure do |config|
... ...