elasticsearch_record 1.6.0 → 1.7.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 +1 -1
- data/README.md +56 -8
- data/docs/CHANGELOG.md +15 -0
- data/docs/{LICENSE.txt → LICENSE} +1 -1
- data/lib/active_record/connection_adapters/elasticsearch_adapter.rb +1 -1
- data/lib/elasticsearch_record/gem_version.rb +2 -2
- data/lib/elasticsearch_record/query.rb +11 -3
- data/lib/elasticsearch_record/querying.rb +36 -1
- data/lib/elasticsearch_record/relation/calculation_methods.rb +132 -13
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52f19a4a5802d333a04d2c72e4a7a51c3f0bfc501c0b8b379e6afb44d1076aca
|
4
|
+
data.tar.gz: ac2eb76b596b4705feac42612fb0e11d530f684750ee780471c765172a69ea7f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 68b0cc2c384b7751c271aa1d3f8b37af778d20af1ca6e42a967b97454ab2121a0606150977690a9153b58567d2172c5e08cfe2adbf7578e3051c60edf0c4a1a4
|
7
|
+
data.tar.gz: bf240b8ccd09364d6237900854c824080068cd6822400f7538dabedd85491cb64dbe45b86725aa353fe9fc598e4e2d4837935775e132af11215ea767daf2b7e1
|
data/.yardopts
CHANGED
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
[](http://rubydoc.info/gems/elasticsearch_record)
|
5
5
|
|
6
6
|
[](https://badge.fury.io/rb/elasticsearch_record)
|
7
|
-
[](docs/LICENSE
|
7
|
+
[](docs/LICENSE)
|
8
8
|
|
9
9
|
ActiveRecord adapter for Elasticsearch
|
10
10
|
|
@@ -14,8 +14,28 @@ _ElasticsearchRecord is a ActiveRecord adapter and provides similar functionalit
|
|
14
14
|
|
15
15
|
**PLEASE NOTE:**
|
16
16
|
|
17
|
-
-
|
18
|
-
-
|
17
|
+
- This is the `rails-7-0-stable`-branch, which only supports rails **7.0** _(see section 'Rails_Versions' for supported versions)_
|
18
|
+
- supports ActiveRecord ~> 7.0 + Elasticsearch >= 7.17
|
19
|
+
|
20
|
+
-----
|
21
|
+
|
22
|
+
## Rails versions
|
23
|
+
|
24
|
+
Supported rails versions:
|
25
|
+
|
26
|
+
### Rails 7.1:
|
27
|
+
_(since gem version 1.8)_
|
28
|
+
|
29
|
+
https://github.com/ruby-smart/elasticsearch_record/tree/rails-7-1-stable
|
30
|
+
|
31
|
+
[](https://github.com/ruby-smart/elasticsearch_record/tree/rails-7-1-stable)
|
32
|
+
|
33
|
+
### Rails 7.0:
|
34
|
+
_(until gem version 1.7)_
|
35
|
+
|
36
|
+
https://github.com/ruby-smart/elasticsearch_record/tree/rails-7-0-stable
|
37
|
+
|
38
|
+
[](https://github.com/ruby-smart/elasticsearch_record/tree/rails-7-0-stable)
|
19
39
|
|
20
40
|
-----
|
21
41
|
|
@@ -24,7 +44,11 @@ _ElasticsearchRecord is a ActiveRecord adapter and provides similar functionalit
|
|
24
44
|
Add this line to your application's Gemfile:
|
25
45
|
|
26
46
|
```ruby
|
27
|
-
gem 'elasticsearch_record'
|
47
|
+
gem 'elasticsearch_record', '~> 1.7'
|
48
|
+
|
49
|
+
# alternative
|
50
|
+
gem 'elasticsearch_record', git: 'https://github.com/ruby-smart/elasticsearch_record', branch: 'rails-7-0-stable'
|
51
|
+
|
28
52
|
```
|
29
53
|
|
30
54
|
And then execute:
|
@@ -235,6 +259,19 @@ total = scope.total
|
|
235
259
|
# > 3335
|
236
260
|
```
|
237
261
|
|
262
|
+
### Available core query methods
|
263
|
+
|
264
|
+
- find_by_sql
|
265
|
+
- find_by_query
|
266
|
+
- find_by_esql
|
267
|
+
- esql
|
268
|
+
- msearch
|
269
|
+
- search
|
270
|
+
|
271
|
+
_see simple documentation about these methods @ {ElasticsearchRecord::Querying rubydoc}_
|
272
|
+
|
273
|
+
_(also see @ [github](https://github.com/ruby-smart/elasticsearch_record/blob/main/lib/elasticsearch_record/querying.rb) )_
|
274
|
+
|
238
275
|
### Available query/relation chain methods
|
239
276
|
- kind
|
240
277
|
- configure
|
@@ -252,7 +289,9 @@ total = scope.total
|
|
252
289
|
- aggs_only!
|
253
290
|
- total_only!
|
254
291
|
|
255
|
-
_see simple documentation about these methods @
|
292
|
+
_see simple documentation about these methods @ {ElasticsearchRecord::Relation::QueryMethods rubydoc}_
|
293
|
+
|
294
|
+
_(also see @ [github](https://github.com/ruby-smart/elasticsearch_record/blob/main/lib/elasticsearch_record/relation/query_methods.rb) )_
|
256
295
|
|
257
296
|
### Available calculation methods
|
258
297
|
- percentiles
|
@@ -262,9 +301,16 @@ _see simple documentation about these methods @ [rubydoc](https://rubydoc.info/g
|
|
262
301
|
- minimum
|
263
302
|
- maximum
|
264
303
|
- sum
|
304
|
+
- boxplot
|
305
|
+
- stats
|
306
|
+
- string_stats
|
307
|
+
- matrix_stats
|
308
|
+
- median_absolute_deviation
|
265
309
|
- calculate
|
266
310
|
|
267
|
-
_see simple documentation about these methods @
|
311
|
+
_see simple documentation about these methods @ {ElasticsearchRecord::Relation::CalculationMethods rubydoc}_
|
312
|
+
|
313
|
+
_(also see @ [github](https://github.com/ruby-smart/elasticsearch_record/blob/main/lib/elasticsearch_record/relation/calculation_methods.rb) )_
|
268
314
|
|
269
315
|
### Available result methods
|
270
316
|
- aggregations
|
@@ -279,7 +325,9 @@ _see simple documentation about these methods @ [rubydoc](https://rubydoc.info/g
|
|
279
325
|
- pit_results
|
280
326
|
- pit_delete
|
281
327
|
|
282
|
-
_see simple documentation about these methods @
|
328
|
+
_see simple documentation about these methods @ {ElasticsearchRecord::Relation::ResultMethods rubydoc}_
|
329
|
+
|
330
|
+
_(also see @ [github](https://github.com/ruby-smart/elasticsearch_record/blob/main/lib/elasticsearch_record/relation/result_methods.rb) )_
|
283
331
|
|
284
332
|
### Additional methods
|
285
333
|
- to_query
|
@@ -620,7 +668,7 @@ This project is intended to be a safe, welcoming space for collaboration, and co
|
|
620
668
|
|
621
669
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
622
670
|
|
623
|
-
A copy of the [LICENSE](docs/LICENSE
|
671
|
+
A copy of the [LICENSE](docs/LICENSE) can be found @ the docs.
|
624
672
|
|
625
673
|
## Code of Conduct
|
626
674
|
|
data/docs/CHANGELOG.md
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
# ElasticsearchRecord - CHANGELOG
|
2
2
|
|
3
|
+
## [1.7.1] - 2024-01-09
|
4
|
+
* [fix] `ElasticsearchRecord::Relation` calculation methods return with different nodes
|
5
|
+
* [ref] `ElasticsearchRecord::Relation#calculate` removes default value of `node`
|
6
|
+
* [ref] `ActiveRecord::ConnectionAdapters::ElasticsearchAdapter#api` prevents inaccurate variable interpretation of `log`
|
7
|
+
|
8
|
+
## [1.7.0] - 2024-01-09
|
9
|
+
* [add] `ElasticsearchRecord::Relation#boxplot` calculation method
|
10
|
+
* [add] `ElasticsearchRecord::Relation#stats` calculation method
|
11
|
+
* [add] `ElasticsearchRecord::Relation#string_stats` calculation method
|
12
|
+
* [add] `ElasticsearchRecord::Relation#matrix_stats` calculation method
|
13
|
+
* [add] `ElasticsearchRecord::Relation#median_absolute_deviation` calculation method
|
14
|
+
* [add] `ElasticsearchRecord::Base#esql` + `ElasticsearchRecord::Base#find_by_esql` to support `ES|QL` queries
|
15
|
+
* [add] new repository branch `rails-7-0-stable` to support different rails versions
|
16
|
+
* [ref] minor code optimizations & documentation changes
|
17
|
+
|
3
18
|
## [1.6.0] - 2023-08-11
|
4
19
|
* [add] `ElasticsearchRecord::Base#undelegate_id_attribute_with` method to support a temporary 'undelegation' (used to create a new record)
|
5
20
|
* [add] `ElasticsearchRecord::Relation#timeout` to directly provide the timeout-parameter to the query
|
@@ -238,7 +238,7 @@ module ActiveRecord # :nodoc:
|
|
238
238
|
# resolve the API target
|
239
239
|
target = namespace == :core ? @connection : @connection.__send__(namespace)
|
240
240
|
|
241
|
-
log
|
241
|
+
__send__(:log, "#{namespace}.#{action}", arguments, name, async: async, log: log) do
|
242
242
|
response = ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
|
243
243
|
target.__send__(action, arguments)
|
244
244
|
end
|
@@ -12,6 +12,7 @@ module ElasticsearchRecord
|
|
12
12
|
TYPE_SEARCH = :search
|
13
13
|
TYPE_MSEARCH = :msearch
|
14
14
|
TYPE_SQL = :sql
|
15
|
+
TYPE_ESQL = :esql
|
15
16
|
|
16
17
|
# -- DOCUMENT TYPES ------------------------------------------------------------------------------------------------
|
17
18
|
TYPE_CREATE = :create
|
@@ -34,7 +35,7 @@ module ElasticsearchRecord
|
|
34
35
|
# includes valid types only
|
35
36
|
TYPES = [
|
36
37
|
# -- QUERY TYPES
|
37
|
-
TYPE_COUNT, TYPE_SEARCH, TYPE_MSEARCH, TYPE_SQL,
|
38
|
+
TYPE_COUNT, TYPE_SEARCH, TYPE_MSEARCH, TYPE_SQL, TYPE_ESQL,
|
38
39
|
# -- DOCUMENT TYPES
|
39
40
|
TYPE_CREATE, TYPE_UPDATE, TYPE_UPDATE_BY_QUERY, TYPE_DELETE, TYPE_DELETE_BY_QUERY,
|
40
41
|
|
@@ -46,7 +47,7 @@ module ElasticsearchRecord
|
|
46
47
|
|
47
48
|
# includes reading types only
|
48
49
|
READ_TYPES = [
|
49
|
-
TYPE_COUNT, TYPE_SEARCH, TYPE_MSEARCH, TYPE_SQL
|
50
|
+
TYPE_COUNT, TYPE_SEARCH, TYPE_MSEARCH, TYPE_SQL, TYPE_ESQL
|
50
51
|
].freeze
|
51
52
|
|
52
53
|
# defines a body to be executed if the query fails - +(none)+
|
@@ -60,6 +61,7 @@ module ElasticsearchRecord
|
|
60
61
|
# if no special type is defined, it simply uses +[:core,self.type]+
|
61
62
|
GATES = {
|
62
63
|
TYPE_SQL => [:sql, :query],
|
64
|
+
TYPE_ESQL => [:esql, :query],
|
63
65
|
TYPE_INDEX_CREATE => [:indices, :create],
|
64
66
|
TYPE_INDEX_CLONE => [:indices, :clone],
|
65
67
|
TYPE_INDEX_UPDATE_MAPPING => [:indices, :put_mapping],
|
@@ -118,6 +120,12 @@ module ElasticsearchRecord
|
|
118
120
|
self
|
119
121
|
end
|
120
122
|
|
123
|
+
# returns true, if the query failed
|
124
|
+
# @return [Boolean]
|
125
|
+
def failed?
|
126
|
+
self.status == STATUS_FAILED
|
127
|
+
end
|
128
|
+
|
121
129
|
# returns true, if the query is valid (e.g. index & type defined)
|
122
130
|
# @return [Boolean]
|
123
131
|
def valid?
|
@@ -143,7 +151,7 @@ module ElasticsearchRecord
|
|
143
151
|
# failed queried will return the related +FAILED_BODIES+ or +{}+ as fallback
|
144
152
|
# @return [Hash, nil]
|
145
153
|
def body
|
146
|
-
return (FAILED_BODIES[self.type].presence || {}) if
|
154
|
+
return (FAILED_BODIES[self.type].presence || {}) if failed?
|
147
155
|
|
148
156
|
@body
|
149
157
|
end
|
@@ -77,7 +77,42 @@ module ElasticsearchRecord
|
|
77
77
|
_load_from_sql(_query_by_sql(query), &block)
|
78
78
|
end
|
79
79
|
|
80
|
-
#
|
80
|
+
# ES|QL query API
|
81
|
+
# Returns search results for an ES|QL (Elasticsearch query language) query.
|
82
|
+
#
|
83
|
+
# @param [String] esql
|
84
|
+
# @param [Proc] block
|
85
|
+
def find_by_esql(esql, &block)
|
86
|
+
# build new query
|
87
|
+
query = ElasticsearchRecord::Query.new(
|
88
|
+
type: ElasticsearchRecord::Query::TYPE_ESQL,
|
89
|
+
body: { query: esql },
|
90
|
+
# IMPORTANT: Always provide all columns
|
91
|
+
columns: source_column_names)
|
92
|
+
|
93
|
+
_load_from_sql(_query_by_sql(query), &block)
|
94
|
+
end
|
95
|
+
|
96
|
+
# executes a +esql+ by provided *ES|SL* query
|
97
|
+
# Does NOT instantiate records.
|
98
|
+
# @param [String] esql
|
99
|
+
# @param [Boolean] async (default: false)
|
100
|
+
def esql(esql, async: false)
|
101
|
+
# build new query
|
102
|
+
query = ElasticsearchRecord::Query.new(
|
103
|
+
type: ElasticsearchRecord::Query::TYPE_ESQL,
|
104
|
+
body: { query: esql },
|
105
|
+
# IMPORTANT: Always provide all columns
|
106
|
+
columns: source_column_names)
|
107
|
+
|
108
|
+
connection.exec_query(query, "#{name} ES|QL", async: async)
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
# executes a +msearch+ by provided *RAW* queries.
|
113
|
+
# Does NOT instantiate records.
|
114
|
+
# @param [Array<String>] queries
|
115
|
+
# @param [Boolean] async (default: false)
|
81
116
|
def msearch(queries, async: false)
|
82
117
|
# build new msearch query
|
83
118
|
query = ElasticsearchRecord::Query.new(
|
@@ -45,6 +45,84 @@ module ElasticsearchRecord
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
+
# A boxplot metrics aggregation that computes boxplot of numeric values extracted from the aggregated documents.
|
49
|
+
# These values can be generated from specific numeric or histogram fields in the documents.
|
50
|
+
#
|
51
|
+
# The boxplot aggregation returns essential information for making a box plot:
|
52
|
+
# *minimum*, *maximum*, *median*, *first quartile* (25th percentile) and *third quartile* (75th percentile) values.
|
53
|
+
#
|
54
|
+
# Person.all.boxplot(:age)
|
55
|
+
# > {
|
56
|
+
# "min": 0.0,
|
57
|
+
# "max": 990.0,
|
58
|
+
# "q1": 167.5,
|
59
|
+
# "q2": 445.0,
|
60
|
+
# "q3": 722.5,
|
61
|
+
# "lower": 0.0,
|
62
|
+
# "upper": 990.0
|
63
|
+
# }
|
64
|
+
#
|
65
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-boxplot-aggregation.html
|
66
|
+
#
|
67
|
+
# @param [Symbol, String] column_name
|
68
|
+
def boxplot(column_name)
|
69
|
+
calculate(:boxplot, column_name)
|
70
|
+
end
|
71
|
+
|
72
|
+
# A multi-value metrics aggregation that computes stats over numeric values extracted from the aggregated documents. #
|
73
|
+
# The stats that are returned consist of: *min*, *max*, *sum*, *count* and *avg*.
|
74
|
+
#
|
75
|
+
# Person.all.stats(:age)
|
76
|
+
# > {
|
77
|
+
# "count": 10,
|
78
|
+
# "min": 0.0,
|
79
|
+
# "max": 990.0,
|
80
|
+
# "sum": 16859,
|
81
|
+
# "avg": 75.5
|
82
|
+
# }
|
83
|
+
#
|
84
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-stats-aggregation.html
|
85
|
+
#
|
86
|
+
# @param [Symbol, String] column_name
|
87
|
+
def stats(column_name)
|
88
|
+
calculate(:stats, column_name)
|
89
|
+
end
|
90
|
+
|
91
|
+
# A multi-value metrics aggregation that computes statistics over string values extracted from the aggregated documents.
|
92
|
+
# These values can be retrieved either from specific keyword fields.
|
93
|
+
#
|
94
|
+
# Person.all.string_stats(:name)
|
95
|
+
# > {
|
96
|
+
# "count": 5,
|
97
|
+
# "min_length": 24,
|
98
|
+
# "max_length": 30,
|
99
|
+
# "avg_length": 28.8,
|
100
|
+
# "entropy": 3.94617750050791
|
101
|
+
# }
|
102
|
+
#
|
103
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-string-stats-aggregation.html
|
104
|
+
#
|
105
|
+
# @param [Symbol, String] column_name
|
106
|
+
def string_stats(column_name)
|
107
|
+
calculate(:string_stats, column_name)
|
108
|
+
end
|
109
|
+
|
110
|
+
# The matrix_stats aggregation is a numeric aggregation that computes the following statistics over a set of document fields:
|
111
|
+
# *count* Number of per field samples included in the calculation.
|
112
|
+
# *mean* The average value for each field.
|
113
|
+
# *variance* Per field Measurement for how spread out the samples are from the mean.
|
114
|
+
# *skewness* Per field measurement quantifying the asymmetric distribution around the mean.
|
115
|
+
# *kurtosis* Per field measurement quantifying the shape of the distribution.
|
116
|
+
# *covariance* A matrix that quantitatively describes how changes in one field are associated with another.
|
117
|
+
# *correlation* The covariance matrix scaled to a range of -1 to 1, inclusive. Describes the relationship between field distributions.
|
118
|
+
#
|
119
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-matrix-stats-aggregation.html
|
120
|
+
#
|
121
|
+
# @param [Array<Symbol|String>] column_names
|
122
|
+
def matrix_stats(*column_names)
|
123
|
+
calculate(:matrix_stats, *column_names)
|
124
|
+
end
|
125
|
+
|
48
126
|
# A multi-value metrics aggregation that calculates one or more
|
49
127
|
# percentiles over numeric values extracted from the aggregated documents.
|
50
128
|
# Returns a hash with empty values (but keys still exists) if there is no row.
|
@@ -59,6 +137,9 @@ module ElasticsearchRecord
|
|
59
137
|
# "95.0" => 2021.0,
|
60
138
|
# "99.0" => 2022.0
|
61
139
|
# }
|
140
|
+
#
|
141
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-percentile-aggregation.html
|
142
|
+
#
|
62
143
|
# @param [Symbol, String] column_name
|
63
144
|
def percentiles(column_name)
|
64
145
|
calculate(:percentiles, column_name, node: :values)
|
@@ -81,10 +162,13 @@ module ElasticsearchRecord
|
|
81
162
|
# "95.0" => 2021.0,
|
82
163
|
# "99.0" => 2022.0
|
83
164
|
# }
|
165
|
+
#
|
166
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-percentile-rank-aggregation.html
|
167
|
+
#
|
84
168
|
# @param [Symbol, String] column_name
|
85
169
|
# @param [Array] values
|
86
170
|
def percentile_ranks(column_name, values)
|
87
|
-
calculate(:
|
171
|
+
calculate(:percentile_ranks, column_name, opts: { values: values }, node: :values)
|
88
172
|
end
|
89
173
|
|
90
174
|
# Calculates the cardinality on a given column. Returns +0+ if there's no row.
|
@@ -92,18 +176,22 @@ module ElasticsearchRecord
|
|
92
176
|
# Person.all.cardinality(:age)
|
93
177
|
# > 12
|
94
178
|
#
|
179
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-cardinality-aggregation.html
|
180
|
+
#
|
95
181
|
# @param [Symbol, String] column_name
|
96
182
|
def cardinality(column_name)
|
97
|
-
calculate(:cardinality, column_name)
|
183
|
+
calculate(:cardinality, column_name, node: :value)
|
98
184
|
end
|
99
185
|
|
100
186
|
# Calculates the average value on a given column. Returns +nil+ if there's no row. See #calculate for examples with options.
|
101
187
|
#
|
102
188
|
# Person.all.average(:age) # => 35.8
|
103
189
|
#
|
190
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-avg-aggregation.html
|
191
|
+
#
|
104
192
|
# @param [Symbol, String] column_name
|
105
193
|
def average(column_name)
|
106
|
-
calculate(:avg, column_name)
|
194
|
+
calculate(:avg, column_name, node: :value)
|
107
195
|
end
|
108
196
|
|
109
197
|
# Calculates the minimum value on a given column. The value is returned
|
@@ -112,9 +200,11 @@ module ElasticsearchRecord
|
|
112
200
|
# Person.all.minimum(:age)
|
113
201
|
# > 7
|
114
202
|
#
|
203
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-min-aggregation.html
|
204
|
+
#
|
115
205
|
# @param [Symbol, String] column_name
|
116
206
|
def minimum(column_name)
|
117
|
-
calculate(:min, column_name)
|
207
|
+
calculate(:min, column_name, node: :value)
|
118
208
|
end
|
119
209
|
|
120
210
|
# Calculates the maximum value on a given column. The value is returned
|
@@ -123,9 +213,28 @@ module ElasticsearchRecord
|
|
123
213
|
#
|
124
214
|
# Person.all.maximum(:age) # => 93
|
125
215
|
#
|
216
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-max-aggregation.html
|
217
|
+
#
|
126
218
|
# @param [Symbol, String] column_name
|
127
219
|
def maximum(column_name)
|
128
|
-
calculate(:max, column_name)
|
220
|
+
calculate(:max, column_name, node: :value)
|
221
|
+
end
|
222
|
+
|
223
|
+
# This single-value aggregation approximates the median absolute deviation of its search results.
|
224
|
+
# Median absolute deviation is a measure of variability. It is a robust statistic,
|
225
|
+
# meaning that it is useful for describing data that may have outliers, or may not be normally distributed.
|
226
|
+
# For such data it can be more descriptive than standard deviation.
|
227
|
+
#
|
228
|
+
# It is calculated as the median of each data point’s deviation from the median of the entire sample.
|
229
|
+
# That is, for a random variable X, the median absolute deviation is median(|median(X) - Xi|).
|
230
|
+
#
|
231
|
+
# Person.all.median_absolute_deviation(:age) # => 91
|
232
|
+
#
|
233
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-median-absolute-deviation-aggregation.html
|
234
|
+
#
|
235
|
+
# @param [Symbol, String] column_name
|
236
|
+
def median_absolute_deviation(column_name)
|
237
|
+
calculate(:median_absolute_deviation, column_name)
|
129
238
|
end
|
130
239
|
|
131
240
|
# Calculates the sum of values on a given column. The value is returned
|
@@ -134,24 +243,34 @@ module ElasticsearchRecord
|
|
134
243
|
#
|
135
244
|
# Person.all.sum(:age) # => 4562
|
136
245
|
#
|
246
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-sum-aggregation.html
|
247
|
+
#
|
137
248
|
# @param [Symbol, String] column_name (optional)
|
138
249
|
def sum(column_name)
|
139
|
-
calculate(:sum, column_name)
|
250
|
+
calculate(:sum, column_name, node: :value)
|
140
251
|
end
|
141
252
|
|
142
|
-
# creates a aggregation with the provided metric (e.g. :sum) and
|
253
|
+
# creates a aggregation with the provided metric (e.g. :sum) and columns.
|
143
254
|
# returns the metric node (default: :value) from the aggregations result.
|
144
255
|
# @param [Symbol, String] metric
|
145
|
-
# @param [Symbol
|
256
|
+
# @param [Array<Symbol|String>] columns
|
146
257
|
# @param [Hash] opts - additional arguments that get merged with the metric definition
|
147
|
-
# @param [Symbol] node (default
|
148
|
-
def calculate(metric,
|
149
|
-
metric_key = "#{
|
258
|
+
# @param [Symbol] node (default: nil)
|
259
|
+
def calculate(metric, *columns, opts: {}, node: nil)
|
260
|
+
metric_key = "calculate_#{metric}"
|
150
261
|
|
151
262
|
# spawn a new aggregation and return the aggs
|
152
|
-
response =
|
263
|
+
response = if columns.size == 1
|
264
|
+
aggregate(metric_key, { metric => { field: columns[0] }.merge(opts) }).aggregations
|
265
|
+
else
|
266
|
+
aggregate(metric_key, { metric => { fields: columns }.merge(opts) }).aggregations
|
267
|
+
end
|
153
268
|
|
154
|
-
|
269
|
+
if node.present?
|
270
|
+
response[metric_key][node]
|
271
|
+
else
|
272
|
+
response[metric_key]
|
273
|
+
end
|
155
274
|
end
|
156
275
|
end
|
157
276
|
end
|
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.
|
4
|
+
version: 1.7.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:
|
11
|
+
date: 2024-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -125,7 +125,7 @@ files:
|
|
125
125
|
- Rakefile
|
126
126
|
- docs/CHANGELOG.md
|
127
127
|
- docs/CODE_OF_CONDUCT.md
|
128
|
-
- docs/LICENSE
|
128
|
+
- docs/LICENSE
|
129
129
|
- elasticsearch_record.gemspec
|
130
130
|
- lib/active_record/connection_adapters/elasticsearch/column.rb
|
131
131
|
- lib/active_record/connection_adapters/elasticsearch/database_statements.rb
|