elasticsearch_record 1.2.0 → 1.2.1
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/.yardopts +3 -1
- data/Gemfile.lock +4 -1
- data/README.md +7 -1
- data/docs/CHANGELOG.md +7 -0
- data/elasticsearch_record.gemspec +1 -0
- data/lib/active_record/connection_adapters/elasticsearch/schema_statements.rb +25 -3
- data/lib/elasticsearch_record/gem_version.rb +1 -1
- data/lib/elasticsearch_record/relation/core_methods.rb +22 -0
- data/lib/elasticsearch_record/relation/query_methods.rb +31 -16
- data/lib/elasticsearch_record/relation/result_methods.rb +2 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32688db9e3220d919f454f7c4c9445b006d43299d66322f4586af9d426fdc907
|
4
|
+
data.tar.gz: 9169c9110e662d647f7eddeddae7fa3497a03ad36486d85c001e762af5c756df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9221a04be02abcb7d8f36da24f3b7e2d061b778233b8190bb14b906bf54b2a8d881a870f9c0b1b65d90b3ff2418fe8ee21d828b35dceac85b2f8bc766677c73c
|
7
|
+
data.tar.gz: a1b4e64cf4a8c33d8ce3aaeb89fedd5b7847a648a1dcfccc2b15ecfba0f99d0fbf9a0c94237edcd6ef0feb8d4ef40889ab00c2b8a6bc50773b4982cd5e326149
|
data/.yardopts
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
elasticsearch_record (1.2.
|
4
|
+
elasticsearch_record (1.2.1)
|
5
5
|
activerecord (~> 7.0.0)
|
6
6
|
elasticsearch (~> 8.4)
|
7
7
|
|
@@ -56,6 +56,8 @@ GEM
|
|
56
56
|
webrick (1.7.0)
|
57
57
|
yard (0.9.28)
|
58
58
|
webrick (~> 1.7.0)
|
59
|
+
yard-activesupport-concern (0.0.1)
|
60
|
+
yard (>= 0.8)
|
59
61
|
|
60
62
|
PLATFORMS
|
61
63
|
x86_64-linux
|
@@ -65,6 +67,7 @@ DEPENDENCIES
|
|
65
67
|
rake (~> 13.0)
|
66
68
|
rspec (~> 3.0)
|
67
69
|
yard (~> 0.9)
|
70
|
+
yard-activesupport-concern (~> 0.0.1)
|
68
71
|
|
69
72
|
BUNDLED WITH
|
70
73
|
2.3.18
|
data/README.md
CHANGED
@@ -136,7 +136,7 @@ scope.where(kind: :undefined).offset(10).update_all(name: "New Name")
|
|
136
136
|
### Refactored ```where``` method:
|
137
137
|
Different to the default where-method you can now use it in different ways.
|
138
138
|
|
139
|
-
Using it by default with a Hash, the method decides itself to either add a filter, or must_not
|
139
|
+
Using it by default with a Hash, the method decides itself to either add a filter, or must_not clause.
|
140
140
|
|
141
141
|
_Hint: If not provided through ```#kind```-method a default kind **:bool** will be used._
|
142
142
|
```ruby
|
@@ -209,6 +209,8 @@ total = scope.total
|
|
209
209
|
- aggs_only!
|
210
210
|
- total_only!
|
211
211
|
|
212
|
+
_see simple documentation about these methods @ [rubydoc](https://rubydoc.info/gems/elasticsearch_record/ElasticsearchRecord/Relation/QueryMethods)_
|
213
|
+
|
212
214
|
### Available calculation methods
|
213
215
|
- percentiles
|
214
216
|
- percentile_ranks
|
@@ -219,6 +221,8 @@ total = scope.total
|
|
219
221
|
- sum
|
220
222
|
- calculate
|
221
223
|
|
224
|
+
_see simple documentation about these methods @ [rubydoc](https://rubydoc.info/gems/elasticsearch_record/ElasticsearchRecord/Relation/CalculationMethods)_
|
225
|
+
|
222
226
|
### Available result methods
|
223
227
|
- aggregations
|
224
228
|
- buckets
|
@@ -231,6 +235,8 @@ total = scope.total
|
|
231
235
|
- point_in_time
|
232
236
|
- pit_results
|
233
237
|
|
238
|
+
_see simple documentation about these methods @ [rubydoc](https://rubydoc.info/gems/elasticsearch_record/ElasticsearchRecord/Relation/ResultMethods)_
|
239
|
+
|
234
240
|
### Additional methods
|
235
241
|
- to_query
|
236
242
|
|
data/docs/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# ElasticsearchRecord - CHANGELOG
|
2
2
|
|
3
|
+
## [1.2.1] - 2022-12-12
|
4
|
+
* [add] `ActiveRecord::ConnectionAdapters::Elasticsearch::SchemaStatements#access_id_fielddata?` which checks the clusters setting 'indices.id_field_data.enabled' to determinate if a general sorting on the +_id+-field is possible or not.
|
5
|
+
* [add] `ElasticsearchRecord::Relation#ordered_relation` which overwrites the original method to check against the `#access_id_fielddata?` method
|
6
|
+
* [fix] default order by '_id' causes an exception if clusters 'indices.id_field_data.enabled' is disabled
|
7
|
+
* [fix] subfield where-condition `where('field.subfield', 'value')` was transformed into a nested 'join-table' hash
|
8
|
+
* [fix] yardoc docs & generation
|
9
|
+
|
3
10
|
## [1.2.0] - 2022-12-02
|
4
11
|
* [add] `ElasticsearchRecord::SchemaMigration` to fix connection-related differences (like table_name_prefix, table_name_suffix)
|
5
12
|
* [add] connection (config-related) 'table_name_prefix' & 'table_name_suffix' - now will be forwarded to all related models & schema-tables
|
@@ -341,7 +341,7 @@ module ActiveRecord
|
|
341
341
|
end
|
342
342
|
|
343
343
|
# overwrite original methods to provide a elasticsearch version
|
344
|
-
def update_table_definition(name, base = self, **options)
|
344
|
+
def update_table_definition(name, base = self, **options)
|
345
345
|
::ActiveRecord::ConnectionAdapters::Elasticsearch::UpdateTableDefinition.new(base, name, **options)
|
346
346
|
end
|
347
347
|
|
@@ -361,11 +361,26 @@ module ActiveRecord
|
|
361
361
|
table_settings(table_name).dig('index', 'max_result_window').presence || 10000
|
362
362
|
end
|
363
363
|
|
364
|
+
# returns true if the cluster option 'id_field_data' is enabled or not configured.
|
365
|
+
# This is required to check if a general sorting on the +_id+-field is possible or not.
|
366
|
+
# @return [Boolean]
|
367
|
+
def access_id_fielddata?
|
368
|
+
@access_id_fielddata = begin
|
369
|
+
status = self.cluster_settings['indices.id_field_data.enabled']
|
370
|
+
# for cluster version lower 7.6 this might not configured.
|
371
|
+
status = (cluster_info[:version] < "7.6") if status.nil?
|
372
|
+
|
373
|
+
status
|
374
|
+
end if @access_id_fielddata.nil?
|
375
|
+
|
376
|
+
@access_id_fielddata
|
377
|
+
end
|
378
|
+
|
364
379
|
# Returns basic information about the cluster.
|
365
380
|
# @return [Hash{Symbol->Unknown}]
|
366
381
|
def cluster_info
|
367
382
|
@cluster_info ||= begin
|
368
|
-
response = api(:core, :info, {}, 'CLUSTER')
|
383
|
+
response = api(:core, :info, {}, 'CLUSTER INFO')
|
369
384
|
|
370
385
|
{
|
371
386
|
name: response.dig('name'),
|
@@ -377,9 +392,16 @@ module ActiveRecord
|
|
377
392
|
end
|
378
393
|
end
|
379
394
|
|
395
|
+
# returns a hash of current set, none-default settings in flat
|
396
|
+
# @return [Hash]
|
397
|
+
def cluster_settings
|
398
|
+
settings = api(:cluster, :get_settings, { flat_settings: true }, 'CLUSTER SETTINGS')
|
399
|
+
settings['persistent'].merge(settings['transient'])
|
400
|
+
end
|
401
|
+
|
380
402
|
# transforms provided schema-type to a sql-type
|
403
|
+
# overwrite original methods to provide a elasticsearch version
|
381
404
|
# @param [String, Symbol] type
|
382
|
-
# @param [String]
|
383
405
|
def type_to_sql(type, **)
|
384
406
|
return '' if type.blank?
|
385
407
|
|
@@ -95,6 +95,28 @@ module ElasticsearchRecord
|
|
95
95
|
responses
|
96
96
|
end
|
97
97
|
end
|
98
|
+
|
99
|
+
# overwrite original methods to provide a elasticsearch version:
|
100
|
+
# checks against the +#access_id_fielddata?+ to ensure the Elasticsearch Cluster allows access on the +_id+ field.
|
101
|
+
def ordered_relation
|
102
|
+
# resolve valid primary_key (either not the '_id' or +access_id_fielddata?+ is enabled)
|
103
|
+
valid_primary_key = if primary_key != '_id' || klass.connection.access_id_fielddata?
|
104
|
+
primary_key
|
105
|
+
else
|
106
|
+
nil
|
107
|
+
end
|
108
|
+
|
109
|
+
# slightly changed original methods content
|
110
|
+
if order_values.empty? && (implicit_order_column || valid_primary_key)
|
111
|
+
if implicit_order_column && valid_primary_key && implicit_order_column != valid_primary_key
|
112
|
+
order(table[implicit_order_column].asc, table[valid_primary_key].asc)
|
113
|
+
else
|
114
|
+
order(table[implicit_order_column || valid_primary_key].asc)
|
115
|
+
end
|
116
|
+
else
|
117
|
+
self
|
118
|
+
end
|
119
|
+
end
|
98
120
|
end
|
99
121
|
end
|
100
122
|
end
|
@@ -14,7 +14,7 @@ module ElasticsearchRecord
|
|
14
14
|
|
15
15
|
# sets or overwrites the query kind (e.g. compound queries -> :bool, :boosting, :constant_score, ...).
|
16
16
|
# Also other query kinds like :intervals, :match, ... are allowed.
|
17
|
-
#
|
17
|
+
# Alternatively the +#query+-method can also be used to provide a kind with arguments.
|
18
18
|
# @param [String, Symbol] value - the kind
|
19
19
|
def kind(value)
|
20
20
|
spawn.kind!(value)
|
@@ -59,6 +59,9 @@ module ElasticsearchRecord
|
|
59
59
|
self
|
60
60
|
end
|
61
61
|
|
62
|
+
# create or add an aggregation to the query.
|
63
|
+
# @example
|
64
|
+
# aggregate(:total, { sum: {field: :amount})
|
62
65
|
def aggregate(*args)
|
63
66
|
check_if_method_has_arguments!(__callee__, args)
|
64
67
|
spawn.aggregate!(*args)
|
@@ -66,7 +69,7 @@ module ElasticsearchRecord
|
|
66
69
|
|
67
70
|
alias_method :aggs, :aggregate
|
68
71
|
|
69
|
-
def aggregate!(opts, *rest)
|
72
|
+
def aggregate!(opts, *rest) # :nodoc:
|
70
73
|
case opts
|
71
74
|
when Symbol, String
|
72
75
|
self.aggs_clause += build_query_clause(opts, rest)
|
@@ -81,60 +84,71 @@ module ElasticsearchRecord
|
|
81
84
|
self
|
82
85
|
end
|
83
86
|
|
87
|
+
# add a whole query 'node' to the query.
|
88
|
+
# @example
|
89
|
+
# query(:bool, {filter: ...})
|
84
90
|
def query(*args)
|
85
91
|
check_if_method_has_arguments!(__callee__, args)
|
86
92
|
spawn.query!(*args)
|
87
93
|
end
|
88
94
|
|
89
|
-
def query!(kind, opts, *rest)
|
95
|
+
def query!(kind, opts, *rest) # :nodoc:
|
90
96
|
kind!(kind)
|
91
97
|
self.query_clause += build_query_clause(opts.keys[0], opts.values[0], rest)
|
92
98
|
self
|
93
99
|
end
|
94
100
|
|
101
|
+
# adds a +filter+ clause.
|
102
|
+
# @example
|
103
|
+
# filter({terms: ...})
|
95
104
|
def filter(*args)
|
96
105
|
check_if_method_has_arguments!(__callee__, args)
|
97
106
|
spawn.filter!(*args)
|
98
107
|
end
|
99
108
|
|
100
|
-
def filter!(opts, *rest)
|
101
|
-
# :nodoc:
|
109
|
+
def filter!(opts, *rest) # :nodoc:
|
102
110
|
set_default_kind!
|
103
111
|
self.query_clause += build_query_clause(:filter, opts, rest)
|
104
112
|
self
|
105
113
|
end
|
106
114
|
|
115
|
+
# adds a +must_not+ clause.
|
116
|
+
# @example
|
117
|
+
# filter({terms: ...})
|
107
118
|
def must_not(*args)
|
108
119
|
check_if_method_has_arguments!(__callee__, args)
|
109
120
|
spawn.must_not!(*args)
|
110
121
|
end
|
111
122
|
|
112
|
-
def must_not!(opts, *rest)
|
113
|
-
# :nodoc:
|
123
|
+
def must_not!(opts, *rest) # :nodoc:
|
114
124
|
set_default_kind!
|
115
125
|
self.query_clause += build_query_clause(:must_not, opts, rest)
|
116
126
|
self
|
117
127
|
end
|
118
128
|
|
129
|
+
# adds a +must+ clause.
|
130
|
+
# @example
|
131
|
+
# must({terms: ...})
|
119
132
|
def must(*args)
|
120
133
|
check_if_method_has_arguments!(__callee__, args)
|
121
134
|
spawn.must!(*args)
|
122
135
|
end
|
123
136
|
|
124
|
-
def must!(opts, *rest)
|
125
|
-
# :nodoc:
|
137
|
+
def must!(opts, *rest) # :nodoc:
|
126
138
|
set_default_kind!
|
127
139
|
self.query_clause += build_query_clause(:must, opts, rest)
|
128
140
|
self
|
129
141
|
end
|
130
142
|
|
143
|
+
# adds a +should+ clause.
|
144
|
+
# @example
|
145
|
+
# should({terms: ...})
|
131
146
|
def should(*args)
|
132
147
|
check_if_method_has_arguments!(__callee__, args)
|
133
148
|
spawn.should!(*args)
|
134
149
|
end
|
135
150
|
|
136
|
-
def should!(opts, *rest)
|
137
|
-
# :nodoc:
|
151
|
+
def should!(opts, *rest) # :nodoc:
|
138
152
|
set_default_kind!
|
139
153
|
self.query_clause += build_query_clause(:should, opts, rest)
|
140
154
|
self
|
@@ -142,7 +156,7 @@ module ElasticsearchRecord
|
|
142
156
|
|
143
157
|
# creates a condition on the relation.
|
144
158
|
# There are several possibilities to call this method.
|
145
|
-
#
|
159
|
+
# @example
|
146
160
|
# # create a simple 'term' condition on the query[:filter] param
|
147
161
|
# where({name: 'hans'})
|
148
162
|
# > query[:filter] << { term: { name: 'hans' } }
|
@@ -162,7 +176,7 @@ module ElasticsearchRecord
|
|
162
176
|
super
|
163
177
|
end
|
164
178
|
|
165
|
-
def where!(opts, *rest)
|
179
|
+
def where!(opts, *rest) # :nodoc:
|
166
180
|
case opts
|
167
181
|
# check the first provided parameter +opts+ and validate, if this is an alias for "must, must_not, should or filter"
|
168
182
|
# if true, we expect the rest[0] to be a hash.
|
@@ -209,12 +223,13 @@ module ElasticsearchRecord
|
|
209
223
|
)
|
210
224
|
end
|
211
225
|
|
212
|
-
# force set default kind
|
226
|
+
# force set default kind, if not previously set
|
213
227
|
set_default_kind!
|
214
228
|
|
215
229
|
# builds predicates from opts (transforms this in a more unreadable way but is required for nested assignment & binds ...)
|
216
|
-
parts =
|
217
|
-
|
230
|
+
parts = opts.map do |key,value|
|
231
|
+
# builds and returns a new Arel Node from provided key/value pair
|
232
|
+
predicate_builder[key,value]
|
218
233
|
end
|
219
234
|
|
220
235
|
self.where_clause += ::ActiveRecord::Relation::WhereClause.new(parts)
|
@@ -4,6 +4,7 @@ module ElasticsearchRecord
|
|
4
4
|
# aggregate pluck provided columns.
|
5
5
|
# returns a hash of values for each provided column
|
6
6
|
#
|
7
|
+
# @example
|
7
8
|
# Person.agg_pluck(:name)
|
8
9
|
# #> {"name" => ['David', 'Jeremy', 'Jose']}
|
9
10
|
#
|
@@ -32,6 +33,7 @@ module ElasticsearchRecord
|
|
32
33
|
# For a single column_name a hash with the distinct key and the +doc_count+ as value is returned.
|
33
34
|
# For multiple column_names a hash with the distinct keys (as hash) and the +doc_count+ as value is returned.
|
34
35
|
#
|
36
|
+
# @example
|
35
37
|
# Person.composite(:name)
|
36
38
|
# #> {"David" => 10, "Jeremy" => 1, "Jose" => 24}
|
37
39
|
#
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elasticsearch_record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tobias Gonsior
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-12-
|
11
|
+
date: 2022-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0.9'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: yard-activesupport-concern
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.0.1
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.0.1
|
83
97
|
description: 'ElasticsearchRecord is a ActiveRecord adapter and provides similar functionality
|
84
98
|
for Elasticsearch.
|
85
99
|
|