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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8c479344b27eac6994fc17c6607f42221b093ddfc5f6db36b88994f25f2a0e56
4
- data.tar.gz: 884ba24246d3ab9ef3500546bca84dcb3eaea184ac20bcfde6a2713e0a6def79
3
+ metadata.gz: 32688db9e3220d919f454f7c4c9445b006d43299d66322f4586af9d426fdc907
4
+ data.tar.gz: 9169c9110e662d647f7eddeddae7fa3497a03ad36486d85c001e762af5c756df
5
5
  SHA512:
6
- metadata.gz: 554ca0302d07210beef1f8bcb4b49f65b9e734122ccbbfb4a44d619d7697d1e5ec4b4164890beacaab4106654e5cdb7c817adf81d5953d46ed9f600b395e8018
7
- data.tar.gz: 2a6a3579a00f2734c623f364a1eea5ba9802896a122c74ea4503764c63ad0294f16279b02cf3ce0f6a8d924ef3cb15004c2e2a933e90f22d311f4cbae067597c
6
+ metadata.gz: 9221a04be02abcb7d8f36da24f3b7e2d061b778233b8190bb14b906bf54b2a8d881a870f9c0b1b65d90b3ff2418fe8ee21d828b35dceac85b2f8bc766677c73c
7
+ data.tar.gz: a1b4e64cf4a8c33d8ce3aaeb89fedd5b7847a648a1dcfccc2b15ecfba0f99d0fbf9a0c94237edcd6ef0feb8d4ef40889ab00c2b8a6bc50773b4982cd5e326149
data/.yardopts CHANGED
@@ -1,4 +1,6 @@
1
1
  --embed-mixins
2
2
  --markup=markdown
3
3
  --files docs/*.*
4
- --plugin relative_markdown_links
4
+ --plugin relative_markdown_links
5
+ --plugin activesupport-concern
6
+ --exclude lib/elasticsearch_record/patches
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- elasticsearch_record (1.2.0)
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 query.
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
@@ -39,4 +39,5 @@ DESC
39
39
  spec.add_development_dependency 'rspec', '~> 3.0'
40
40
  spec.add_development_dependency 'rake', "~> 13.0"
41
41
  spec.add_development_dependency 'yard', '~> 0.9'
42
+ spec.add_development_dependency 'yard-activesupport-concern', '~> 0.0.1'
42
43
  end
@@ -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) # :nodoc:
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
 
@@ -9,7 +9,7 @@ module ElasticsearchRecord
9
9
  module VERSION
10
10
  MAJOR = 1
11
11
  MINOR = 2
12
- TINY = 0
12
+ TINY = 1
13
13
  PRE = nil
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
@@ -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
- # As an alternative you can also call the #query(<kind>,{argument}) method.
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 = predicate_builder.build_from_hash(opts) do |table_name|
217
- lookup_table_klass_from_join_dependencies(table_name)
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.0
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-02 00:00:00.000000000 Z
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