elasticsearch-model 6.0.0 → 6.1.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.
Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -0
  3. data/README.md +14 -7
  4. data/Rakefile +27 -36
  5. data/elasticsearch-model.gemspec +1 -1
  6. data/examples/activerecord_mapping_completion.rb +2 -15
  7. data/gemfiles/3.0.gemfile +6 -1
  8. data/gemfiles/4.0.gemfile +7 -1
  9. data/gemfiles/5.0.gemfile +6 -0
  10. data/lib/elasticsearch/model.rb +15 -8
  11. data/lib/elasticsearch/model/adapters/active_record.rb +7 -26
  12. data/lib/elasticsearch/model/indexing.rb +5 -3
  13. data/lib/elasticsearch/model/naming.rb +6 -1
  14. data/lib/elasticsearch/model/response.rb +2 -2
  15. data/lib/elasticsearch/model/response/pagination.rb +2 -192
  16. data/lib/elasticsearch/model/response/pagination/kaminari.rb +109 -0
  17. data/lib/elasticsearch/model/response/pagination/will_paginate.rb +95 -0
  18. data/lib/elasticsearch/model/response/result.rb +1 -1
  19. data/lib/elasticsearch/model/version.rb +1 -1
  20. data/spec/elasticsearch/model/adapter_spec.rb +119 -0
  21. data/spec/elasticsearch/model/adapters/active_record/associations_spec.rb +334 -0
  22. data/spec/elasticsearch/model/adapters/active_record/basic_spec.rb +340 -0
  23. data/spec/elasticsearch/model/adapters/active_record/dynamic_index_name_spec.rb +18 -0
  24. data/spec/elasticsearch/model/adapters/active_record/import_spec.rb +187 -0
  25. data/spec/elasticsearch/model/adapters/active_record/multi_model_spec.rb +110 -0
  26. data/spec/elasticsearch/model/adapters/active_record/namespaced_model_spec.rb +38 -0
  27. data/spec/elasticsearch/model/adapters/active_record/pagination_spec.rb +315 -0
  28. data/spec/elasticsearch/model/adapters/active_record/parent_child_spec.rb +75 -0
  29. data/spec/elasticsearch/model/adapters/active_record/serialization_spec.rb +61 -0
  30. data/spec/elasticsearch/model/adapters/active_record_spec.rb +207 -0
  31. data/spec/elasticsearch/model/adapters/default_spec.rb +41 -0
  32. data/spec/elasticsearch/model/adapters/mongoid/basic_spec.rb +267 -0
  33. data/spec/elasticsearch/model/adapters/mongoid/multi_model_spec.rb +66 -0
  34. data/spec/elasticsearch/model/adapters/mongoid_spec.rb +235 -0
  35. data/spec/elasticsearch/model/adapters/multiple_spec.rb +125 -0
  36. data/spec/elasticsearch/model/callbacks_spec.rb +33 -0
  37. data/spec/elasticsearch/model/client_spec.rb +66 -0
  38. data/spec/elasticsearch/model/hash_wrapper_spec.rb +12 -0
  39. data/spec/elasticsearch/model/importing_spec.rb +214 -0
  40. data/spec/elasticsearch/model/indexing_spec.rb +918 -0
  41. data/spec/elasticsearch/model/module_spec.rb +101 -0
  42. data/spec/elasticsearch/model/multimodel_spec.rb +55 -0
  43. data/spec/elasticsearch/model/naming_inheritance_spec.rb +184 -0
  44. data/spec/elasticsearch/model/naming_spec.rb +186 -0
  45. data/spec/elasticsearch/model/proxy_spec.rb +107 -0
  46. data/spec/elasticsearch/model/response/aggregations_spec.rb +66 -0
  47. data/spec/elasticsearch/model/response/base_spec.rb +90 -0
  48. data/spec/elasticsearch/model/response/pagination/kaminari_spec.rb +410 -0
  49. data/spec/elasticsearch/model/response/pagination/will_paginate_spec.rb +262 -0
  50. data/spec/elasticsearch/model/response/records_spec.rb +118 -0
  51. data/spec/elasticsearch/model/response/response_spec.rb +131 -0
  52. data/spec/elasticsearch/model/response/result_spec.rb +122 -0
  53. data/spec/elasticsearch/model/response/results_spec.rb +56 -0
  54. data/spec/elasticsearch/model/searching_search_request_spec.rb +112 -0
  55. data/spec/elasticsearch/model/searching_spec.rb +49 -0
  56. data/spec/elasticsearch/model/serializing_spec.rb +22 -0
  57. data/spec/spec_helper.rb +161 -0
  58. data/spec/support/app.rb +21 -0
  59. data/spec/support/app/answer.rb +33 -0
  60. data/spec/support/app/article.rb +22 -0
  61. data/spec/support/app/article_for_pagination.rb +12 -0
  62. data/spec/support/app/article_with_custom_serialization.rb +13 -0
  63. data/spec/support/app/article_with_dynamic_index_name.rb +15 -0
  64. data/spec/support/app/author.rb +9 -0
  65. data/spec/support/app/authorship.rb +4 -0
  66. data/spec/support/app/category.rb +3 -0
  67. data/spec/support/app/comment.rb +3 -0
  68. data/spec/support/app/episode.rb +11 -0
  69. data/spec/support/app/image.rb +19 -0
  70. data/spec/support/app/import_article.rb +12 -0
  71. data/spec/support/app/mongoid_article.rb +21 -0
  72. data/spec/support/app/namespaced_book.rb +10 -0
  73. data/spec/support/app/parent_and_child_searchable.rb +24 -0
  74. data/spec/support/app/post.rb +14 -0
  75. data/spec/support/app/question.rb +27 -0
  76. data/spec/support/app/searchable.rb +48 -0
  77. data/spec/support/app/series.rb +11 -0
  78. data/spec/support/model.json +1 -0
  79. data/{test → spec}/support/model.yml +0 -0
  80. metadata +129 -86
  81. data/test/integration/active_record_associations_parent_child_test.rb +0 -188
  82. data/test/integration/active_record_associations_test.rb +0 -339
  83. data/test/integration/active_record_basic_test.rb +0 -255
  84. data/test/integration/active_record_custom_serialization_test.rb +0 -67
  85. data/test/integration/active_record_import_test.rb +0 -168
  86. data/test/integration/active_record_namespaced_model_test.rb +0 -56
  87. data/test/integration/active_record_pagination_test.rb +0 -149
  88. data/test/integration/dynamic_index_name_test.rb +0 -52
  89. data/test/integration/mongoid_basic_test.rb +0 -240
  90. data/test/integration/multiple_models_test.rb +0 -176
  91. data/test/support/model.json +0 -1
  92. data/test/test_helper.rb +0 -92
  93. data/test/unit/adapter_active_record_test.rb +0 -157
  94. data/test/unit/adapter_default_test.rb +0 -41
  95. data/test/unit/adapter_mongoid_test.rb +0 -161
  96. data/test/unit/adapter_multiple_test.rb +0 -106
  97. data/test/unit/adapter_test.rb +0 -69
  98. data/test/unit/callbacks_test.rb +0 -31
  99. data/test/unit/client_test.rb +0 -27
  100. data/test/unit/hash_wrapper_test.rb +0 -13
  101. data/test/unit/importing_test.rb +0 -224
  102. data/test/unit/indexing_test.rb +0 -720
  103. data/test/unit/module_test.rb +0 -68
  104. data/test/unit/multimodel_test.rb +0 -38
  105. data/test/unit/naming_inheritance_test.rb +0 -94
  106. data/test/unit/naming_test.rb +0 -103
  107. data/test/unit/proxy_test.rb +0 -98
  108. data/test/unit/response_aggregations_test.rb +0 -46
  109. data/test/unit/response_base_test.rb +0 -40
  110. data/test/unit/response_pagination_kaminari_test.rb +0 -433
  111. data/test/unit/response_pagination_will_paginate_test.rb +0 -398
  112. data/test/unit/response_records_test.rb +0 -91
  113. data/test/unit/response_result_test.rb +0 -90
  114. data/test/unit/response_results_test.rb +0 -34
  115. data/test/unit/response_test.rb +0 -104
  116. data/test/unit/searching_search_request_test.rb +0 -78
  117. data/test/unit/searching_test.rb +0 -41
  118. data/test/unit/serializing_test.rb +0 -17
@@ -0,0 +1,110 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Elasticsearch::Model::Adapter::ActiveRecord MultiModel' do
4
+
5
+ before(:all) do
6
+ ActiveRecord::Schema.define do
7
+ create_table Episode.table_name do |t|
8
+ t.string :name
9
+ t.datetime :created_at, :default => 'NOW()'
10
+ end
11
+
12
+ create_table Series.table_name do |t|
13
+ t.string :name
14
+ t.datetime :created_at, :default => 'NOW()'
15
+ end
16
+ end
17
+ end
18
+
19
+ before do
20
+ models = [ Episode, Series ]
21
+ clear_tables(models)
22
+ models.each do |model|
23
+ model.__elasticsearch__.create_index! force: true
24
+ model.create name: "The #{model.name}"
25
+ model.create name: "A great #{model.name}"
26
+ model.create name: "The greatest #{model.name}"
27
+ model.__elasticsearch__.refresh_index!
28
+ end
29
+ end
30
+
31
+ after do
32
+ clear_indices(Episode, Series)
33
+ clear_tables(Episode, Series)
34
+ end
35
+
36
+ context 'when the search is across multimodels' do
37
+
38
+ let(:search_result) do
39
+ Elasticsearch::Model.search(%q<"The greatest Episode"^2 OR "The greatest Series">, [Series, Episode])
40
+ end
41
+
42
+ it 'executes the search across models' do
43
+ expect(search_result.results.size).to eq(2)
44
+ expect(search_result.records.size).to eq(2)
45
+ end
46
+
47
+ describe '#results' do
48
+
49
+ it 'returns an instance of Elasticsearch::Model::Response::Result' do
50
+ expect(search_result.results[0]).to be_a(Elasticsearch::Model::Response::Result)
51
+ expect(search_result.results[1]).to be_a(Elasticsearch::Model::Response::Result)
52
+ end
53
+
54
+ it 'returns the correct model instance' do
55
+ expect(search_result.results[0].name).to eq('The greatest Episode')
56
+ expect(search_result.results[1].name).to eq('The greatest Series')
57
+ end
58
+
59
+ it 'provides access to the results' do
60
+ expect(search_result.results[0].name).to eq('The greatest Episode')
61
+ expect(search_result.results[0].name?).to be(true)
62
+ expect(search_result.results[0].boo?).to be(false)
63
+
64
+ expect(search_result.results[1].name).to eq('The greatest Series')
65
+ expect(search_result.results[1].name?).to be(true)
66
+ expect(search_result.results[1].boo?).to be(false)
67
+ end
68
+ end
69
+
70
+ describe '#records' do
71
+
72
+ it 'returns an instance of Elasticsearch::Model::Response::Result' do
73
+ expect(search_result.records[0]).to be_a(Episode)
74
+ expect(search_result.records[1]).to be_a(Series)
75
+ end
76
+
77
+ it 'returns the correct model instance' do
78
+ expect(search_result.records[0].name).to eq('The greatest Episode')
79
+ expect(search_result.records[1].name).to eq('The greatest Series')
80
+ end
81
+
82
+ context 'when the data store is changed' do
83
+
84
+ before do
85
+ Series.find_by_name("The greatest Series").delete
86
+ Series.__elasticsearch__.refresh_index!
87
+ end
88
+
89
+ it 'only returns matching records' do
90
+ expect(search_result.results.size).to eq(2)
91
+ expect(search_result.records.size).to eq(1 )
92
+ expect(search_result.records[0].name).to eq('The greatest Episode')
93
+ end
94
+ end
95
+ end
96
+
97
+ describe 'pagination' do
98
+
99
+ let(:search_result) do
100
+ Elasticsearch::Model.search('series OR episode', [Series, Episode])
101
+ end
102
+
103
+ it 'properly paginates the results' do
104
+ expect(search_result.page(1).per(3).results.size).to eq(3)
105
+ expect(search_result.page(2).per(3).results.size).to eq(3)
106
+ expect(search_result.page(3).per(3).results.size).to eq(0)
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Elasticsearch::Model::Adapter::ActiveRecord Namespaced Model' do
4
+
5
+ before(:all) do
6
+ ActiveRecord::Schema.define(:version => 1) do
7
+ create_table :books do |t|
8
+ t.string :title
9
+ end
10
+ end
11
+
12
+ MyNamespace::Book.delete_all
13
+ MyNamespace::Book.__elasticsearch__.create_index!(force: true)
14
+ MyNamespace::Book.create!(title: 'Test')
15
+ MyNamespace::Book.__elasticsearch__.refresh_index!
16
+ end
17
+
18
+ after do
19
+ clear_indices(MyNamespace::Book)
20
+ clear_tables(MyNamespace::Book)
21
+ end
22
+
23
+ context 'when the model is namespaced' do
24
+
25
+ it 'has the proper index name' do
26
+ expect(MyNamespace::Book.index_name).to eq('my_namespace-books')
27
+ end
28
+
29
+ it 'has the proper document type' do
30
+ expect(MyNamespace::Book.document_type).to eq('book')
31
+ end
32
+
33
+ it 'saves the document into the index' do
34
+ expect(MyNamespace::Book.search('title:test').results.size).to eq(1)
35
+ expect(MyNamespace::Book.search('title:test').results.first.title).to eq('Test')
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,315 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Elasticsearch::Model::Adapter::ActiveRecord Pagination' do
4
+
5
+ before(:all) do
6
+ ActiveRecord::Schema.define(:version => 1) do
7
+ create_table ArticleForPagination.table_name do |t|
8
+ t.string :title
9
+ t.datetime :created_at, :default => 'NOW()'
10
+ t.boolean :published
11
+ end
12
+ end
13
+
14
+ Kaminari::Hooks.init if defined?(Kaminari::Hooks)
15
+
16
+ ArticleForPagination.__elasticsearch__.create_index! force: true
17
+
18
+ 68.times do |i|
19
+ ArticleForPagination.create! title: "Test #{i}", published: (i % 2 == 0)
20
+ end
21
+
22
+ ArticleForPagination.import
23
+ ArticleForPagination.__elasticsearch__.refresh_index!
24
+ end
25
+
26
+ context 'when no other page is specified' do
27
+
28
+ let(:records) do
29
+ ArticleForPagination.search('title:test').page(1).records
30
+ end
31
+
32
+ describe '#size' do
33
+
34
+ it 'returns the correct size' do
35
+ expect(records.size).to eq(25)
36
+ end
37
+ end
38
+
39
+ describe '#current_page' do
40
+
41
+ it 'returns the correct current page' do
42
+ expect(records.current_page).to eq(1)
43
+ end
44
+ end
45
+
46
+ describe '#prev_page' do
47
+
48
+ it 'returns the correct previous page' do
49
+ expect(records.prev_page).to be_nil
50
+ end
51
+ end
52
+
53
+ describe '#next_page' do
54
+
55
+ it 'returns the correct next page' do
56
+ expect(records.next_page).to eq(2)
57
+ end
58
+ end
59
+
60
+ describe '#total_pages' do
61
+
62
+ it 'returns the correct total pages' do
63
+ expect(records.total_pages).to eq(3)
64
+ end
65
+ end
66
+
67
+ describe '#first_page?' do
68
+
69
+ it 'returns the correct first page' do
70
+ expect(records.first_page?).to be(true)
71
+ end
72
+ end
73
+
74
+ describe '#last_page?' do
75
+
76
+ it 'returns the correct last page' do
77
+ expect(records.last_page?).to be(false)
78
+ end
79
+ end
80
+
81
+ describe '#out_of_range?' do
82
+
83
+ it 'returns whether the pagination is out of range' do
84
+ expect(records.out_of_range?).to be(false)
85
+ end
86
+ end
87
+ end
88
+
89
+ context 'when a specific page is specified' do
90
+
91
+ let(:records) do
92
+ ArticleForPagination.search('title:test').page(2).records
93
+ end
94
+
95
+ describe '#size' do
96
+
97
+ it 'returns the correct size' do
98
+ expect(records.size).to eq(25)
99
+ end
100
+ end
101
+
102
+ describe '#current_page' do
103
+
104
+ it 'returns the correct current page' do
105
+ expect(records.current_page).to eq(2)
106
+ end
107
+ end
108
+
109
+ describe '#prev_page' do
110
+
111
+ it 'returns the correct previous page' do
112
+ expect(records.prev_page).to eq(1)
113
+ end
114
+ end
115
+
116
+ describe '#next_page' do
117
+
118
+ it 'returns the correct next page' do
119
+ expect(records.next_page).to eq(3)
120
+ end
121
+ end
122
+
123
+ describe '#total_pages' do
124
+
125
+ it 'returns the correct total pages' do
126
+ expect(records.total_pages).to eq(3)
127
+ end
128
+ end
129
+
130
+ describe '#first_page?' do
131
+
132
+ it 'returns the correct first page' do
133
+ expect(records.first_page?).to be(false)
134
+ end
135
+ end
136
+
137
+ describe '#last_page?' do
138
+
139
+ it 'returns the correct last page' do
140
+ expect(records.last_page?).to be(false)
141
+ end
142
+ end
143
+
144
+ describe '#out_of_range?' do
145
+
146
+ it 'returns whether the pagination is out of range' do
147
+ expect(records.out_of_range?).to be(false)
148
+ end
149
+ end
150
+ end
151
+
152
+ context 'when a the last page is specified' do
153
+
154
+ let(:records) do
155
+ ArticleForPagination.search('title:test').page(3).records
156
+ end
157
+
158
+ describe '#size' do
159
+
160
+ it 'returns the correct size' do
161
+ expect(records.size).to eq(18)
162
+ end
163
+ end
164
+
165
+ describe '#current_page' do
166
+
167
+ it 'returns the correct current page' do
168
+ expect(records.current_page).to eq(3)
169
+ end
170
+ end
171
+
172
+ describe '#prev_page' do
173
+
174
+ it 'returns the correct previous page' do
175
+ expect(records.prev_page).to eq(2)
176
+ end
177
+ end
178
+
179
+ describe '#next_page' do
180
+
181
+ it 'returns the correct next page' do
182
+ expect(records.next_page).to be_nil
183
+ end
184
+ end
185
+
186
+ describe '#total_pages' do
187
+
188
+ it 'returns the correct total pages' do
189
+ expect(records.total_pages).to eq(3)
190
+ end
191
+ end
192
+
193
+ describe '#first_page?' do
194
+
195
+ it 'returns the correct first page' do
196
+ expect(records.first_page?).to be(false)
197
+ end
198
+ end
199
+
200
+ describe '#last_page?' do
201
+
202
+ it 'returns the correct last page' do
203
+ expect(records.last_page?).to be(true)
204
+ end
205
+ end
206
+
207
+ describe '#out_of_range?' do
208
+
209
+ it 'returns whether the pagination is out of range' do
210
+ expect(records.out_of_range?).to be(false)
211
+ end
212
+ end
213
+ end
214
+
215
+ context 'when an invalid page is specified' do
216
+
217
+ let(:records) do
218
+ ArticleForPagination.search('title:test').page(6).records
219
+ end
220
+
221
+ describe '#size' do
222
+
223
+ it 'returns the correct size' do
224
+ expect(records.size).to eq(0)
225
+ end
226
+ end
227
+
228
+ describe '#current_page' do
229
+
230
+ it 'returns the correct current page' do
231
+ expect(records.current_page).to eq(6)
232
+ end
233
+ end
234
+
235
+ describe '#next_page' do
236
+
237
+ it 'returns the correct next page' do
238
+ expect(records.next_page).to be_nil
239
+ end
240
+ end
241
+
242
+ describe '#total_pages' do
243
+
244
+ it 'returns the correct total pages' do
245
+ expect(records.total_pages).to eq(3)
246
+ end
247
+ end
248
+
249
+ describe '#first_page?' do
250
+
251
+ it 'returns the correct first page' do
252
+ expect(records.first_page?).to be(false)
253
+ end
254
+ end
255
+
256
+ describe '#last_page?' do
257
+
258
+ it 'returns whether it is the last page', if: !(Kaminari::VERSION < '1') do
259
+ expect(records.last_page?).to be(false)
260
+ end
261
+
262
+ it 'returns whether it is the last page', if: Kaminari::VERSION < '1' do
263
+ expect(records.last_page?).to be(true) # Kaminari returns current_page >= total_pages in version < 1.0
264
+ end
265
+ end
266
+
267
+ describe '#out_of_range?' do
268
+
269
+ it 'returns whether the pagination is out of range' do
270
+ expect(records.out_of_range?).to be(true)
271
+ end
272
+ end
273
+ end
274
+
275
+ context 'when a scope is also specified' do
276
+
277
+ let(:records) do
278
+ ArticleForPagination.search('title:test').page(2).records.published
279
+ end
280
+
281
+ describe '#size' do
282
+
283
+ it 'returns the correct size' do
284
+ expect(records.size).to eq(12)
285
+ end
286
+ end
287
+ end
288
+
289
+ context 'when a sorting is specified' do
290
+
291
+ let(:search) do
292
+ ArticleForPagination.search({ query: { match: { title: 'test' } }, sort: [ { id: 'desc' } ] })
293
+ end
294
+
295
+ it 'applies the sort' do
296
+ expect(search.page(2).records.first.id).to eq(43)
297
+ expect(search.page(3).records.first.id).to eq(18)
298
+ expect(search.page(2).per(5).records.first.id).to eq(63)
299
+ end
300
+ end
301
+
302
+ context 'when the model has a specific default per page set' do
303
+
304
+ around do |example|
305
+ original_default = ArticleForPagination.instance_variable_get(:@_default_per_page)
306
+ ArticleForPagination.paginates_per 50
307
+ example.run
308
+ ArticleForPagination.paginates_per original_default
309
+ end
310
+
311
+ it 'uses the default per page setting' do
312
+ expect(ArticleForPagination.search('*').page(1).records.size).to eq(50)
313
+ end
314
+ end
315
+ end