elastic_searchable 0.6.4 → 0.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/elastic_searchable/active_record_extensions.rb +43 -0
- data/lib/elastic_searchable/index.rb +16 -11
- data/lib/elastic_searchable/version.rb +1 -1
- data/lib/elastic_searchable.rb +1 -2
- data/test/helper.rb +1 -4
- data/test/setup_database.rb +30 -0
- data/test/test_elastic_searchable.rb +6 -28
- metadata +7 -5
- data/lib/elastic_searchable/active_record.rb +0 -47
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'after_commit'
|
3
|
+
require 'backgrounded'
|
4
|
+
require 'elastic_searchable/queries'
|
5
|
+
require 'elastic_searchable/callbacks'
|
6
|
+
require 'elastic_searchable/index'
|
7
|
+
|
8
|
+
module ElasticSearchable
|
9
|
+
module ActiveRecordExtensions
|
10
|
+
attr_accessor :elastic_options
|
11
|
+
|
12
|
+
# Valid options:
|
13
|
+
# :index (optional) configure index to store data in. default to ElasticSearchable.default_index
|
14
|
+
# :type (optional) configue type to store data in. default to model table name
|
15
|
+
# :index_options (optional) configure index properties (ex: tokenizer)
|
16
|
+
# :mapping (optional) configure field properties for this model (ex: skip analyzer for field)
|
17
|
+
# :if (optional) reference symbol/proc condition to only index when condition is true
|
18
|
+
# :unless (optional) reference symbol/proc condition to skip indexing when condition is true
|
19
|
+
# :json (optional) configure the json document to be indexed (see http://api.rubyonrails.org/classes/ActiveModel/Serializers/JSON.html#method-i-as_json for available options)
|
20
|
+
def elastic_searchable(options = {})
|
21
|
+
options.symbolize_keys!
|
22
|
+
self.elastic_options = options
|
23
|
+
|
24
|
+
extend ElasticSearchable::Indexing::ClassMethods
|
25
|
+
extend ElasticSearchable::Queries
|
26
|
+
|
27
|
+
include ElasticSearchable::Indexing::InstanceMethods
|
28
|
+
include ElasticSearchable::Callbacks::InstanceMethods
|
29
|
+
|
30
|
+
backgrounded :update_index_on_create => ElasticSearchable::Callbacks.backgrounded_options, :update_index_on_update => ElasticSearchable::Callbacks.backgrounded_options
|
31
|
+
class << self
|
32
|
+
backgrounded :delete_id_from_index => ElasticSearchable::Callbacks.backgrounded_options
|
33
|
+
end
|
34
|
+
|
35
|
+
define_callbacks :after_index_on_create, :after_index_on_update, :after_index
|
36
|
+
after_commit_on_create :update_index_on_create_backgrounded, :if => :should_index?
|
37
|
+
after_commit_on_update :update_index_on_update_backgrounded, :if => :should_index?
|
38
|
+
after_commit_on_destroy :delete_from_index
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
ActiveRecord::Base.send(:extend, ElasticSearchable::ActiveRecordExtensions)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'will_paginate'
|
2
|
+
|
1
3
|
module ElasticSearchable
|
2
4
|
module Indexing
|
3
5
|
module ClassMethods
|
@@ -54,20 +56,20 @@ module ElasticSearchable
|
|
54
56
|
end
|
55
57
|
|
56
58
|
# reindex all records using bulk api
|
57
|
-
# options:
|
58
|
-
# :scope - scope the find_in_batches to only a subset of records
|
59
|
-
# :batch - counter to start indexing at
|
60
|
-
# :include - passed to find_in_batches to hydrate objects
|
61
59
|
# see http://www.elasticsearch.org/guide/reference/api/bulk.html
|
60
|
+
# options:
|
61
|
+
# :scope - scope to use for looking up records to reindex. defaults to self (all)
|
62
|
+
# :page - page/batch to begin indexing at. defaults to 1
|
63
|
+
# :per_page - number of records to index per batch. defaults to 1000
|
62
64
|
def reindex(options = {})
|
63
65
|
self.update_index_mapping
|
64
|
-
|
65
|
-
options[:batch_size] ||= 1000
|
66
|
-
options[:start] ||= (batch - 1) * options[:batch_size]
|
66
|
+
options.reverse_merge! :page => 1, :per_page => 1000, :total_entries => 1
|
67
67
|
scope = options.delete(:scope) || self
|
68
|
-
|
69
|
-
|
70
|
-
|
68
|
+
|
69
|
+
records = scope.paginate(options)
|
70
|
+
while records.any? do
|
71
|
+
ElasticSearchable.logger.info "reindexing batch ##{records.current_page}..."
|
72
|
+
|
71
73
|
actions = []
|
72
74
|
records.each do |record|
|
73
75
|
next unless record.should_index?
|
@@ -82,9 +84,12 @@ module ElasticSearchable
|
|
82
84
|
begin
|
83
85
|
ElasticSearchable.request(:put, '/_bulk', :body => "\n#{actions.join("\n")}\n") if actions.any?
|
84
86
|
rescue ElasticError => e
|
85
|
-
ElasticSearchable.logger.warn "Error indexing batch ##{
|
87
|
+
ElasticSearchable.logger.warn "Error indexing batch ##{options[:page]}: #{e.message}"
|
86
88
|
ElasticSearchable.logger.warn e
|
87
89
|
end
|
90
|
+
|
91
|
+
options.merge! :page => (options[:page] + 1)
|
92
|
+
records = scope.paginate(options)
|
88
93
|
end
|
89
94
|
end
|
90
95
|
|
data/lib/elastic_searchable.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'httparty'
|
2
2
|
require 'logger'
|
3
|
-
require 'elastic_searchable/
|
3
|
+
require 'elastic_searchable/active_record_extensions'
|
4
4
|
|
5
5
|
module ElasticSearchable
|
6
6
|
include HTTParty
|
@@ -46,4 +46,3 @@ module ElasticSearchable
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
ActiveRecord::Base.send(:include, ElasticSearchable::ActiveRecord)
|
data/test/helper.rb
CHANGED
@@ -14,10 +14,7 @@ require 'mocha'
|
|
14
14
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
15
15
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
16
16
|
require 'elastic_searchable'
|
17
|
-
|
18
|
-
config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
|
19
|
-
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
|
20
|
-
ActiveRecord::Base.establish_connection(config[ENV['DB'] || 'sqlite'])
|
17
|
+
require 'setup_database'
|
21
18
|
|
22
19
|
class Test::Unit::TestCase
|
23
20
|
def delete_index
|
@@ -0,0 +1,30 @@
|
|
1
|
+
config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
|
2
|
+
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
|
3
|
+
ActiveRecord::Base.establish_connection(config[ENV['DB'] || 'sqlite'])
|
4
|
+
|
5
|
+
ActiveRecord::Schema.define(:version => 1) do
|
6
|
+
create_table :posts, :force => true do |t|
|
7
|
+
t.column :title, :string
|
8
|
+
t.column :body, :string
|
9
|
+
end
|
10
|
+
create_table :blogs, :force => true do |t|
|
11
|
+
t.column :title, :string
|
12
|
+
t.column :body, :string
|
13
|
+
end
|
14
|
+
create_table :users, :force => true do |t|
|
15
|
+
t.column :name, :string
|
16
|
+
end
|
17
|
+
create_table :friends, :force => true do |t|
|
18
|
+
t.column :name, :string
|
19
|
+
t.column :favorite_color, :string
|
20
|
+
end
|
21
|
+
create_table :books, :force => true do |t|
|
22
|
+
t.column :title, :string
|
23
|
+
end
|
24
|
+
create_table :max_page_size_classes, :force => true do |t|
|
25
|
+
t.column :name, :string
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
WillPaginate.enable_activerecord
|
30
|
+
|
@@ -1,30 +1,6 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'helper')
|
2
2
|
|
3
3
|
class TestElasticSearchable < Test::Unit::TestCase
|
4
|
-
ActiveRecord::Schema.define(:version => 1) do
|
5
|
-
create_table :posts, :force => true do |t|
|
6
|
-
t.column :title, :string
|
7
|
-
t.column :body, :string
|
8
|
-
end
|
9
|
-
create_table :blogs, :force => true do |t|
|
10
|
-
t.column :title, :string
|
11
|
-
t.column :body, :string
|
12
|
-
end
|
13
|
-
create_table :users, :force => true do |t|
|
14
|
-
t.column :name, :string
|
15
|
-
end
|
16
|
-
create_table :friends, :force => true do |t|
|
17
|
-
t.column :name, :string
|
18
|
-
t.column :favorite_color, :string
|
19
|
-
end
|
20
|
-
create_table :books, :force => true do |t|
|
21
|
-
t.column :title, :string
|
22
|
-
end
|
23
|
-
create_table :max_page_size_classes, :force => true do |t|
|
24
|
-
t.column :name, :string
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
4
|
def setup
|
29
5
|
delete_index
|
30
6
|
end
|
@@ -122,12 +98,14 @@ class TestElasticSearchable < Test::Unit::TestCase
|
|
122
98
|
end
|
123
99
|
context 'Post.reindex' do
|
124
100
|
setup do
|
125
|
-
Post.reindex
|
101
|
+
Post.reindex :per_page => 1, :scope => Post.scoped(:order => 'body desc')
|
126
102
|
Post.refresh_index
|
127
103
|
end
|
128
104
|
should 'have reindexed both records' do
|
129
|
-
|
130
|
-
|
105
|
+
assert_nothing_raised do
|
106
|
+
ElasticSearchable.request :get, "/elastic_searchable/posts/#{@first_post.id}"
|
107
|
+
ElasticSearchable.request :get, "/elastic_searchable/posts/#{@second_post.id}"
|
108
|
+
end
|
131
109
|
end
|
132
110
|
end
|
133
111
|
end
|
@@ -149,7 +127,7 @@ class TestElasticSearchable < Test::Unit::TestCase
|
|
149
127
|
end
|
150
128
|
should 'be paginated' do
|
151
129
|
assert_equal 1, @results.current_page
|
152
|
-
assert_equal
|
130
|
+
assert_equal Post.per_page, @results.per_page
|
153
131
|
assert_nil @results.previous_page
|
154
132
|
assert_nil @results.next_page
|
155
133
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elastic_searchable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 13
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 6
|
9
|
-
-
|
10
|
-
version: 0.6.
|
9
|
+
- 5
|
10
|
+
version: 0.6.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ryan Sonnek
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-04-01 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -191,13 +191,14 @@ files:
|
|
191
191
|
- VERSION
|
192
192
|
- elastic_searchable.gemspec
|
193
193
|
- lib/elastic_searchable.rb
|
194
|
-
- lib/elastic_searchable/
|
194
|
+
- lib/elastic_searchable/active_record_extensions.rb
|
195
195
|
- lib/elastic_searchable/callbacks.rb
|
196
196
|
- lib/elastic_searchable/index.rb
|
197
197
|
- lib/elastic_searchable/queries.rb
|
198
198
|
- lib/elastic_searchable/version.rb
|
199
199
|
- test/database.yml
|
200
200
|
- test/helper.rb
|
201
|
+
- test/setup_database.rb
|
201
202
|
- test/test_elastic_searchable.rb
|
202
203
|
has_rdoc: true
|
203
204
|
homepage: http://github.com/wireframe/elastic_searchable
|
@@ -236,4 +237,5 @@ summary: elastic search for activerecord
|
|
236
237
|
test_files:
|
237
238
|
- test/database.yml
|
238
239
|
- test/helper.rb
|
240
|
+
- test/setup_database.rb
|
239
241
|
- test/test_elastic_searchable.rb
|
@@ -1,47 +0,0 @@
|
|
1
|
-
require 'active_record'
|
2
|
-
require 'after_commit'
|
3
|
-
require 'backgrounded'
|
4
|
-
require 'elastic_searchable/queries'
|
5
|
-
require 'elastic_searchable/callbacks'
|
6
|
-
require 'elastic_searchable/index'
|
7
|
-
|
8
|
-
module ElasticSearchable
|
9
|
-
module ActiveRecord
|
10
|
-
def self.included(base)
|
11
|
-
base.send :extend, ClassMethods
|
12
|
-
end
|
13
|
-
|
14
|
-
module ClassMethods
|
15
|
-
attr_accessor :elastic_options
|
16
|
-
|
17
|
-
# Valid options:
|
18
|
-
# :index (optional) configure index to store data in. default to ElasticSearchable.default_index
|
19
|
-
# :type (optional) configue type to store data in. default to model table name
|
20
|
-
# :index_options (optional) configure index properties (ex: tokenizer)
|
21
|
-
# :mapping (optional) configure field properties for this model (ex: skip analyzer for field)
|
22
|
-
# :if (optional) reference symbol/proc condition to only index when condition is true
|
23
|
-
# :unless (optional) reference symbol/proc condition to skip indexing when condition is true
|
24
|
-
# :json (optional) configure the json document to be indexed (see http://api.rubyonrails.org/classes/ActiveModel/Serializers/JSON.html#method-i-as_json for available options)
|
25
|
-
def elastic_searchable(options = {})
|
26
|
-
options.symbolize_keys!
|
27
|
-
self.elastic_options = options
|
28
|
-
|
29
|
-
extend ElasticSearchable::Indexing::ClassMethods
|
30
|
-
extend ElasticSearchable::Queries
|
31
|
-
|
32
|
-
include ElasticSearchable::Indexing::InstanceMethods
|
33
|
-
include ElasticSearchable::Callbacks::InstanceMethods
|
34
|
-
|
35
|
-
backgrounded :update_index_on_create => ElasticSearchable::Callbacks.backgrounded_options, :update_index_on_update => ElasticSearchable::Callbacks.backgrounded_options
|
36
|
-
class << self
|
37
|
-
backgrounded :delete_id_from_index => ElasticSearchable::Callbacks.backgrounded_options
|
38
|
-
end
|
39
|
-
|
40
|
-
define_callbacks :after_index_on_create, :after_index_on_update, :after_index
|
41
|
-
after_commit_on_create :update_index_on_create_backgrounded, :if => :should_index?
|
42
|
-
after_commit_on_update :update_index_on_update_backgrounded, :if => :should_index?
|
43
|
-
after_commit_on_destroy :delete_from_index
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|