elasticsearch-model 6.0.0 → 6.1.0

Sign up to get free protection for your applications and to get access to all the features.
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