elasticsearch-model 7.2.0 → 8.0.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/Gemfile +1 -0
- data/README.md +22 -22
- data/Rakefile +7 -6
- data/elasticsearch-model.gemspec +5 -5
- data/examples/activerecord_associations.rb +1 -1
- data/examples/activerecord_custom_analyzer.rb +2 -2
- data/gemfiles/{6.0.gemfile → 6.1.gemfile} +6 -6
- data/gemfiles/{5.0.gemfile → 7.0.gemfile} +8 -7
- data/gemfiles/{3.0.gemfile → 7.1.gemfile} +9 -8
- data/lib/elasticsearch/model/adapter.rb +0 -2
- data/lib/elasticsearch/model/adapters/active_record.rb +0 -4
- data/lib/elasticsearch/model/adapters/default.rb +0 -4
- data/lib/elasticsearch/model/adapters/mongoid.rb +9 -11
- data/lib/elasticsearch/model/adapters/multiple.rb +0 -1
- data/lib/elasticsearch/model/importing.rb +1 -12
- data/lib/elasticsearch/model/indexing.rb +6 -19
- data/lib/elasticsearch/model/multimodel.rb +1 -10
- data/lib/elasticsearch/model/naming.rb +7 -58
- data/lib/elasticsearch/model/proxy.rb +6 -7
- data/lib/elasticsearch/model/response/result.rb +0 -6
- data/lib/elasticsearch/model/searching.rb +2 -3
- data/lib/elasticsearch/model/version.rb +1 -1
- data/lib/elasticsearch/model.rb +6 -3
- data/spec/elasticsearch/model/adapter_spec.rb +0 -11
- data/spec/elasticsearch/model/adapters/active_record/associations_spec.rb +48 -76
- data/spec/elasticsearch/model/adapters/active_record/basic_spec.rb +6 -78
- data/spec/elasticsearch/model/adapters/active_record/import_spec.rb +6 -2
- data/spec/elasticsearch/model/adapters/active_record/namespaced_model_spec.rb +1 -5
- data/spec/elasticsearch/model/adapters/active_record/pagination_spec.rb +0 -8
- data/spec/elasticsearch/model/adapters/active_record/parent_child_spec.rb +1 -4
- data/spec/elasticsearch/model/adapters/active_record/serialization_spec.rb +9 -11
- data/spec/elasticsearch/model/adapters/mongoid_spec.rb +1 -1
- data/spec/elasticsearch/model/adapters/multiple_spec.rb +1 -11
- data/spec/elasticsearch/model/importing_spec.rb +6 -35
- data/spec/elasticsearch/model/indexing_spec.rb +45 -170
- data/spec/elasticsearch/model/module_spec.rb +0 -1
- data/spec/elasticsearch/model/multimodel_spec.rb +2 -8
- data/spec/elasticsearch/model/naming_spec.rb +0 -68
- data/spec/elasticsearch/model/proxy_spec.rb +8 -2
- data/spec/elasticsearch/model/response/aggregations_spec.rb +4 -4
- data/spec/elasticsearch/model/response/base_spec.rb +0 -1
- data/spec/elasticsearch/model/response/pagination/kaminari_spec.rb +3 -4
- data/spec/elasticsearch/model/response/pagination/will_paginate_spec.rb +0 -1
- data/spec/elasticsearch/model/response/records_spec.rb +0 -1
- data/spec/elasticsearch/model/response/response_spec.rb +0 -1
- data/spec/elasticsearch/model/response/result_spec.rb +0 -17
- data/spec/elasticsearch/model/response/results_spec.rb +0 -1
- data/spec/elasticsearch/model/searching_search_request_spec.rb +5 -6
- data/spec/spec_helper.rb +9 -11
- data/spec/support/app/answer.rb +0 -1
- data/spec/support/app/article.rb +0 -2
- data/spec/support/app/article_no_type.rb +1 -1
- data/spec/support/app/namespaced_book.rb +0 -2
- data/spec/support/app/parent_and_child_searchable.rb +6 -4
- data/spec/support/app/question.rb +0 -1
- metadata +15 -16
- data/gemfiles/4.0.gemfile +0 -36
@@ -17,15 +17,10 @@
|
|
17
17
|
|
18
18
|
module Elasticsearch
|
19
19
|
module Model
|
20
|
-
|
21
|
-
# Provides methods for getting and setting index name and document type for the model
|
20
|
+
# Provides methods for getting and setting index and name for the model
|
22
21
|
#
|
23
22
|
module Naming
|
24
|
-
|
25
|
-
DEFAULT_DOC_TYPE = '_doc'.freeze
|
26
|
-
|
27
23
|
module ClassMethods
|
28
|
-
|
29
24
|
# Get or set the name of the index
|
30
25
|
#
|
31
26
|
# @example Set the index name for the `Article` model
|
@@ -64,46 +59,18 @@ module Elasticsearch
|
|
64
59
|
@index_name = name
|
65
60
|
end
|
66
61
|
|
67
|
-
# Get or set the document type
|
68
|
-
#
|
69
|
-
# @example Set the document type for the `Article` model
|
70
|
-
#
|
71
|
-
# class Article
|
72
|
-
# document_type "my-article"
|
73
|
-
# end
|
74
|
-
#
|
75
|
-
# @example Directly set the document type for the `Article` model
|
76
|
-
#
|
77
|
-
# Article.document_type "my-article"
|
78
|
-
#
|
79
|
-
def document_type name=nil
|
80
|
-
@document_type = name || @document_type || implicit(:document_type)
|
81
|
-
end
|
82
|
-
|
83
|
-
|
84
|
-
# Set the document type
|
85
|
-
#
|
86
|
-
# @see document_type
|
87
|
-
#
|
88
|
-
def document_type=(name)
|
89
|
-
@document_type = name
|
90
|
-
end
|
91
|
-
|
92
62
|
private
|
93
63
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
def default_index_name
|
99
|
-
self.model_name.collection.gsub(/\//, '-')
|
100
|
-
end
|
64
|
+
def implicit(prop)
|
65
|
+
self.send("default_#{prop}")
|
66
|
+
end
|
101
67
|
|
102
|
-
|
68
|
+
def default_index_name
|
69
|
+
self.model_name.collection.gsub(/\//, '-')
|
70
|
+
end
|
103
71
|
end
|
104
72
|
|
105
73
|
module InstanceMethods
|
106
|
-
|
107
74
|
# Get or set the index name for the model instance
|
108
75
|
#
|
109
76
|
# @example Set the index name for an instance of the `Article` model
|
@@ -129,25 +96,7 @@ module Elasticsearch
|
|
129
96
|
def index_name=(name)
|
130
97
|
@index_name = name
|
131
98
|
end
|
132
|
-
|
133
|
-
# @example Set the document type for an instance of the `Article` model
|
134
|
-
#
|
135
|
-
# @article.document_type "my-article"
|
136
|
-
# @article.__elasticsearch__.update_document
|
137
|
-
#
|
138
|
-
def document_type name=nil
|
139
|
-
@document_type = name || @document_type || self.class.document_type
|
140
|
-
end
|
141
|
-
|
142
|
-
# Set the document type
|
143
|
-
#
|
144
|
-
# @see document_type
|
145
|
-
#
|
146
|
-
def document_type=(name)
|
147
|
-
@document_type = name
|
148
|
-
end
|
149
99
|
end
|
150
|
-
|
151
100
|
end
|
152
101
|
end
|
153
102
|
end
|
@@ -17,7 +17,6 @@
|
|
17
17
|
|
18
18
|
module Elasticsearch
|
19
19
|
module Model
|
20
|
-
|
21
20
|
# This module provides a proxy interfacing between the including class and
|
22
21
|
# `Elasticsearch::Model`, preventing the pollution of the including class namespace.
|
23
22
|
#
|
@@ -45,7 +44,6 @@ module Elasticsearch
|
|
45
44
|
# # => true
|
46
45
|
#
|
47
46
|
module Proxy
|
48
|
-
|
49
47
|
# Define the `__elasticsearch__` class and instance methods in the including class
|
50
48
|
# and register a callback for intercepting changes in the model.
|
51
49
|
#
|
@@ -53,9 +51,7 @@ module Elasticsearch
|
|
53
51
|
# module and the functionality is accessible via the proxy.
|
54
52
|
#
|
55
53
|
def self.included(base)
|
56
|
-
|
57
54
|
base.class_eval do
|
58
|
-
|
59
55
|
# `ClassMethodsProxy` instance, accessed as `MyModel.__elasticsearch__`
|
60
56
|
def self.__elasticsearch__ &block
|
61
57
|
@__elasticsearch__ ||= ClassMethodsProxy.new(self)
|
@@ -115,15 +111,18 @@ module Elasticsearch
|
|
115
111
|
@target = target
|
116
112
|
end
|
117
113
|
|
118
|
-
|
114
|
+
def self.ruby2_keywords(*) # :nodoc:
|
115
|
+
end if RUBY_VERSION < "2.7"
|
116
|
+
|
117
|
+
# Delegate methods to `@target`. As per [the Ruby 3.0 explanation for keyword arguments](https://www.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-keyword-arguments-in-ruby-3-0/), the only way to work on Ruby <2.7, and 2.7, and 3.0+ is to use `ruby2_keywords`.
|
119
118
|
#
|
120
|
-
def method_missing(method_name, *arguments, &block)
|
119
|
+
ruby2_keywords def method_missing(method_name, *arguments, &block)
|
121
120
|
target.respond_to?(method_name) ? target.__send__(method_name, *arguments, &block) : super
|
122
121
|
end
|
123
122
|
|
124
123
|
# Respond to methods from `@target`
|
125
124
|
#
|
126
|
-
def
|
125
|
+
def respond_to_missing?(method_name, include_private = false)
|
127
126
|
target.respond_to?(method_name) || super
|
128
127
|
end
|
129
128
|
|
@@ -37,7 +37,6 @@ module Elasticsearch
|
|
37
37
|
@options = options
|
38
38
|
|
39
39
|
__index_name = options[:index] || klass.index_name
|
40
|
-
__document_type = options[:type] || klass.document_type
|
41
40
|
|
42
41
|
case
|
43
42
|
# search query: ...
|
@@ -54,9 +53,9 @@ module Elasticsearch
|
|
54
53
|
end
|
55
54
|
|
56
55
|
if body
|
57
|
-
@definition = { index: __index_name,
|
56
|
+
@definition = { index: __index_name, body: body }.update options
|
58
57
|
else
|
59
|
-
@definition = { index: __index_name,
|
58
|
+
@definition = { index: __index_name, q: q }.update options
|
60
59
|
end
|
61
60
|
end
|
62
61
|
|
data/lib/elasticsearch/model.rb
CHANGED
@@ -62,7 +62,6 @@ when defined?(::WillPaginate)
|
|
62
62
|
end
|
63
63
|
|
64
64
|
module Elasticsearch
|
65
|
-
|
66
65
|
# Elasticsearch integration for Ruby models
|
67
66
|
# =========================================
|
68
67
|
#
|
@@ -85,7 +84,7 @@ module Elasticsearch
|
|
85
84
|
# # ...
|
86
85
|
#
|
87
86
|
module Model
|
88
|
-
METHODS = [:search, :mapping, :mappings, :settings, :index_name, :
|
87
|
+
METHODS = [:search, :mapping, :mappings, :settings, :index_name, :import]
|
89
88
|
|
90
89
|
# Adds the `Elasticsearch::Model` functionality to the including class.
|
91
90
|
#
|
@@ -108,12 +107,16 @@ module Elasticsearch
|
|
108
107
|
def self.included(base)
|
109
108
|
base.class_eval do
|
110
109
|
include Elasticsearch::Model::Proxy
|
111
|
-
|
112
110
|
# Delegate common methods to the `__elasticsearch__` ClassMethodsProxy, unless they are defined already
|
113
111
|
class << self
|
114
112
|
METHODS.each do |method|
|
115
113
|
delegate method, to: :__elasticsearch__ unless self.public_instance_methods.include?(method)
|
116
114
|
end
|
115
|
+
|
116
|
+
def inherited(subclass)
|
117
|
+
super
|
118
|
+
Registry.add(subclass) if subclass.is_a?(Class)
|
119
|
+
end
|
117
120
|
end
|
118
121
|
end
|
119
122
|
|
@@ -18,7 +18,6 @@
|
|
18
18
|
require 'spec_helper'
|
19
19
|
|
20
20
|
describe Elasticsearch::Model::Adapter do
|
21
|
-
|
22
21
|
before(:all) do
|
23
22
|
class ::DummyAdapterClass; end
|
24
23
|
class ::DummyAdapterClassWithAdapter; end
|
@@ -37,14 +36,12 @@ describe Elasticsearch::Model::Adapter do
|
|
37
36
|
end
|
38
37
|
|
39
38
|
describe '#from_class' do
|
40
|
-
|
41
39
|
it 'should return an Adapter instance' do
|
42
40
|
expect(Elasticsearch::Model::Adapter.from_class(DummyAdapterClass)).to be_a(Elasticsearch::Model::Adapter::Adapter)
|
43
41
|
end
|
44
42
|
end
|
45
43
|
|
46
44
|
describe 'register' do
|
47
|
-
|
48
45
|
before do
|
49
46
|
expect(Elasticsearch::Model::Adapter::Adapter).to receive(:register).and_call_original
|
50
47
|
Elasticsearch::Model::Adapter.register(:foo, lambda { |c| false })
|
@@ -55,7 +52,6 @@ describe Elasticsearch::Model::Adapter do
|
|
55
52
|
end
|
56
53
|
|
57
54
|
context 'when a specific adapter class is set' do
|
58
|
-
|
59
55
|
before do
|
60
56
|
expect(Elasticsearch::Model::Adapter::Adapter).to receive(:register).and_call_original
|
61
57
|
Elasticsearch::Model::Adapter::Adapter.register(DummyAdapter,
|
@@ -73,7 +69,6 @@ describe Elasticsearch::Model::Adapter do
|
|
73
69
|
end
|
74
70
|
|
75
71
|
describe 'default adapter' do
|
76
|
-
|
77
72
|
let(:adapter) do
|
78
73
|
Elasticsearch::Model::Adapter::Adapter.new(DummyAdapterClass)
|
79
74
|
end
|
@@ -84,11 +79,9 @@ describe Elasticsearch::Model::Adapter do
|
|
84
79
|
end
|
85
80
|
|
86
81
|
describe '#records_mixin' do
|
87
|
-
|
88
82
|
before do
|
89
83
|
Elasticsearch::Model::Adapter::Adapter.register(DummyAdapter,
|
90
84
|
lambda { |c| c == DummyAdapterClassWithAdapter })
|
91
|
-
|
92
85
|
end
|
93
86
|
|
94
87
|
let(:adapter) do
|
@@ -101,11 +94,9 @@ describe Elasticsearch::Model::Adapter do
|
|
101
94
|
end
|
102
95
|
|
103
96
|
describe '#callbacks_mixin' do
|
104
|
-
|
105
97
|
before do
|
106
98
|
Elasticsearch::Model::Adapter::Adapter.register(DummyAdapter,
|
107
99
|
lambda { |c| c == DummyAdapterClassWithAdapter })
|
108
|
-
|
109
100
|
end
|
110
101
|
|
111
102
|
let(:adapter) do
|
@@ -118,11 +109,9 @@ describe Elasticsearch::Model::Adapter do
|
|
118
109
|
end
|
119
110
|
|
120
111
|
describe '#importing_mixin' do
|
121
|
-
|
122
112
|
before do
|
123
113
|
Elasticsearch::Model::Adapter::Adapter.register(DummyAdapter,
|
124
114
|
lambda { |c| c == DummyAdapterClassWithAdapter })
|
125
|
-
|
126
115
|
end
|
127
116
|
|
128
117
|
let(:adapter) do
|
@@ -18,7 +18,6 @@
|
|
18
18
|
require 'spec_helper'
|
19
19
|
|
20
20
|
describe 'Elasticsearch::Model::Adapter::ActiveRecord Associations' do
|
21
|
-
|
22
21
|
before(:all) do
|
23
22
|
ActiveRecord::Schema.define(version: 1) do
|
24
23
|
create_table :categories do |t|
|
@@ -76,7 +75,6 @@ describe 'Elasticsearch::Model::Adapter::ActiveRecord Associations' do
|
|
76
75
|
end
|
77
76
|
|
78
77
|
context 'when a document is created' do
|
79
|
-
|
80
78
|
before do
|
81
79
|
Post.create!(title: 'Test')
|
82
80
|
Post.create!(title: 'Testing Coding')
|
@@ -97,9 +95,7 @@ describe 'Elasticsearch::Model::Adapter::ActiveRecord Associations' do
|
|
97
95
|
end
|
98
96
|
|
99
97
|
describe 'has_many_and_belongs_to association' do
|
100
|
-
|
101
|
-
context 'when an association is updated' do
|
102
|
-
|
98
|
+
context 'when an association is updated' do
|
103
99
|
before do
|
104
100
|
post.categories = [category_a, category_b]
|
105
101
|
Post.__elasticsearch__.refresh_index!
|
@@ -119,20 +115,20 @@ describe 'Elasticsearch::Model::Adapter::ActiveRecord Associations' do
|
|
119
115
|
|
120
116
|
let(:search_result) do
|
121
117
|
Post.search(query: {
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
118
|
+
bool: {
|
119
|
+
must: {
|
120
|
+
multi_match: {
|
121
|
+
fields: ['title'],
|
122
|
+
query: 'first'
|
123
|
+
}
|
124
|
+
},
|
125
|
+
filter: {
|
126
|
+
terms: {
|
127
|
+
categories: ['One']
|
128
|
+
}
|
129
|
+
}
|
130
|
+
}
|
131
|
+
} )
|
136
132
|
end
|
137
133
|
|
138
134
|
it 'applies the update with' do
|
@@ -144,7 +140,6 @@ describe 'Elasticsearch::Model::Adapter::ActiveRecord Associations' do
|
|
144
140
|
end
|
145
141
|
|
146
142
|
context 'when an association is deleted' do
|
147
|
-
|
148
143
|
before do
|
149
144
|
post.categories = [category_a, category_b]
|
150
145
|
post.categories = [category_b]
|
@@ -165,20 +160,20 @@ describe 'Elasticsearch::Model::Adapter::ActiveRecord Associations' do
|
|
165
160
|
|
166
161
|
let(:search_result) do
|
167
162
|
Post.search(query: {
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
163
|
+
bool: {
|
164
|
+
must: {
|
165
|
+
multi_match: {
|
166
|
+
fields: ['title'],
|
167
|
+
query: 'first'
|
168
|
+
}
|
169
|
+
},
|
170
|
+
filter: {
|
171
|
+
terms: {
|
172
|
+
categories: ['One']
|
173
|
+
}
|
174
|
+
}
|
175
|
+
}
|
176
|
+
} )
|
182
177
|
end
|
183
178
|
|
184
179
|
it 'applies the update with a reindex' do
|
@@ -189,9 +184,7 @@ describe 'Elasticsearch::Model::Adapter::ActiveRecord Associations' do
|
|
189
184
|
end
|
190
185
|
|
191
186
|
describe 'has_many through association' do
|
192
|
-
|
193
187
|
context 'when the association is updated' do
|
194
|
-
|
195
188
|
before do
|
196
189
|
author_a = Author.where(first_name: "John", last_name: "Smith").first_or_create!
|
197
190
|
author_b = Author.where(first_name: "Mary", last_name: "Smith").first_or_create!
|
@@ -210,33 +203,17 @@ describe 'Elasticsearch::Model::Adapter::ActiveRecord Associations' do
|
|
210
203
|
Post.__elasticsearch__.refresh_index!
|
211
204
|
end
|
212
205
|
|
213
|
-
|
214
|
-
|
215
|
-
let(:search_result) do
|
216
|
-
Post.search('authors.full_name:john')
|
217
|
-
end
|
218
|
-
|
219
|
-
it 'applies the update', if: active_record_at_least_4? do
|
220
|
-
expect(search_result.results.size).to eq(2)
|
221
|
-
expect(search_result.records.size).to eq(2)
|
222
|
-
end
|
206
|
+
let(:search_result) do
|
207
|
+
Post.search('authors.full_name:john')
|
223
208
|
end
|
224
209
|
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
Post.search('authors.author.full_name:john')
|
229
|
-
end
|
230
|
-
|
231
|
-
it 'applies the update', if: !active_record_at_least_4? do
|
232
|
-
expect(search_result.results.size).to eq(2)
|
233
|
-
expect(search_result.records.size).to eq(2)
|
234
|
-
end
|
210
|
+
it 'applies the update' do
|
211
|
+
expect(search_result.results.size).to eq(2)
|
212
|
+
expect(search_result.records.size).to eq(2)
|
235
213
|
end
|
236
214
|
end
|
237
215
|
|
238
|
-
context 'when an association is added'
|
239
|
-
|
216
|
+
context 'when an association is added' do
|
240
217
|
before do
|
241
218
|
author_a = Author.where(first_name: "John", last_name: "Smith").first_or_create!
|
242
219
|
author_b = Author.where(first_name: "Mary", last_name: "Smith").first_or_create!
|
@@ -262,9 +239,7 @@ describe 'Elasticsearch::Model::Adapter::ActiveRecord Associations' do
|
|
262
239
|
end
|
263
240
|
|
264
241
|
describe 'has_many association' do
|
265
|
-
|
266
|
-
context 'when an association is added', if: active_record_at_least_4? do
|
267
|
-
|
242
|
+
context 'when an association is added' do
|
268
243
|
before do
|
269
244
|
# Create posts
|
270
245
|
post_1 = Post.create!(title: "First Post", text: "This is the first post...")
|
@@ -282,18 +257,18 @@ describe 'Elasticsearch::Model::Adapter::ActiveRecord Associations' do
|
|
282
257
|
|
283
258
|
let(:search_result) do
|
284
259
|
Post.search(query: {
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
260
|
+
nested: {
|
261
|
+
path: 'comments',
|
262
|
+
query: {
|
263
|
+
bool: {
|
264
|
+
must: [
|
265
|
+
{ match: { 'comments.author' => 'john' } },
|
266
|
+
{ match: { 'comments.text' => 'good' } }
|
267
|
+
]
|
268
|
+
}
|
269
|
+
}
|
270
|
+
}
|
271
|
+
})
|
297
272
|
end
|
298
273
|
|
299
274
|
it 'adds the association' do
|
@@ -303,9 +278,7 @@ describe 'Elasticsearch::Model::Adapter::ActiveRecord Associations' do
|
|
303
278
|
end
|
304
279
|
|
305
280
|
describe '#touch' do
|
306
|
-
|
307
281
|
context 'when a touch callback is defined on the model' do
|
308
|
-
|
309
282
|
before do
|
310
283
|
# Create categories
|
311
284
|
category_a = Category.where(title: "One").first_or_create!
|
@@ -329,7 +302,6 @@ describe 'Elasticsearch::Model::Adapter::ActiveRecord Associations' do
|
|
329
302
|
end
|
330
303
|
|
331
304
|
describe '#includes' do
|
332
|
-
|
333
305
|
before do
|
334
306
|
post_1 = Post.create(title: 'One')
|
335
307
|
post_2 = Post.create(title: 'Two')
|