elasticsearch-persistence 5.0.2 → 6.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +5 -5
  2. data/.rspec +2 -0
  3. data/Gemfile +9 -0
  4. data/README.md +206 -338
  5. data/Rakefile +15 -12
  6. data/elasticsearch-persistence.gemspec +6 -7
  7. data/examples/notes/application.rb +3 -4
  8. data/lib/elasticsearch/persistence.rb +2 -110
  9. data/lib/elasticsearch/persistence/repository.rb +212 -53
  10. data/lib/elasticsearch/persistence/repository/dsl.rb +94 -0
  11. data/lib/elasticsearch/persistence/repository/find.rb +27 -10
  12. data/lib/elasticsearch/persistence/repository/response/results.rb +21 -8
  13. data/lib/elasticsearch/persistence/repository/search.rb +30 -18
  14. data/lib/elasticsearch/persistence/repository/serialize.rb +65 -7
  15. data/lib/elasticsearch/persistence/repository/store.rb +38 -44
  16. data/lib/elasticsearch/persistence/version.rb +1 -1
  17. data/spec/repository/find_spec.rb +179 -0
  18. data/spec/repository/response/results_spec.rb +128 -0
  19. data/spec/repository/search_spec.rb +181 -0
  20. data/spec/repository/serialize_spec.rb +53 -0
  21. data/spec/repository/store_spec.rb +327 -0
  22. data/spec/repository_spec.rb +723 -0
  23. data/spec/spec_helper.rb +32 -0
  24. metadata +26 -104
  25. data/examples/music/album.rb +0 -54
  26. data/examples/music/artist.rb +0 -70
  27. data/examples/music/artists/_form.html.erb +0 -8
  28. data/examples/music/artists/artists_controller.rb +0 -67
  29. data/examples/music/artists/artists_controller_test.rb +0 -53
  30. data/examples/music/artists/index.html.erb +0 -60
  31. data/examples/music/artists/show.html.erb +0 -54
  32. data/examples/music/assets/application.css +0 -257
  33. data/examples/music/assets/autocomplete.css +0 -48
  34. data/examples/music/assets/blank_artist.png +0 -0
  35. data/examples/music/assets/blank_cover.png +0 -0
  36. data/examples/music/assets/form.css +0 -113
  37. data/examples/music/index_manager.rb +0 -73
  38. data/examples/music/search/index.html.erb +0 -95
  39. data/examples/music/search/search_controller.rb +0 -41
  40. data/examples/music/search/search_controller_test.rb +0 -12
  41. data/examples/music/search/search_helper.rb +0 -15
  42. data/examples/music/suggester.rb +0 -69
  43. data/examples/music/template.rb +0 -430
  44. data/examples/music/vendor/assets/jquery-ui-1.10.4.custom.min.css +0 -7
  45. data/examples/music/vendor/assets/jquery-ui-1.10.4.custom.min.js +0 -6
  46. data/examples/music/vendor/assets/stylesheets/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  47. data/lib/elasticsearch/persistence/client.rb +0 -51
  48. data/lib/elasticsearch/persistence/model.rb +0 -135
  49. data/lib/elasticsearch/persistence/model/base.rb +0 -87
  50. data/lib/elasticsearch/persistence/model/errors.rb +0 -8
  51. data/lib/elasticsearch/persistence/model/find.rb +0 -180
  52. data/lib/elasticsearch/persistence/model/rails.rb +0 -47
  53. data/lib/elasticsearch/persistence/model/store.rb +0 -254
  54. data/lib/elasticsearch/persistence/model/utils.rb +0 -0
  55. data/lib/elasticsearch/persistence/repository/class.rb +0 -71
  56. data/lib/elasticsearch/persistence/repository/naming.rb +0 -115
  57. data/lib/rails/generators/elasticsearch/model/model_generator.rb +0 -21
  58. data/lib/rails/generators/elasticsearch/model/templates/model.rb.tt +0 -9
  59. data/lib/rails/generators/elasticsearch_generator.rb +0 -2
  60. data/test/integration/model/model_basic_test.rb +0 -233
  61. data/test/integration/repository/custom_class_test.rb +0 -85
  62. data/test/integration/repository/customized_class_test.rb +0 -82
  63. data/test/integration/repository/default_class_test.rb +0 -116
  64. data/test/integration/repository/virtus_model_test.rb +0 -118
  65. data/test/test_helper.rb +0 -55
  66. data/test/unit/model_base_test.rb +0 -72
  67. data/test/unit/model_find_test.rb +0 -153
  68. data/test/unit/model_gateway_test.rb +0 -101
  69. data/test/unit/model_rails_test.rb +0 -112
  70. data/test/unit/model_store_test.rb +0 -576
  71. data/test/unit/persistence_test.rb +0 -32
  72. data/test/unit/repository_class_test.rb +0 -51
  73. data/test/unit/repository_client_test.rb +0 -32
  74. data/test/unit/repository_find_test.rb +0 -388
  75. data/test/unit/repository_indexing_test.rb +0 -37
  76. data/test/unit/repository_module_test.rb +0 -146
  77. data/test/unit/repository_naming_test.rb +0 -146
  78. data/test/unit/repository_response_results_test.rb +0 -98
  79. data/test/unit/repository_search_test.rb +0 -117
  80. data/test/unit/repository_serialize_test.rb +0 -57
  81. data/test/unit/repository_store_test.rb +0 -303
@@ -1,21 +0,0 @@
1
- require "rails/generators/elasticsearch_generator"
2
-
3
- module Elasticsearch
4
- module Generators
5
- class ModelGenerator < ::Rails::Generators::NamedBase
6
- source_root File.expand_path('../templates', __FILE__)
7
-
8
- desc "Creates an Elasticsearch::Persistence model"
9
- argument :attributes, type: :array, default: [], banner: "attribute:type attribute:type"
10
-
11
- check_class_collision
12
-
13
- def create_model_file
14
- @padding = attributes.map { |a| a.name.size }.max
15
- template "model.rb.tt", File.join("app/models", class_path, "#{file_name}.rb")
16
- end
17
-
18
- hook_for :test_framework
19
- end
20
- end
21
- end
@@ -1,9 +0,0 @@
1
- <% module_namespacing do -%>
2
- class <%= class_name %>
3
- include Elasticsearch::Persistence::Model
4
-
5
- <% attributes.each do |attribute| -%>
6
- <%= "attribute :#{attribute.name},".ljust(@padding+12) %> <%= attribute.type %>
7
- <% end -%>
8
- end
9
- <% end -%>
@@ -1,2 +0,0 @@
1
- require "rails/generators/named_base"
2
- require "rails/generators/active_model"
@@ -1,233 +0,0 @@
1
- require 'test_helper'
2
-
3
- require 'elasticsearch/persistence/model'
4
- require 'elasticsearch/persistence/model/rails'
5
-
6
- module Elasticsearch
7
- module Persistence
8
- class PersistenceModelBasicIntegrationTest < Elasticsearch::Test::IntegrationTestCase
9
-
10
- class ::Person
11
- include Elasticsearch::Persistence::Model
12
- include Elasticsearch::Persistence::Model::Rails
13
-
14
- settings index: { number_of_shards: 1 }
15
- document_type 'human_being'
16
-
17
- attribute :name, String,
18
- mapping: { fields: {
19
- name: { type: 'text', analyzer: 'snowball' },
20
- raw: { type: 'keyword' }
21
- } }
22
-
23
- attribute :birthday, Date
24
- attribute :department, String
25
- attribute :salary, Integer
26
- attribute :admin, Boolean, default: false
27
-
28
- validates :name, presence: true
29
- end
30
-
31
- context "A basic persistence model" do
32
- setup do
33
- Person.create_index! force: true
34
- end
35
-
36
- should "save the object with custom ID" do
37
- person = Person.new id: 1, name: 'Number One'
38
- person.save
39
-
40
- document = Person.find(1)
41
- assert_not_nil document
42
- assert_equal 'Number One', document.name
43
- end
44
-
45
- should "create the object with custom ID" do
46
- person = Person.create id: 1, name: 'Number One'
47
-
48
- document = Person.find(1)
49
- assert_not_nil document
50
- assert_equal 'Number One', document.name
51
- end
52
-
53
- should "save and find the object" do
54
- person = Person.new name: 'John Smith', birthday: Date.parse('1970-01-01')
55
- assert person.save
56
-
57
- assert_not_nil person.id
58
- document = Person.find(person.id)
59
-
60
- assert_instance_of Person, document
61
- assert_equal 'John Smith', document.name
62
- assert_equal 'John Smith', Person.find(person.id).name
63
-
64
- assert_not_nil Elasticsearch::Persistence.client.get index: 'people', type: 'human_being', id: person.id
65
- end
66
-
67
- should "not save an invalid object" do
68
- person = Person.new name: nil
69
- assert ! person.save
70
- end
71
-
72
- should "save an invalid object with the :validate option" do
73
- person = Person.new name: nil, salary: 100
74
- assert person.save validate: false
75
-
76
- assert_not_nil person.id
77
- document = Person.find(person.id)
78
- assert_equal 100, document.salary
79
- end
80
-
81
- should "delete the object" do
82
- person = Person.create name: 'John Smith', birthday: Date.parse('1970-01-01')
83
-
84
- person.destroy
85
- assert person.frozen?
86
-
87
- assert_raise Elasticsearch::Transport::Transport::Errors::NotFound do
88
- Elasticsearch::Persistence.client.get index: 'people', type: 'person', id: person.id
89
- end
90
- end
91
-
92
- should "update an object attribute" do
93
- person = Person.create name: 'John Smith'
94
-
95
- person.update name: 'UPDATED'
96
-
97
- assert_equal 'UPDATED', person.name
98
- assert_equal 'UPDATED', Person.find(person.id).name
99
- end
100
-
101
- should "create the model with correct Date form Rails' form attributes" do
102
- params = { "birthday(1i)"=>"2014",
103
- "birthday(2i)"=>"1",
104
- "birthday(3i)"=>"1"
105
- }
106
- person = Person.create params.merge(name: 'TEST')
107
-
108
- assert_equal Date.parse('2014-01-01'), person.birthday
109
- assert_equal Date.parse('2014-01-01'), Person.find(person.id).birthday
110
- end
111
-
112
- should_eventually "update the model with correct Date form Rails' form attributes" do
113
- params = { "birthday(1i)"=>"2014",
114
- "birthday(2i)"=>"1",
115
- "birthday(3i)"=>"1"
116
- }
117
- person = Person.create params.merge(name: 'TEST')
118
-
119
- person.update params.merge('birthday(1i)' => '2015')
120
-
121
- assert_equal Date.parse('2015-01-01'), person.birthday
122
- assert_equal Date.parse('2015-01-01'), Person.find(person.id).birthday
123
- end
124
-
125
- should "increment an object attribute" do
126
- person = Person.create name: 'John Smith', salary: 1_000
127
-
128
- person.increment :salary
129
-
130
- assert_equal 1_001, person.salary
131
- assert_equal 1_001, Person.find(person.id).salary
132
- end
133
-
134
- should "update the object timestamp" do
135
- person = Person.create name: 'John Smith'
136
- updated_at = person.updated_at
137
-
138
- sleep 1
139
- person.touch
140
-
141
- assert person.updated_at > updated_at, [person.updated_at, updated_at].inspect
142
-
143
- found = Person.find(person.id)
144
- assert found.updated_at > updated_at, [found.updated_at, updated_at].inspect
145
- end
146
-
147
- should 'update the object timestamp on save' do
148
- person = Person.create name: 'John Smith'
149
- person.admin = true
150
- sleep 1
151
- person.save
152
-
153
- Person.gateway.refresh_index!
154
-
155
- found = Person.find(person.id)
156
-
157
- # Compare without milliseconds
158
- assert_equal person.updated_at.to_i, found.updated_at.to_i
159
- end
160
-
161
- should "respect the version" do
162
- person = Person.create name: 'John Smith'
163
-
164
- person.update( { name: 'UPDATE 1' })
165
-
166
- assert_raise Elasticsearch::Transport::Transport::Errors::Conflict do
167
- person.update( { name: 'UPDATE 2' }, { version: 1 } )
168
- end
169
- end
170
-
171
- should "find all instances" do
172
- Person.create name: 'John Smith'
173
- Person.create name: 'Mary Smith'
174
- Person.gateway.refresh_index!
175
-
176
- people = Person.all
177
-
178
- assert_equal 2, people.total
179
- assert_equal 2, people.size
180
- end
181
-
182
- should "find instances by search" do
183
- Person.create name: 'John Smith'
184
- Person.create name: 'Mary Smith'
185
- Person.gateway.refresh_index!
186
-
187
- people = Person.search query: { match: { name: 'smith' } },
188
- highlight: { fields: { name: {} } }
189
-
190
- assert_equal 2, people.total
191
- assert_equal 2, people.size
192
-
193
- assert people.map_with_hit { |o,h| h._score }.all? { |s| s > 0 }
194
-
195
- assert_not_nil people.first.hit
196
- assert_match /smith/i, people.first.hit.highlight['name'].first
197
- end
198
-
199
- should "find instances in batches" do
200
- 50.times { |i| Person.create name: "John #{i+1}" }
201
- Person.gateway.refresh_index!
202
-
203
- @batches = 0
204
- @results = []
205
-
206
- Person.find_in_batches(_source_include: 'name') do |batch|
207
- @batches += 1
208
- @results += batch.map(&:name)
209
- end
210
-
211
- assert_equal 3, @batches
212
- assert_equal 50, @results.size
213
- assert_contains @results, 'John 1'
214
- end
215
-
216
- should "find each instance" do
217
- 50.times { |i| Person.create name: "John #{i+1}" }
218
- Person.gateway.refresh_index!
219
-
220
- @results = []
221
-
222
- Person.find_each(_source_include: 'name') do |person|
223
- @results << person.name
224
- end
225
-
226
- assert_equal 50, @results.size
227
- assert_contains @results, 'John 1'
228
- end
229
- end
230
-
231
- end
232
- end
233
- end
@@ -1,85 +0,0 @@
1
- require 'test_helper'
2
-
3
- module Elasticsearch
4
- module Persistence
5
- class RepositoryCustomClassIntegrationTest < Elasticsearch::Test::IntegrationTestCase
6
-
7
- class ::MyNote
8
- attr_reader :attributes
9
-
10
- def initialize(attributes={})
11
- @attributes = Hashie::Mash.new(attributes)
12
- end
13
-
14
- def method_missing(method_name, *arguments, &block)
15
- attributes.respond_to?(method_name) ? attributes.__send__(method_name, *arguments, &block) : super
16
- end
17
-
18
- def respond_to?(method_name, include_private=false)
19
- attributes.respond_to?(method_name) || super
20
- end
21
-
22
- def to_hash
23
- @attributes
24
- end
25
- end
26
-
27
- context "A custom repository class" do
28
- setup do
29
- class ::MyNotesRepository
30
- include Elasticsearch::Persistence::Repository
31
-
32
- klass MyNote
33
-
34
- settings number_of_shards: 1 do
35
- mapping do
36
- indexes :title, analyzer: 'snowball'
37
- end
38
- end
39
-
40
- create_index!
41
-
42
- def deserialize(document)
43
- klass.new document.merge(document['_source'])
44
- end
45
- end
46
-
47
- @repository = MyNotesRepository.new
48
-
49
- @repository.client.cluster.health wait_for_status: 'yellow'
50
- end
51
-
52
- should "save the object under a correct index and type" do
53
- @repository.save MyNote.new(id: '1', title: 'Test')
54
- result = @repository.find(1)
55
-
56
- assert_instance_of MyNote, result
57
- assert_equal 'Test', result.title
58
-
59
- assert_not_nil Elasticsearch::Persistence.client.get index: 'my_notes_repository',
60
- type: 'my_note',
61
- id: '1'
62
- end
63
-
64
- should "delete the object" do
65
- note = MyNote.new id: 1, title: 'Test'
66
- @repository.save note
67
-
68
- assert_not_nil @repository.find(1)
69
-
70
- @repository.delete(note)
71
- assert_raise(Elasticsearch::Persistence::Repository::DocumentNotFound) { @repository.find(1) }
72
- end
73
-
74
- should "retrieve the object via a search query" do
75
- note = MyNote.new title: 'Testing'
76
- @repository.save note, refresh: true
77
-
78
- results = @repository.search query: { match: { title: 'Test' } }
79
- assert_equal 'Testing', results.first.title
80
- end
81
- end
82
-
83
- end
84
- end
85
- end
@@ -1,82 +0,0 @@
1
- require 'test_helper'
2
-
3
- module Elasticsearch
4
- module Persistence
5
- class RepositoryCustomizedClassIntegrationTest < Elasticsearch::Test::IntegrationTestCase
6
-
7
- module ::My
8
- class Note
9
- attr_reader :attributes
10
-
11
- def initialize(attributes={})
12
- @attributes = attributes
13
- end
14
-
15
- def to_hash
16
- @attributes
17
- end
18
- end
19
- end
20
-
21
- context "A custom repository class" do
22
- setup do
23
- @repository = Elasticsearch::Persistence::Repository.new do
24
- index 'my_notes'
25
- type 'my_note'
26
- klass My::Note
27
-
28
- settings number_of_shards: 1 do
29
- mapping do
30
- indexes :title, analyzer: 'snowball'
31
- end
32
- end
33
-
34
- create_index!
35
- end
36
-
37
- @repository.client.cluster.health wait_for_status: 'yellow'
38
- end
39
-
40
- should "save the object under a correct index and type" do
41
- @repository.save My::Note.new(id: '1', title: 'Test')
42
-
43
- assert_instance_of My::Note, @repository.find(1)
44
- assert_not_nil Elasticsearch::Persistence.client.get index: 'my_notes', type: 'my_note', id: '1'
45
- end
46
-
47
- should "update the document" do
48
- @repository.save Note.new(id: 1, title: 'Test')
49
-
50
- @repository.update 1, doc: { title: 'UPDATED' }
51
- assert_equal 'UPDATED', @repository.find(1).attributes['title']
52
- end
53
-
54
- should "update the document with a script" do
55
- @repository.save Note.new(id: 1, title: 'Test')
56
-
57
- @repository.update 1, script: 'ctx._source.title = "UPDATED"'
58
- assert_equal 'UPDATED', @repository.find(1).attributes['title']
59
- end
60
-
61
- should "delete the object" do
62
- note = My::Note.new id: 1, title: 'Test'
63
- @repository.save note
64
-
65
- assert_not_nil @repository.find(1)
66
-
67
- @repository.delete(note)
68
- assert_raise(Elasticsearch::Persistence::Repository::DocumentNotFound) { @repository.find(1) }
69
- end
70
-
71
- should "create the index with correct mapping" do
72
- note = My::Note.new title: 'Testing'
73
- @repository.save note, refresh: true
74
-
75
- results = @repository.search query: { match: { title: 'Test' } }
76
- assert_equal 'Testing', results.first.attributes['title']
77
- end
78
- end
79
-
80
- end
81
- end
82
- end
@@ -1,116 +0,0 @@
1
- require 'test_helper'
2
-
3
- module Elasticsearch
4
- module Persistence
5
- class RepositoryDefaultClassIntegrationTest < Elasticsearch::Test::IntegrationTestCase
6
-
7
- class ::Note
8
- attr_reader :attributes
9
-
10
- def initialize(attributes={})
11
- @attributes = attributes
12
- end
13
-
14
- def to_hash
15
- @attributes
16
- end
17
- end
18
-
19
- context "The default repository class" do
20
- setup do
21
- @repository = Elasticsearch::Persistence::Repository.new
22
- @repository.client.cluster.health wait_for_status: 'yellow'
23
- end
24
-
25
- should "save the object with a custom ID and find it" do
26
- @repository.save Note.new(id: '1', title: 'Test')
27
-
28
- assert_equal 'Test', @repository.find(1).attributes['title']
29
- end
30
-
31
- should "save the object with an auto-generated ID and find it" do
32
- response = @repository.save Note.new(title: 'Test')
33
-
34
- assert_equal 'Test', @repository.find(response['_id']).attributes['title']
35
- end
36
-
37
- should "update the document" do
38
- @repository.save Note.new(id: 1, title: 'Test')
39
-
40
- @repository.update 1, type: 'note', doc: { title: 'UPDATED' }
41
- assert_equal 'UPDATED', @repository.find(1).attributes['title']
42
- end
43
-
44
- should "update the document with a script" do
45
- @repository.save Note.new(id: 1, title: 'Test')
46
-
47
- @repository.update 1, type: 'note', script: 'ctx._source.title = "UPDATED"'
48
- assert_equal 'UPDATED', @repository.find(1).attributes['title']
49
- end
50
-
51
- should "save the document with an upsert" do
52
- @repository.update 1, type: 'note', script: 'ctx._source.clicks += 1', upsert: { clicks: 1 }
53
- assert_equal 1, @repository.find(1).attributes['clicks']
54
- end
55
-
56
- should "delete an object" do
57
- note = Note.new(id: '1', title: 'Test')
58
-
59
- @repository.save(note)
60
- assert_not_nil @repository.find(1)
61
- @repository.delete(note)
62
- assert_raise(Elasticsearch::Persistence::Repository::DocumentNotFound) { @repository.find(1) }
63
- end
64
-
65
- should "find multiple objects" do
66
- (1..5).each { |i| @repository.save Note.new(id: i, title: "Test #{i}") }
67
-
68
- assert_equal 5, @repository.find(1, 2, 3, 4, 5).size
69
- assert_equal 5, @repository.find([1, 2, 3, 4, 5]).size
70
- end
71
-
72
- should "pass options to save and find" do
73
- note = Note.new(id: '1', title: 'Test')
74
- @repository.save note, routing: 'ABC'
75
-
76
- @repository.client.cluster.health level: 'indices', wait_for_status: 'yellow'
77
-
78
- assert_raise Elasticsearch::Persistence::Repository::DocumentNotFound do
79
- @repository.find(1, routing: 'DEF')
80
- end
81
-
82
- assert_nothing_raised do
83
- note = @repository.find(1, routing: 'ABC')
84
- assert_instance_of Note, note
85
- end
86
- end
87
-
88
- should "find notes with full text search" do
89
- @repository.save Note.new(title: 'Test')
90
- @repository.save Note.new(title: 'Test Test')
91
- @repository.save Note.new(title: 'Crust')
92
- @repository.client.indices.refresh index: @repository.index_name
93
-
94
- results = @repository.search 'test'
95
- assert_equal 2, results.size
96
-
97
- results = @repository.search query: { match: { title: 'Test' } }
98
- assert_equal 2, results.size
99
- end
100
-
101
- should "count notes" do
102
- @repository.save Note.new(title: 'Test')
103
- @repository.client.indices.refresh index: @repository.index_name
104
- assert_equal 1, @repository.count
105
- end
106
-
107
- should "save and find a plain hash" do
108
- @repository.save id: 1, title: 'Hash'
109
- result = @repository.find(1)
110
- assert_equal 'Hash', result['_source']['title']
111
- end
112
- end
113
-
114
- end
115
- end
116
- end