elasticsearch_record 1.0.2 → 1.2.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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +4 -0
  3. data/Gemfile.lock +10 -14
  4. data/README.md +194 -27
  5. data/docs/CHANGELOG.md +55 -18
  6. data/docs/LICENSE.txt +1 -1
  7. data/elasticsearch_record.gemspec +42 -0
  8. data/lib/active_record/connection_adapters/elasticsearch/column.rb +27 -6
  9. data/lib/active_record/connection_adapters/elasticsearch/database_statements.rb +142 -125
  10. data/lib/active_record/connection_adapters/elasticsearch/quoting.rb +2 -23
  11. data/lib/active_record/connection_adapters/elasticsearch/schema_creation.rb +30 -0
  12. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/attribute_methods.rb +103 -0
  13. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/clone_table_definition.rb +88 -0
  14. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/column_methods.rb +42 -0
  15. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/create_table_definition.rb +160 -0
  16. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_alias_definition.rb +32 -0
  17. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_definition.rb +187 -0
  18. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_mapping_definition.rb +145 -0
  19. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_meta_definition.rb +24 -0
  20. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_setting_definition.rb +141 -0
  21. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/update_table_definition.rb +199 -0
  22. data/lib/active_record/connection_adapters/elasticsearch/schema_definitions.rb +40 -0
  23. data/lib/active_record/connection_adapters/elasticsearch/schema_dumper.rb +151 -0
  24. data/lib/active_record/connection_adapters/elasticsearch/schema_statements.rb +424 -174
  25. data/lib/active_record/connection_adapters/elasticsearch/table_statements.rb +326 -0
  26. data/lib/active_record/connection_adapters/elasticsearch/type/multicast_value.rb +2 -0
  27. data/lib/active_record/connection_adapters/elasticsearch/unsupported_implementation.rb +32 -0
  28. data/lib/active_record/connection_adapters/elasticsearch_adapter.rb +127 -19
  29. data/lib/arel/collectors/elasticsearch_query.rb +3 -1
  30. data/lib/arel/visitors/elasticsearch.rb +7 -579
  31. data/lib/arel/visitors/elasticsearch_base.rb +234 -0
  32. data/lib/arel/visitors/elasticsearch_query.rb +464 -0
  33. data/lib/arel/visitors/elasticsearch_schema.rb +165 -0
  34. data/lib/elasticsearch_record/core.rb +58 -8
  35. data/lib/elasticsearch_record/errors.rb +13 -0
  36. data/lib/elasticsearch_record/gem_version.rb +6 -2
  37. data/lib/elasticsearch_record/instrumentation/log_subscriber.rb +27 -9
  38. data/lib/elasticsearch_record/model_schema.rb +31 -2
  39. data/lib/elasticsearch_record/persistence.rb +56 -40
  40. data/lib/elasticsearch_record/query.rb +59 -17
  41. data/lib/elasticsearch_record/querying.rb +17 -0
  42. data/lib/elasticsearch_record/relation/calculation_methods.rb +3 -0
  43. data/lib/elasticsearch_record/relation/core_methods.rb +57 -17
  44. data/lib/elasticsearch_record/relation/query_clause_tree.rb +38 -1
  45. data/lib/elasticsearch_record/relation/query_methods.rb +6 -0
  46. data/lib/elasticsearch_record/relation/result_methods.rb +15 -9
  47. data/lib/elasticsearch_record/result.rb +32 -5
  48. data/lib/elasticsearch_record/schema_migration.rb +29 -10
  49. data/lib/elasticsearch_record/statement_cache.rb +2 -1
  50. data/lib/elasticsearch_record/tasks/elasticsearch_database_tasks.rb +15 -5
  51. data/lib/elasticsearch_record.rb +2 -1
  52. metadata +30 -9
  53. data/.ruby-version +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aee5f9a1e1bc853f7e7648313db47e4b3179f85049baebc364cfce80a3e1dbdf
4
- data.tar.gz: c3c17cd41fcc22930d28fdfdaedc69f5d5832d003e53141a0682942b8bb29496
3
+ metadata.gz: 8c479344b27eac6994fc17c6607f42221b093ddfc5f6db36b88994f25f2a0e56
4
+ data.tar.gz: 884ba24246d3ab9ef3500546bca84dcb3eaea184ac20bcfde6a2713e0a6def79
5
5
  SHA512:
6
- metadata.gz: e81eb876eb78e6133b4c8edc868f1d72fa2d3064d17680c6f0252f05d4c4029e3a6941dc3cd50948fc31ee91da308bb4f899c0744d708c5b4c66873a51985ba7
7
- data.tar.gz: 5235d1a1e23ccce634d994fc037a6b15ec0471cbc0cb16e35891f61cd01bad39cedc16c390a569b958677dada149825cdb514d59bb6d85465182b583974deeb7
6
+ metadata.gz: 554ca0302d07210beef1f8bcb4b49f65b9e734122ccbbfb4a44d619d7697d1e5ec4b4164890beacaab4106654e5cdb7c817adf81d5953d46ed9f600b395e8018
7
+ data.tar.gz: 2a6a3579a00f2734c623f364a1eea5ba9802896a122c74ea4503764c63ad0294f16279b02cf3ce0f6a8d924ef3cb15004c2e2a933e90f22d311f4cbae067597c
data/.yardopts ADDED
@@ -0,0 +1,4 @@
1
+ --embed-mixins
2
+ --markup=markdown
3
+ --files docs/*.*
4
+ --plugin relative_markdown_links
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- elasticsearch_record (0.1.0)
4
+ elasticsearch_record (1.2.0)
5
5
  activerecord (~> 7.0.0)
6
6
  elasticsearch (~> 8.4)
7
7
 
@@ -20,19 +20,18 @@ GEM
20
20
  tzinfo (~> 2.0)
21
21
  concurrent-ruby (1.1.10)
22
22
  diff-lcs (1.5.0)
23
- docile (1.4.0)
24
23
  elastic-transport (8.1.0)
25
24
  faraday (< 3)
26
25
  multi_json
27
- elasticsearch (8.4.0)
26
+ elasticsearch (8.5.2)
28
27
  elastic-transport (~> 8)
29
- elasticsearch-api (= 8.4.0)
30
- elasticsearch-api (8.4.0)
28
+ elasticsearch-api (= 8.5.2)
29
+ elasticsearch-api (8.5.2)
31
30
  multi_json
32
- faraday (2.5.2)
31
+ faraday (2.7.1)
33
32
  faraday-net_http (>= 2.0, < 3.1)
34
33
  ruby2_keywords (>= 0.0.4)
35
- faraday-net_http (3.0.0)
34
+ faraday-net_http (3.0.2)
36
35
  i18n (1.12.0)
37
36
  concurrent-ruby (~> 1.0)
38
37
  minitest (5.16.3)
@@ -52,14 +51,11 @@ GEM
52
51
  rspec-support (~> 3.11.0)
53
52
  rspec-support (3.11.1)
54
53
  ruby2_keywords (0.0.5)
55
- simplecov (0.21.2)
56
- docile (~> 1.1)
57
- simplecov-html (~> 0.11)
58
- simplecov_json_formatter (~> 0.1)
59
- simplecov-html (0.12.3)
60
- simplecov_json_formatter (0.1.4)
61
54
  tzinfo (2.0.5)
62
55
  concurrent-ruby (~> 1.0)
56
+ webrick (1.7.0)
57
+ yard (0.9.28)
58
+ webrick (~> 1.7.0)
63
59
 
64
60
  PLATFORMS
65
61
  x86_64-linux
@@ -68,7 +64,7 @@ DEPENDENCIES
68
64
  elasticsearch_record!
69
65
  rake (~> 13.0)
70
66
  rspec (~> 3.0)
71
- simplecov (~> 0.21)
67
+ yard (~> 0.9)
72
68
 
73
69
  BUNDLED WITH
74
70
  2.3.18
data/README.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # ElasticsearchRecord
2
2
 
3
+ [![GitHub](https://img.shields.io/badge/github-ruby--smart/elasticsearch_record-blue.svg)](http://github.com/ruby-smart/elasticsearch_record)
4
+ [![Documentation](https://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://rubydoc.info/gems/elasticsearch_record)
5
+
3
6
  [![Gem Version](https://badge.fury.io/rb/elasticsearch_record.svg)](https://badge.fury.io/rb/elasticsearch_record)
7
+ [![License](https://img.shields.io/github/license/ruby-smart/elasticsearch_record)](docs/LICENSE.txt)
4
8
 
5
9
  ActiveRecord adapter for Elasticsearch
6
10
 
@@ -9,6 +13,7 @@ _ElasticsearchRecord is a ActiveRecord adapter and provides similar functionalit
9
13
  -----
10
14
 
11
15
  **PLEASE NOTE:**
16
+
12
17
  - This is still in **development**!
13
18
  - Specs & documentation will follow.
14
19
  - You might experience BUGs and Exceptions...
@@ -34,19 +39,25 @@ Or install it yourself as:
34
39
 
35
40
 
36
41
  ## Features
37
- * CRUD: Reading and Writing Data as already used for ActiveRecord models ```create, update, delete```
38
- * Query-chaining through the Active Record Query Interface
39
- * Query interface with additional methods for ```filter, must, must_not, should```
40
- * Aggregation queries ```aggregate```
42
+ * ActiveRecord's `create, read, update & delete` behaviours
43
+ * Active Record Query Interface
44
+ * query-chaining
45
+ * scopes
46
+ * additional relation methods to find records with `filter, must, must_not, should`
47
+ * aggregated queries with Elasticsearch `aggregation` methods
48
+ * resolve search response `hits`, `aggregations`, `buckets`, ... instead of ActiveRecord objects
49
+ * Third-party gem support
50
+ * access `elasticsearch-dsl` query builder through `model.search{ ... }`
51
+ * Schema
52
+ * dump
53
+ * create & update of tables _(indices)_ with mappings, settings & aliases
41
54
  * Instrumentation for ElasticsearchRecord
55
+ * logs Elasticsearch API-calls
56
+ * shows Runtime in logs
42
57
 
43
58
  ## Contra - what it _(currently)_ can not
44
- * Query-based associations like 'has_one' through a single _(or multiple)_ queries - aka. joins
59
+ * Joins to other indexes or databases
45
60
  * complex, combined or nested queries ```and, or, Model.arel ...```
46
- * Create mappings / schema through migrations _(so no create_table, update_column, ...)_
47
- * Schema dumps
48
- * Manage indexes and mappings
49
-
50
61
 
51
62
  ## Setup
52
63
 
@@ -103,11 +114,19 @@ end
103
114
 
104
115
  ### d) have FUN with your model:
105
116
  ```ruby
106
- scope = Search.filter(term: {name: 'MyImportantObject'}).limit(5)
117
+ scope = Search
118
+ .where(name: 'Custom Object Name')
119
+ .where(token: nil)
120
+ .filter(terms: {type: [:x, :y]})
121
+ .limit(5)
122
+
123
+ # take the first object
107
124
  obj = scope.take
108
125
 
126
+ # update the objects name
109
127
  obj.update(name: "Not-So-Important")
110
128
 
129
+ # extend scope and update all docs
111
130
  scope.where(kind: :undefined).offset(10).update_all(name: "New Name")
112
131
 
113
132
  ```
@@ -115,7 +134,6 @@ scope.where(kind: :undefined).offset(10).update_all(name: "New Name")
115
134
  ## Active Record Query Interface
116
135
 
117
136
  ### Refactored ```where``` method:
118
-
119
137
  Different to the default where-method you can now use it in different ways.
120
138
 
121
139
  Using it by default with a Hash, the method decides itself to either add a filter, or must_not query.
@@ -141,17 +159,42 @@ Search.where(:should, term: {name: 'Mano'})
141
159
  # > should: {term: {name: 'Mano'}}
142
160
  ```
143
161
 
144
- ### Usage Examples
162
+ ### Result methods:
163
+ You can simply return RAW data without instantiating ActiveRecord objects:
164
+
145
165
  ```ruby
146
- # save a new record
147
- model = Search.new(name: "Cool object", kind: "open")
148
- model.save
149
166
 
150
- # find a record by id
151
- MyEsIndex.find_by_id("xyzAbc34")
167
+ # returns the response RAW hits hash.
168
+ hits = Search.where(name: 'A nice object').hits
169
+ # > {"total"=>{"value"=>5, "relation"=>"eq"}, "max_score"=>1.0, "hits"=>[{ "_index": "search", "_type": "_doc", "_id": "abc123", "_score": 1.0, "_source": { "name": "A nice object", ...
170
+
171
+ # Returns the RAW +_source+ data from each hit - aka. +rows+.
172
+ results = Search.where(name: 'A nice object').results
173
+ # > [{ "name": "A nice object", ...
174
+
175
+ # returns the response RAW aggregations hash.
176
+ aggs = Search.where(name: 'A nice object').aggregate(:total, {sum: {field: :amount}}).aggregations
177
+ # > {"total"=>{"value"=>6722604.0}}
178
+
179
+ # returns the (nested) bucket values (and aggregated values) from the response aggregations.
180
+ buckets = Search.where(name: 'A nice object').aggregate(:total, {sum: {field: :amount}}).buckets
181
+ # > {"total"=>6722604.0}
182
+
183
+ # resolves RAW +_source+ data from each hit with a +point_in_time+ query (also includes _id)
184
+ # useful if you want more then 10000 results.
185
+ results = Search.where(name: 'A nice object').pit_results
186
+ # > [{ "_id": "abc123", "name": "A nice object", ...
187
+
188
+ # returns the total value of the query without querying again (it uses the total value from the response)
189
+ scope = Search.where(name: 'A nice object').limit(5)
190
+ results_count = scope.count
191
+ # > 5
192
+ total = scope.total
193
+ # > 3335
194
+
152
195
  ```
153
196
 
154
- ### Useful chain methods
197
+ ### Available query/relation chain methods
155
198
  - kind
156
199
  - configure
157
200
  - aggregate
@@ -161,8 +204,12 @@ MyEsIndex.find_by_id("xyzAbc34")
161
204
  - must
162
205
  - should
163
206
  - aggregate
207
+ - restrict
208
+ - hits_only!
209
+ - aggs_only!
210
+ - total_only!
164
211
 
165
- ### Useful calculation methods
212
+ ### Available calculation methods
166
213
  - percentiles
167
214
  - percentile_ranks
168
215
  - cardinality
@@ -172,8 +219,9 @@ MyEsIndex.find_by_id("xyzAbc34")
172
219
  - sum
173
220
  - calculate
174
221
 
175
- ### Useful result methods
222
+ ### Available result methods
176
223
  - aggregations
224
+ - buckets
177
225
  - hits
178
226
  - results
179
227
  - total
@@ -188,31 +236,150 @@ MyEsIndex.find_by_id("xyzAbc34")
188
236
 
189
237
  -----
190
238
 
191
- ### Useful model-class attributes
239
+ ### Useful model class attributes
192
240
  - index_base_name
241
+ - relay_id_attribute
193
242
 
194
- ### Useful model methods
243
+ ### Useful model class methods
244
+ - auto_increment?
245
+ - max_result_window
195
246
  - source_column_names
196
247
  - searchable_column_names
197
248
  - find_by_query
198
249
  - msearch
199
250
 
251
+ ## ActiveRecord ConnectionAdapters table-methods
252
+ Access these methods through the model's connection.
253
+
254
+ ```ruby
255
+ # returns mapping of provided table (index)
256
+ model.connection.table_mappings('table-name')
257
+ ```
258
+
259
+ - table_mappings
260
+ - table_metas
261
+ - table_settings
262
+ - table_aliases
263
+ - table_state
264
+ - table_schema
265
+ - alias_exists?
266
+ - setting_exists?
267
+ - mapping_exists?
268
+ - meta_exists?
269
+ - max_result_window
270
+ - cluster_info
271
+
272
+ ## Active Record Schema migration methods
273
+ Access these methods through the model's connection or within any `Migration`.
274
+
275
+ **cluster actions:**
276
+ - open_table
277
+ - open_tables
278
+ - close_table
279
+ - close_tables
280
+ - truncate_table
281
+ - truncate_tables
282
+ - drop_table
283
+ - block_table
284
+ - unblock_table
285
+ - clone_table
286
+ - create_table
287
+ - change_table
288
+
289
+ **table actions:**
290
+ - change_meta
291
+ - delete_meta
292
+ - add_mapping
293
+ - change_mapping
294
+ - change_mapping_meta
295
+ - change_mapping_attributes
296
+ - add_setting
297
+ - change_setting
298
+ - delete_setting
299
+ - add_alias
300
+ - change_alias
301
+ - delete_alias
302
+
303
+ ```ruby
304
+ # Example migration
305
+ class AddTests < ActiveRecord::Migration[7.0]
306
+ def up
307
+ create_table "assignments", if_not_exists: true do |t|
308
+ t.string :key, primary_key: true
309
+ t.text :value
310
+ t.timestamps
311
+
312
+ t.setting :number_of_shards, "1"
313
+ t.setting :number_of_replicas, 0
314
+ end
315
+
316
+ # changes the auto-increment value
317
+ change_meta "assignments", :auto_increment, 3625
318
+
319
+ create_table "settings", force: true do |t|
320
+ t.mapping :created_at, :date
321
+ t.mapping :key, :integer do |m|
322
+ m.primary_key = true
323
+ m.auto_increment = 10
324
+ end
325
+ t.mapping :status, :keyword
326
+ t.mapping :updated_at, :date
327
+ t.mapping :value, :text
328
+
329
+ t.setting "index.number_of_replicas", "0"
330
+ t.setting "index.number_of_shards", "1"
331
+ t.setting "index.routing.allocation.include._tier_preference", "data_content"
332
+ end
333
+
334
+ add_mapping "settings", :active, :boolean do |m|
335
+ m.comment = "Contains the active state"
336
+ end
337
+
338
+ change_table 'settings', force: true do |t|
339
+ t.add_setting("index.search.idle.after", "20s")
340
+ t.add_setting("index.shard.check_on_startup", true)
341
+ t.add_alias('supersettings')
342
+ end
343
+
344
+ delete_alias('settings', :supersettings)
345
+ delete_setting('settings', 'index.search.idle.after')
346
+
347
+ change_table 'settings', force: true do |t|
348
+ t.integer :amount_of_newbies
349
+ end
350
+
351
+ create_table "vintage", force: true do |t|
352
+ t.primary_key :number
353
+ t.string :name
354
+ t.timestamps
355
+ end
356
+
357
+ change_mapping_attributes "vintage", :number, fields: {raw: {type: :keyword}}
358
+ end
359
+
360
+ def down
361
+ drop_table 'assignments'
362
+ drop_table 'settings'
363
+ drop_table 'vintage'
364
+ end
365
+ end
366
+ ```
200
367
 
201
368
  ## Docs
202
369
 
203
- [CHANGELOG](./docs/CHANGELOG.md)
370
+ [CHANGELOG](docs/CHANGELOG.md)
204
371
 
205
372
  ## Contributing
206
373
 
207
- Bug reports and pull requests are welcome on GitHub at [elasticsearch_record](https://github.com/ruby-smart/elasticsearch_record).
208
- This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](./docs/CODE_OF_CONDUCT.md).
374
+ Bug reports and pull requests are welcome on [GitHub](https://github.com/ruby-smart/elasticsearch_record).
375
+ This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](docs/CODE_OF_CONDUCT.md).
209
376
 
210
377
  ## License
211
378
 
212
379
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
213
380
 
214
- A copy of the [LICENSE](./docs/LICENSE.txt) can be found @ the docs.
381
+ A copy of the [LICENSE](docs/LICENSE.txt) can be found @ the docs.
215
382
 
216
383
  ## Code of Conduct
217
384
 
218
- Everyone interacting in the project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [CODE OF CONDUCT](./docs/CODE_OF_CONDUCT.md).
385
+ Everyone interacting in the project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [CODE OF CONDUCT](docs/CODE_OF_CONDUCT.md).
data/docs/CHANGELOG.md CHANGED
@@ -1,43 +1,80 @@
1
1
  # ElasticsearchRecord - CHANGELOG
2
2
 
3
+ ## [1.2.0] - 2022-12-02
4
+ * [add] `ElasticsearchRecord::SchemaMigration` to fix connection-related differences (like table_name_prefix, table_name_suffix)
5
+ * [add] connection (config-related) 'table_name_prefix' & 'table_name_suffix' - now will be forwarded to all related models & schema-tables
6
+ * [add] `#block_table`, `#unblock_table`, `#clone_table`, `#table_metas`, `#meta_exists?`, `#change_meta`, `#delete_meta` methods for Elasticsearch ConnectionAdapter
7
+ * [add] `ElasticsearchRecord::Base.auto_increment?`
8
+ * [add] index 'meta' method to access the `_meta` mapping
9
+ * [add] `.ElasticsearchRecord::Base.relay_id_attribute` to relay a possible existing 'id'-attribute
10
+ * [add] new enabled attribute `enabled` - which defines 'searchable attributes & fields' and gets also read from the index-mappings
11
+ * [ref] insert a new record with primary_key & auto_increment through a wrapper `_insert_with_auto_increment`
12
+ * [ref] resolve `primary_keys` now from the index `_meta` mapping first (old mapping-related 'meta.primary_key:"true"' is still supported)
13
+ * [ref] disable 'strict' mode (= validation) of settings, alias, mappings as default (this can be still used with `strict: true`)
14
+ * [ref] silent unsupported methods 'create/drop' for `ElasticsearchRecord::Tasks::ElasticsearchDatabaseTasks`
15
+ * [ref] primary_key & auto_increment handling of custom defined mappings - now uses the index `_meta` mapping
16
+ * [fix] creating a record with different 'primary_key' fails with removed value (value no longer gets dropped)
17
+ * [fix] some index-settings not being ignored through `#transform_settings!`
18
+ * [fix] `ActiveRecord::ConnectionAdapters::Elasticsearch::SchemaDumper` dumping environment-related tables in the same database
19
+ * [fix] `ActiveRecord::ConnectionAdapters::Elasticsearch::TableMappingDefinition` fails with explicit assignable attributes (now uses ASSIGNABLE_ATTRIBUTES)
20
+ * [fix] tables with provided 'table_name_prefix' or 'table_name_suffix' not being ignored by the SchemaDumper
21
+
22
+ ## [1.1.0] - 2022-12-01
23
+ * [add] support for schema dumps & migrations for Elasticsearch
24
+ * [add] `buckets` query/relation result method to resolve the buckets as key->value hash from aggregations
25
+ * [add] support for third-party gems (e.g. elasticsearch-dsl)
26
+ * [add] custom primary_key support with 'auto_increment' adaption _(beta)_
27
+ * [ref] instrumentation of `LogSubscriber` coloring
28
+ * [ref] unsupported methods to show exception
29
+ * [ref] query/relation method `#msearch` to support options 'resolve', 'transpose' & 'keep_null_relation'
30
+ * [ref] `ActiveRecord::ConnectionAdapters::ElasticsearchAdapter#translate_exception` for better error handling
31
+ * [ref] `ActiveRecord::ConnectionAdapters::Elasticsearch::Column` for a much easier assignment
32
+ * [ref] gemspec, yardoc & docs
33
+ * [fix] `ActiveRecord::ConnectionAdapters::ElasticsearchAdapter::BASE_STRUCTURE` to force primary_key column '_id' as virtual
34
+ * [fix] `ElasticsearchRecord::Relation::QueryClauseTree` not correctly calculating & merging 'filters, musts, ... '
35
+ * [fix] failing query not really failing in nested queries (msearch)
36
+ * [fix] 'null_realation' being executed in msearch
37
+ * [fix] quoting of columns, attributes & values
38
+ * [fix] query/relation method `#count` not preventing 'null_relation?'
39
+
3
40
  ## [1.0.2] - 2022-11-07
4
- * [add] ```ActiveRecord::ConnectionAdapters::ElasticsearchAdapter#migrations_paths``` with 'db/migrate_elasticsearch'
41
+ * [add] `ActiveRecord::ConnectionAdapters::ElasticsearchAdapter#migrations_paths` with 'db/migrate_elasticsearch'
5
42
  * [fix] to prevent executing 'primary' migrations to elasticsearch (SchemaDumper may still throw error comments)
6
43
  * [add] temporary workarounds for scheme & migrations until we support it (so bin/rails db:migrate - tasks will now run again)
7
44
 
8
45
  ## [1.0.1] - 2022-10-19
9
- * [add] ```ActiveRecord::ConnectionAdapters::Elasticsearch::Type::Nested``` class to cast nested values
46
+ * [add] `ActiveRecord::ConnectionAdapters::Elasticsearch::Type::Nested` class to cast nested values
10
47
  * [add] **properties** to column definition (so they are also searchable by _Relation_ conditions)
11
48
  * [add] exception for _Relation_ #pit_results if batch size is too large
12
49
  * [add] a default _#find_by_id_-method to proved a 'fallback' functionality for the primary '_id' column
13
50
  * [fix] nested properties are not cast for column-type "object"
14
- * [fix] ```ActiveRecord::ConnectionAdapters::Elasticsearch::SchemaStatements``` fields and property detection
15
- * [fix] ```ElasticsearchRecord::StatementCache::PartialQuery``` reference manipulation of cached hash _(missing .deep_dup )_
16
- * [ref] ```ActiveRecord::ConnectionAdapters::Elasticsearch::Type::Object``` class to only cast object values
17
- * [ref] ```Arel::Visitors::Elasticsearch#visit_Sort``` to detect a random sort with correct keyword: "**\_\_rand\_\_**"
51
+ * [fix] `ActiveRecord::ConnectionAdapters::Elasticsearch::SchemaStatements` fields and property detection
52
+ * [fix] `ElasticsearchRecord::StatementCache::PartialQuery` reference manipulation of cached hash _(missing .deep_dup )_
53
+ * [ref] `ActiveRecord::ConnectionAdapters::Elasticsearch::Type::Object` class to only cast object values
54
+ * [ref] `Arel::Visitors::Elasticsearch#visit_Sort` to detect a random sort with correct keyword: "**\_\_rand\_\_**"
18
55
 
19
56
  ## [1.0.0] - 2022-10-18
20
- * [add] patch for ```ActiveRecord::Relation::Merger``` - to support AR-relations
21
- * [add] ```ElasticsearchRecord::Relation#pit_results``` _offset_ & _yield_ support
22
- * [add] individual instrumentation names for ```ElasticsearchRecord::Relation``` result methods (like: #aggregations)
57
+ * [add] patch for `ActiveRecord::Relation::Merger` - to support AR-relations
58
+ * [add] `ElasticsearchRecord::Relation#pit_results` _offset_ & _yield_ support
59
+ * [add] individual instrumentation names for `ElasticsearchRecord::Relation` result methods (like: #aggregations)
23
60
  * [rem] cleanup Debugging & logging
24
61
  * [fix] quoting for any values
25
- * [fix] calculation ```count``` method to support already known syntax (with column, distinct, limited, ...)
26
- * [fix] ```Arel::Nodes``` to support additional args (query, kind, aggs, ...)
62
+ * [fix] calculation `count` method to support already known syntax (with column, distinct, limited, ...)
63
+ * [fix] `Arel::Nodes` to support additional args (query, kind, aggs, ...)
27
64
  * [fix] _relation manager patch_ to not mash up different relations
28
- * [fix] ```ElasticsearchRecord``` total calculation for failed queries
29
- * [fix] ```ElasticsearchRecord::Relation#count``` to correctly _unscope_
30
- * [fix] ```Arel::Visitors::Elasticsearch```
65
+ * [fix] `ElasticsearchRecord` total calculation for failed queries
66
+ * [fix] `ElasticsearchRecord::Relation#count` to correctly _unscope_
67
+ * [fix] `Arel::Visitors::Elasticsearch`
31
68
  * build query where-clauses without existing default query-"kind"
32
69
  * directly fail if a grouping _(visit_Arel_Nodes_Grouping)_ was provided
33
70
  * forced _failed!_ state was not correctly claimed
34
71
  * buggy _assign_-method for nested arrays
35
- * [fix] ```Arel::Collectors::ElasticsearchQuery```
72
+ * [fix] `Arel::Collectors::ElasticsearchQuery`
36
73
  * claim for _argument_
37
74
  * delete key on _nil_ assign
38
- * [ref] simplify ```Arel::Collectors::ElasticsearchQuery``` (remove stack & scoping)
39
- * [ref] simplify ```Arel::Visitors::Elasticsearch``` to support binds (statement cache) and simple where predicates
40
- * [ref] rename ```ElasticsearchRecord::Query#arguments``` -> _#query_arguments_
75
+ * [ref] simplify `Arel::Collectors::ElasticsearchQuery` (remove stack & scoping)
76
+ * [ref] simplify `Arel::Visitors::Elasticsearch` to support binds (statement cache) and simple where predicates
77
+ * [ref] rename `ElasticsearchRecord::Query#arguments` -> _#query_arguments_
41
78
 
42
79
  ## [0.1.2] - 2022-09-23
43
80
  * [fix] Records / Elasticsearch index with additional 'id' fields not recognizing
data/docs/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2022 Tobias Gonsior
3
+ Copyright (c) 2022 Ruby Smart
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/elasticsearch_record/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "elasticsearch_record"
7
+ spec.version = ElasticsearchRecord.version
8
+ spec.authors = ["Tobias Gonsior"]
9
+ spec.email = ["info@ruby-smart.org"]
10
+ spec.summary = "ActiveRecord adapter for Elasticsearch"
11
+ spec.description = <<DESC
12
+ ElasticsearchRecord is a ActiveRecord adapter and provides similar functionality for Elasticsearch.
13
+ DESC
14
+
15
+ spec.homepage = "https://github.com/ruby-smart/elasticsearch_record"
16
+ spec.license = "MIT"
17
+ spec.required_ruby_version = ">= 2.7.0"
18
+
19
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
20
+ spec.metadata["homepage_uri"] = spec.homepage
21
+ spec.metadata["source_code_uri"] = "https://github.com/ruby-smart/elasticsearch_record"
22
+ spec.metadata['documentation_uri'] = 'https://rubydoc.info/gems/elasticsearch_record'
23
+ spec.metadata["changelog_uri"] = "#{spec.metadata["source_code_uri"]}/blob/main/docs/CHANGELOG.md"
24
+
25
+ # Specify which files should be added to the gem when it is released.
26
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
27
+ spec.files = Dir.chdir(__dir__) do
28
+ `git ls-files -z`.split("\x0").reject do |f|
29
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
30
+ end
31
+ end
32
+
33
+ spec.require_paths = ["lib"]
34
+
35
+ spec.add_dependency 'activerecord', '~> 7.0.0'
36
+ spec.add_dependency 'elasticsearch', '~> 8.4'
37
+
38
+ #spec.add_development_dependency 'coveralls_reborn', '~> 0.25'
39
+ spec.add_development_dependency 'rspec', '~> 3.0'
40
+ spec.add_development_dependency 'rake', "~> 13.0"
41
+ spec.add_development_dependency 'yard', '~> 0.9'
42
+ end
@@ -5,13 +5,27 @@ module ActiveRecord
5
5
  module Elasticsearch
6
6
  class Column < ConnectionAdapters::Column # :nodoc:
7
7
 
8
- attr_reader :virtual, :fields, :properties
8
+ attr_reader :virtual, :fields, :properties, :meta, :enabled
9
9
 
10
- def initialize(name, default, sql_type_metadata = nil, null = true, default_function = nil, **kwargs)
11
- @virtual = kwargs.delete(:virtual)
12
- @fields = kwargs.delete(:fields)
13
- @properties = kwargs.delete(:properties)
14
- super(name, default, sql_type_metadata, null, default_function, **kwargs)
10
+ def initialize(name, default, sql_type_metadata = nil, virtual: false, fields: nil, properties: nil, meta: nil, enabled: nil, **kwargs)
11
+ @virtual = virtual
12
+ @fields = fields.presence || []
13
+ @properties = properties.presence || []
14
+ @meta = meta.presence || {}
15
+ @enabled = enabled.nil? ? true : enabled
16
+
17
+ super(name, default, sql_type_metadata, true, nil, **kwargs)
18
+ end
19
+
20
+ # returns comment from meta
21
+ def comment
22
+ meta? && meta['comment']
23
+ end
24
+
25
+ # returns true if this column is enabled (= searchable by queries)
26
+ # @return [Boolean]
27
+ def enabled?
28
+ !!enabled
15
29
  end
16
30
 
17
31
  # returns true if this column is virtual.
@@ -21,6 +35,13 @@ module ActiveRecord
21
35
  !!virtual
22
36
  end
23
37
 
38
+ # returns true if this column has meta information
39
+ # To receive the nested meta-data just call +#meta+ on this object.
40
+ # @return [Boolean]
41
+ def meta?
42
+ meta.present?
43
+ end
44
+
24
45
  # returns true if this column has nested fields
25
46
  # To receive the nested names just call +#fields+ on this object.
26
47
  # @return [Boolean]