elasticsearch_record 1.0.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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]