elasticsearch-model-extensions 0.1.0 → 0.2.0
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.
- checksums.yaml +4 -4
- data/.travis.yml +13 -8
- data/Gemfile +1 -0
- data/lib/elasticsearch/model/extensions/delayed_job/delete_document_job.rb +23 -0
- data/lib/elasticsearch/model/extensions/delayed_job/document_job.rb +56 -0
- data/lib/elasticsearch/model/extensions/delayed_job/index_document_job.rb +23 -0
- data/lib/elasticsearch/model/extensions/delayed_job/partially_update_document_job.rb +24 -0
- data/lib/elasticsearch/model/extensions/delayed_job.rb +3 -0
- data/lib/elasticsearch/model/extensions/version.rb +1 -1
- data/spec/integration_spec.rb +59 -29
- data/spec/outer_document_updating_spec.rb +50 -12
- data/spec/setup/articles.rb +29 -0
- data/spec/setup/articles_with_comments.rb +2 -0
- data/spec/setup/articles_with_comments_and_delayed_jobs.rb +90 -0
- data/spec/setup/undefine.rb +7 -0
- metadata +12 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 147bafb31fb754df6328f7fa3c2e27a5af454d06
|
4
|
+
data.tar.gz: dc047cf6c1423e9b3a45682737cee36869389f94
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 05d3f75d719269e736958c19e64cf3c19c16a3a89562f73e71c9c925023526dbc755487c67cd1d001ba2adc235ed765514f3dccd7d516641d3201c1c84ce8041
|
7
|
+
data.tar.gz: 33b5d02632d47fa7584ede224f6692c8f12604cd6f1ffff16c3d316e732fb4d26fef182ffc5cd1880b25e46860859b68915750540334f84e0e22163e1290f60e
|
data/.travis.yml
CHANGED
@@ -1,15 +1,20 @@
|
|
1
|
-
bundler_args: --without development
|
1
|
+
bundler_args: "--without development"
|
2
2
|
language: ruby
|
3
3
|
rvm:
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
- 2.1.2
|
5
|
+
- 2.1.3
|
6
|
+
- ruby-head
|
7
7
|
matrix:
|
8
8
|
allow_failures:
|
9
|
-
|
9
|
+
- rvm: ruby-head
|
10
10
|
fast_finish: true
|
11
11
|
before_script:
|
12
|
-
|
13
|
-
|
12
|
+
- ls -la /usr/share/elasticsearch/bin/elasticsearch
|
13
|
+
- echo $PWD
|
14
14
|
before_install: gem install bundler
|
15
|
-
script: SERVER=launch TEST_CLUSTER_COMMAND=/usr/share/elasticsearch/bin/elasticsearch
|
15
|
+
script: SERVER=launch TEST_CLUSTER_COMMAND=/usr/share/elasticsearch/bin/elasticsearch
|
16
|
+
TEST_CLUSTER_PARAMS='-Des.default.path.conf=/etc/elasticsearch/ -Des.default.path.logs=/var/log/elasticsearch/'
|
17
|
+
TEST_CLUSTER_PORT=19250 bundle exec rspec
|
18
|
+
notifications:
|
19
|
+
slack:
|
20
|
+
secure: CjEsKopTHFKWCyouA988YJrtrqsPsCg4fFNrhuVNoOl8DRYC4D0FS/NwVKNEnchDjl9pz5YFkc5QCLaMGtG6ZgQVc9zdg0cDizbRIF9WI5ryOWamthvfdx54/EIJXtQxUTeono4SwieAkjXRGrWpNzdGxY4xs6Hdfwup/YYPdiI=
|
data/Gemfile
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative 'document_job'
|
2
|
+
|
3
|
+
module Elasticsearch
|
4
|
+
module Model
|
5
|
+
module Extensions
|
6
|
+
module DelayedJob
|
7
|
+
|
8
|
+
class DeleteDocumentJob < DocumentJob
|
9
|
+
def initialize(params)
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
def perform
|
14
|
+
try_with_record do |record|
|
15
|
+
record.__elasticsearch__.delete_document
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'delayed_job'
|
2
|
+
|
3
|
+
module Elasticsearch
|
4
|
+
module Model
|
5
|
+
module Extensions
|
6
|
+
module DelayedJob
|
7
|
+
|
8
|
+
class DocumentJob
|
9
|
+
def initialize(params)
|
10
|
+
record = params[:record]
|
11
|
+
@active_record = params[:active_record] || record.class
|
12
|
+
@id = params[:id] || record.id
|
13
|
+
@run_only_if = params[:run_only_if]
|
14
|
+
end
|
15
|
+
|
16
|
+
def max_attempts
|
17
|
+
10
|
18
|
+
end
|
19
|
+
|
20
|
+
def enqueue!
|
21
|
+
Delayed::Job.enqueue self
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def find_record_or_raise
|
27
|
+
@active_record.find(@id)
|
28
|
+
end
|
29
|
+
|
30
|
+
def record
|
31
|
+
begin
|
32
|
+
find_record_or_raise
|
33
|
+
rescue ActiveRecord::RecordNotFound => e
|
34
|
+
Rails.logger.info "#{self.class.name}: #{e.to_s}"
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def if_enabled_try_with_record(&block)
|
40
|
+
if @run_only_if.nil? || @run_only_if[0].send(@run_only_if[1])
|
41
|
+
try_with_record(&block)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def try_with_record
|
46
|
+
record.tap do |r|
|
47
|
+
yield r if r
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative 'document_job'
|
2
|
+
|
3
|
+
module Elasticsearch
|
4
|
+
module Model
|
5
|
+
module Extensions
|
6
|
+
module DelayedJob
|
7
|
+
|
8
|
+
class IndexDocumentJob < DocumentJob
|
9
|
+
def initialize(params)
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
def perform
|
14
|
+
try_with_record do |record|
|
15
|
+
record.__elasticsearch__.index_document
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'document_job'
|
2
|
+
|
3
|
+
module Elasticsearch
|
4
|
+
module Model
|
5
|
+
module Extensions
|
6
|
+
module DelayedJob
|
7
|
+
|
8
|
+
class PartiallyUpdateDocumentJob < DocumentJob
|
9
|
+
def initialize(params)
|
10
|
+
super(record: params[:record])
|
11
|
+
@changes = params[:changes]
|
12
|
+
end
|
13
|
+
|
14
|
+
def perform
|
15
|
+
try_with_record do |record|
|
16
|
+
record.partially_update_document(*@changes)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/spec/integration_spec.rb
CHANGED
@@ -1,45 +1,75 @@
|
|
1
1
|
require 'elasticsearch/model/extensions/all'
|
2
2
|
|
3
|
-
RSpec.
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
RSpec.shared_examples 'a normal elasticsearch-model object' do
|
4
|
+
describe 'a record creation' do
|
5
|
+
before(:each) do
|
6
|
+
::Article.create(title: 'foo', created_at: Time.now)
|
7
|
+
|
8
|
+
::Article.__elasticsearch__.refresh_index!
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'makes the document searchable' do
|
12
|
+
expect(Article.search('foo').records.size).to eq(1)
|
10
13
|
end
|
14
|
+
end
|
11
15
|
|
12
|
-
|
13
|
-
|
14
|
-
|
16
|
+
describe 'a record update' do
|
17
|
+
before(:each) do
|
18
|
+
Article.first.update_attributes title: 'Test2'
|
15
19
|
|
16
|
-
|
17
|
-
mapping do
|
18
|
-
indexes :title, type: 'string', analyzer: 'snowball'
|
19
|
-
indexes :created_at, type: 'date'
|
20
|
-
end
|
21
|
-
end
|
20
|
+
Article.__elasticsearch__.refresh_index!
|
22
21
|
end
|
23
22
|
|
24
|
-
|
25
|
-
|
23
|
+
it 'makes the document unsearchable using the old content' do
|
24
|
+
expect(Article.search('Test').records.size).to eq(0)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'makes the document searchable using the new content' do
|
28
|
+
expect(Article.search('Test2').records.size).to eq(1)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe 'a record deletion' do
|
33
|
+
before(:each) do
|
34
|
+
Article.first.destroy
|
26
35
|
|
27
|
-
|
28
|
-
|
29
|
-
::Article.create! title: 'Coding'
|
36
|
+
Article.__elasticsearch__.refresh_index!
|
37
|
+
end
|
30
38
|
|
31
|
-
|
39
|
+
it 'makes the document unsearchable' do
|
40
|
+
expect(Article.search('Test').records.size).to eq(0)
|
41
|
+
end
|
32
42
|
end
|
43
|
+
end
|
44
|
+
|
45
|
+
RSpec.describe 'integration' do
|
46
|
+
context 'with articles' do
|
47
|
+
before :each do
|
48
|
+
load 'setup/articles.rb'
|
49
|
+
end
|
33
50
|
|
34
|
-
|
35
|
-
|
36
|
-
|
51
|
+
after :each do
|
52
|
+
ActiveRecord::Schema.define(:version => 2) do
|
53
|
+
drop_table :articles
|
54
|
+
end
|
37
55
|
end
|
56
|
+
|
57
|
+
it_behaves_like 'a normal elasticsearch-model object'
|
38
58
|
end
|
39
59
|
|
40
|
-
|
41
|
-
|
42
|
-
|
60
|
+
context 'with articles_with_comments_and_delayed_jobs' do
|
61
|
+
before(:each) do
|
62
|
+
load 'setup/articles_with_comments_and_delayed_jobs.rb'
|
63
|
+
end
|
43
64
|
|
44
|
-
|
65
|
+
after(:each) do
|
66
|
+
ActiveRecord::Schema.define(:version => 2) do
|
67
|
+
drop_table :articles
|
68
|
+
drop_table :comments
|
69
|
+
drop_table :delayed_jobs
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
it_behaves_like 'a normal elasticsearch-model object'
|
74
|
+
end
|
45
75
|
end
|
@@ -1,17 +1,6 @@
|
|
1
1
|
require 'elasticsearch/model/extensions/all'
|
2
2
|
|
3
|
-
RSpec.
|
4
|
-
before(:each) do
|
5
|
-
load 'setup/articles_with_comments.rb'
|
6
|
-
end
|
7
|
-
|
8
|
-
after :each do
|
9
|
-
ActiveRecord::Schema.define(:version => 2) do
|
10
|
-
drop_table :comments
|
11
|
-
drop_table :articles
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
3
|
+
RSpec.shared_examples 'a document updates outer documents on changed' do
|
15
4
|
describe 'an article' do
|
16
5
|
def article
|
17
6
|
::Article.search('Comment1').records.first
|
@@ -30,6 +19,22 @@ RSpec.describe Elasticsearch::Model::Extensions::OuterDocumentUpdating do
|
|
30
19
|
}
|
31
20
|
end
|
32
21
|
|
22
|
+
context 'with a comment updated' do
|
23
|
+
before(:each) do
|
24
|
+
article.comments.first.update_attributes body: 'Comment3'
|
25
|
+
|
26
|
+
Article.__elasticsearch__.refresh_index!
|
27
|
+
end
|
28
|
+
|
29
|
+
specify {
|
30
|
+
expect(Article.search('Comment1').records.first).to be_nil
|
31
|
+
}
|
32
|
+
|
33
|
+
specify {
|
34
|
+
expect(Article.search('Comment3').records.first).not_to be_nil
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
33
38
|
context 'when a comment destroyed' do
|
34
39
|
before(:each) do
|
35
40
|
article.comments.first.destroy
|
@@ -47,3 +52,36 @@ RSpec.describe Elasticsearch::Model::Extensions::OuterDocumentUpdating do
|
|
47
52
|
end
|
48
53
|
end
|
49
54
|
end
|
55
|
+
|
56
|
+
RSpec.describe Elasticsearch::Model::Extensions::OuterDocumentUpdating do
|
57
|
+
context 'having articles with comments' do
|
58
|
+
before(:each) do
|
59
|
+
load 'setup/articles_with_comments.rb'
|
60
|
+
end
|
61
|
+
|
62
|
+
after :each do
|
63
|
+
ActiveRecord::Schema.define(:version => 2) do
|
64
|
+
drop_table :comments
|
65
|
+
drop_table :articles
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it_behaves_like 'a document updates outer documents on changed'
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'having articles with comments and delayed jobs' do
|
73
|
+
before(:each) do
|
74
|
+
load 'setup/articles_with_comments_and_delayed_jobs.rb'
|
75
|
+
end
|
76
|
+
|
77
|
+
after :each do
|
78
|
+
ActiveRecord::Schema.define(:version => 2) do
|
79
|
+
drop_table :comments
|
80
|
+
drop_table :articles
|
81
|
+
drop_table :delayed_jobs
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it_behaves_like 'a document updates outer documents on changed'
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
load 'setup/undefine.rb'
|
2
|
+
|
3
|
+
ActiveRecord::Schema.define(:version => 1) do
|
4
|
+
create_table :articles do |t|
|
5
|
+
t.string :title
|
6
|
+
t.datetime :created_at, :default => 'NOW()'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class ::Article < ActiveRecord::Base
|
11
|
+
include Elasticsearch::Model
|
12
|
+
include Elasticsearch::Model::Callbacks
|
13
|
+
|
14
|
+
settings index: {number_of_shards: 1, number_of_replicas: 0} do
|
15
|
+
mapping do
|
16
|
+
indexes :title, type: 'string', analyzer: 'snowball'
|
17
|
+
indexes :created_at, type: 'date'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Article.delete_all
|
23
|
+
Article.__elasticsearch__.create_index! force: true
|
24
|
+
|
25
|
+
::Article.create! title: 'Test'
|
26
|
+
::Article.create! title: 'Testing Coding'
|
27
|
+
::Article.create! title: 'Coding'
|
28
|
+
|
29
|
+
Article.__elasticsearch__.refresh_index!
|
@@ -0,0 +1,90 @@
|
|
1
|
+
load 'setup/undefine.rb'
|
2
|
+
|
3
|
+
require 'elasticsearch/model/extensions/all'
|
4
|
+
require 'elasticsearch/model/extensions/delayed_job'
|
5
|
+
|
6
|
+
ActiveRecord::Schema.define(:version => 1) do
|
7
|
+
create_table :articles do |t|
|
8
|
+
t.string :title
|
9
|
+
t.datetime :created_at, :default => 'NOW()'
|
10
|
+
end
|
11
|
+
|
12
|
+
create_table :comments do |t|
|
13
|
+
t.integer :article_id
|
14
|
+
t.string :body
|
15
|
+
t.datetime :created_at, :default => 'NOW()'
|
16
|
+
end
|
17
|
+
|
18
|
+
create_table :delayed_jobs, :force => true do |table|
|
19
|
+
table.integer :priority, :default => 0
|
20
|
+
table.integer :attempts, :default => 0
|
21
|
+
table.text :handler
|
22
|
+
table.text :last_error
|
23
|
+
table.datetime :run_at
|
24
|
+
table.datetime :locked_at
|
25
|
+
table.datetime :failed_at
|
26
|
+
table.string :locked_by
|
27
|
+
table.string :queue
|
28
|
+
table.timestamps
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
Delayed::Worker.delay_jobs = false
|
33
|
+
|
34
|
+
class ::Article < ActiveRecord::Base
|
35
|
+
has_many :comments
|
36
|
+
|
37
|
+
accepts_nested_attributes_for :comments
|
38
|
+
|
39
|
+
include Elasticsearch::Model
|
40
|
+
include Elasticsearch::Model::Callbacks
|
41
|
+
include Elasticsearch::Model::Extensions::IndexOperations
|
42
|
+
include Elasticsearch::Model::Extensions::BatchUpdating
|
43
|
+
include Elasticsearch::Model::Extensions::PartialUpdating
|
44
|
+
|
45
|
+
DEPENDENT_CUSTOM_ATTRIBUTES = {
|
46
|
+
%w| comments | => %w| num_comments |
|
47
|
+
}
|
48
|
+
|
49
|
+
include Elasticsearch::Model::Extensions::DependencyTracking
|
50
|
+
|
51
|
+
settings index: {number_of_shards: 1, number_of_replicas: 0} do
|
52
|
+
mapping do
|
53
|
+
indexes :title, type: 'string', analyzer: 'snowball'
|
54
|
+
indexes :created_at, type: 'date'
|
55
|
+
indexes :comments, type: 'object' do
|
56
|
+
indexes :body, type: 'string', include_in_all: true
|
57
|
+
end
|
58
|
+
indexes :num_comments, type: 'long'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def num_comments
|
63
|
+
comments.count
|
64
|
+
end
|
65
|
+
|
66
|
+
# Required by Comment's `OuterDocumentUpdating`
|
67
|
+
include Elasticsearch::Model::Extensions::MappingReflection
|
68
|
+
end
|
69
|
+
|
70
|
+
class ::Comment < ActiveRecord::Base
|
71
|
+
include Elasticsearch::Model
|
72
|
+
include Elasticsearch::Model::Callbacks
|
73
|
+
include Elasticsearch::Model::Extensions::IndexOperations
|
74
|
+
include Elasticsearch::Model::Extensions::BatchUpdating
|
75
|
+
include Elasticsearch::Model::Extensions::PartialUpdating
|
76
|
+
include Elasticsearch::Model::Extensions::OuterDocumentUpdating
|
77
|
+
|
78
|
+
partially_updates_document_of ::Article, records_to_update_documents: -> comment { Article.find(comment.article_id) } do |t, changed_fields|
|
79
|
+
Elasticsearch::Model::Extensions::DelayedJob::PartiallyUpdateDocumentJob.new(record: t, changes: changed_fields).enqueue!
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
Article.delete_all
|
84
|
+
Article.__elasticsearch__.create_index! force: true
|
85
|
+
|
86
|
+
::Article.create! title: 'Test'
|
87
|
+
::Article.create! title: 'Testing Coding'
|
88
|
+
::Article.create! title: 'Coding', comments_attributes: [{ body: 'Comment1' }]
|
89
|
+
|
90
|
+
Article.__elasticsearch__.refresh_index!
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elasticsearch-model-extensions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yusuke KUOKA
|
@@ -59,6 +59,11 @@ files:
|
|
59
59
|
- lib/elasticsearch/model/extensions/batch_updating.rb
|
60
60
|
- lib/elasticsearch/model/extensions/callback.rb
|
61
61
|
- lib/elasticsearch/model/extensions/configuration.rb
|
62
|
+
- lib/elasticsearch/model/extensions/delayed_job.rb
|
63
|
+
- lib/elasticsearch/model/extensions/delayed_job/delete_document_job.rb
|
64
|
+
- lib/elasticsearch/model/extensions/delayed_job/document_job.rb
|
65
|
+
- lib/elasticsearch/model/extensions/delayed_job/index_document_job.rb
|
66
|
+
- lib/elasticsearch/model/extensions/delayed_job/partially_update_document_job.rb
|
62
67
|
- lib/elasticsearch/model/extensions/dependency_tracking.rb
|
63
68
|
- lib/elasticsearch/model/extensions/destroy_callback.rb
|
64
69
|
- lib/elasticsearch/model/extensions/index_operations.rb
|
@@ -73,11 +78,14 @@ files:
|
|
73
78
|
- spec/integration_spec.rb
|
74
79
|
- spec/outer_document_updating_spec.rb
|
75
80
|
- spec/partial_updating_spec.rb
|
81
|
+
- spec/setup/articles.rb
|
76
82
|
- spec/setup/articles_with_comments.rb
|
83
|
+
- spec/setup/articles_with_comments_and_delayed_jobs.rb
|
77
84
|
- spec/setup/elasticsearch/model.rb
|
78
85
|
- spec/setup/elasticsearch/start.rb
|
79
86
|
- spec/setup/elasticsearch/stop.rb
|
80
87
|
- spec/setup/sqlite.rb
|
88
|
+
- spec/setup/undefine.rb
|
81
89
|
- spec/spec_helper.rb
|
82
90
|
homepage: https://github.com/crowdworks/elasticsearch-model-extensions
|
83
91
|
licenses:
|
@@ -110,10 +118,12 @@ test_files:
|
|
110
118
|
- spec/integration_spec.rb
|
111
119
|
- spec/outer_document_updating_spec.rb
|
112
120
|
- spec/partial_updating_spec.rb
|
121
|
+
- spec/setup/articles.rb
|
113
122
|
- spec/setup/articles_with_comments.rb
|
123
|
+
- spec/setup/articles_with_comments_and_delayed_jobs.rb
|
114
124
|
- spec/setup/elasticsearch/model.rb
|
115
125
|
- spec/setup/elasticsearch/start.rb
|
116
126
|
- spec/setup/elasticsearch/stop.rb
|
117
127
|
- spec/setup/sqlite.rb
|
128
|
+
- spec/setup/undefine.rb
|
118
129
|
- spec/spec_helper.rb
|
119
|
-
has_rdoc:
|