Commit 80ffae451ba9399f6e3ea8f1b98688fdb1896324

Authored by Andrew Kane
1 parent 3bfdc4a1

Start moving to elasticsearch gem

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