elasticsearch_record 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +4 -0
- data/Gemfile.lock +10 -14
- data/README.md +180 -27
- data/docs/CHANGELOG.md +36 -18
- data/docs/LICENSE.txt +1 -1
- data/elasticsearch_record.gemspec +42 -0
- data/lib/active_record/connection_adapters/elasticsearch/column.rb +20 -6
- data/lib/active_record/connection_adapters/elasticsearch/database_statements.rb +142 -125
- data/lib/active_record/connection_adapters/elasticsearch/quoting.rb +2 -23
- data/lib/active_record/connection_adapters/elasticsearch/schema_creation.rb +30 -0
- data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/attribute_methods.rb +103 -0
- data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/column_methods.rb +42 -0
- data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/create_table_definition.rb +158 -0
- data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_alias_definition.rb +32 -0
- data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_definition.rb +132 -0
- data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_mapping_definition.rb +110 -0
- data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_setting_definition.rb +136 -0
- data/lib/active_record/connection_adapters/elasticsearch/schema_definitions/update_table_definition.rb +174 -0
- data/lib/active_record/connection_adapters/elasticsearch/schema_definitions.rb +37 -0
- data/lib/active_record/connection_adapters/elasticsearch/schema_dumper.rb +110 -0
- data/lib/active_record/connection_adapters/elasticsearch/schema_statements.rb +398 -174
- data/lib/active_record/connection_adapters/elasticsearch/table_statements.rb +232 -0
- data/lib/active_record/connection_adapters/elasticsearch/type/multicast_value.rb +2 -0
- data/lib/active_record/connection_adapters/elasticsearch/unsupported_implementation.rb +32 -0
- data/lib/active_record/connection_adapters/elasticsearch_adapter.rb +112 -19
- data/lib/arel/collectors/elasticsearch_query.rb +0 -1
- data/lib/arel/visitors/elasticsearch.rb +7 -579
- data/lib/arel/visitors/elasticsearch_base.rb +234 -0
- data/lib/arel/visitors/elasticsearch_query.rb +463 -0
- data/lib/arel/visitors/elasticsearch_schema.rb +124 -0
- data/lib/elasticsearch_record/core.rb +44 -10
- data/lib/elasticsearch_record/errors.rb +13 -0
- data/lib/elasticsearch_record/gem_version.rb +6 -2
- data/lib/elasticsearch_record/instrumentation/log_subscriber.rb +27 -9
- data/lib/elasticsearch_record/model_schema.rb +5 -0
- data/lib/elasticsearch_record/persistence.rb +31 -26
- data/lib/elasticsearch_record/query.rb +56 -17
- data/lib/elasticsearch_record/querying.rb +17 -0
- data/lib/elasticsearch_record/relation/calculation_methods.rb +3 -0
- data/lib/elasticsearch_record/relation/core_methods.rb +57 -17
- data/lib/elasticsearch_record/relation/query_clause_tree.rb +38 -1
- data/lib/elasticsearch_record/relation/query_methods.rb +6 -0
- data/lib/elasticsearch_record/relation/result_methods.rb +15 -9
- data/lib/elasticsearch_record/result.rb +32 -5
- data/lib/elasticsearch_record/statement_cache.rb +2 -1
- data/lib/elasticsearch_record.rb +2 -2
- metadata +29 -11
- data/.ruby-version +0 -1
- data/lib/elasticsearch_record/schema_migration.rb +0 -30
@@ -3,202 +3,426 @@
|
|
3
3
|
module ActiveRecord
|
4
4
|
module ConnectionAdapters
|
5
5
|
module Elasticsearch
|
6
|
-
|
6
|
+
# extend adapter with schema-related statements
|
7
|
+
#
|
8
|
+
# *ORIGINAL* methods untouched:
|
9
|
+
# - internal_string_options_for_primary_key
|
10
|
+
# - options_include_default?
|
11
|
+
# - fetch_type_metadata
|
12
|
+
# - column_exists?
|
13
|
+
#
|
14
|
+
# *SUPPORTED* but not used:
|
15
|
+
# - strip_table_name_prefix_and_suffix
|
16
|
+
#
|
17
|
+
# *UNSUPPORTED* methods that will be +ignored+:
|
18
|
+
# - native_database_types
|
19
|
+
# - table_options
|
20
|
+
# - table_comment
|
21
|
+
# - table_alias_for
|
22
|
+
# - columns_for_distinct
|
23
|
+
# - extract_new_default_value
|
24
|
+
# - insert_versions_sql
|
25
|
+
# - data_source_sql
|
26
|
+
# - quoted_scope
|
27
|
+
# - add_column_for_alter
|
28
|
+
# - rename_column_sql
|
29
|
+
# - remove_column_for_alter
|
30
|
+
# - remove_columns_for_alter
|
31
|
+
# - add_timestamps_for_alter
|
32
|
+
# - remove_timestamps_for_alter
|
33
|
+
# - foreign_key_name
|
34
|
+
# - foreign_key_for
|
35
|
+
# - foreign_key_for!
|
36
|
+
# - extract_foreign_key_action
|
37
|
+
# - check_constraint_name
|
38
|
+
# - check_constraint_for
|
39
|
+
# - check_constraint_for!
|
40
|
+
# - validate_index_length!
|
41
|
+
# - can_remove_index_by_name?
|
42
|
+
# - index_column_names
|
43
|
+
# - index_name_options
|
44
|
+
# - add_index_sort_order
|
45
|
+
# - options_for_index_columns
|
46
|
+
# - add_options_for_index_columns
|
47
|
+
# - index_name_for_remove
|
48
|
+
# - add_index_options
|
49
|
+
# - index_algorithm
|
50
|
+
# - quoted_columns_for_index
|
51
|
+
# - check_constraint_options
|
52
|
+
# - check_constraints
|
53
|
+
# - foreign_key_exists?
|
54
|
+
# - foreign_key_column_for
|
55
|
+
# - foreign_key_options
|
56
|
+
# - foreign_keys
|
57
|
+
# - index_name_exists?
|
58
|
+
# - indexes
|
59
|
+
# - index_name
|
60
|
+
# - index_exists?
|
61
|
+
#
|
62
|
+
# *UNSUPPORTED* methods that will +fail+:
|
63
|
+
# - views
|
64
|
+
# - view_exists?
|
65
|
+
# - add_index
|
66
|
+
# - remove_index
|
67
|
+
# - rename_index
|
68
|
+
# - add_reference
|
69
|
+
# - remove_reference
|
70
|
+
# - add_foreign_key
|
71
|
+
# - remove_foreign_key
|
72
|
+
# - add_check_constraint
|
73
|
+
# - remove_check_constraint
|
74
|
+
# - rename_table_indexes
|
75
|
+
# - rename_column_indexes
|
76
|
+
# - create_alter_table
|
77
|
+
# - insert_fixture
|
78
|
+
# - insert_fixtures_set
|
79
|
+
# - bulk_change_table
|
80
|
+
# - dump_schema_information
|
81
|
+
#
|
82
|
+
# OVERWRITTEN methods for Elasticsearch:
|
83
|
+
# ...
|
84
|
+
module SchemaStatements
|
85
|
+
extend ActiveSupport::Concern
|
7
86
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
87
|
+
included do
|
88
|
+
define_unsupported_method :views, :view_exists?, :add_index, :remove_index, :rename_index, :add_reference,
|
89
|
+
:remove_reference, :add_foreign_key, :remove_foreign_key, :add_check_constraint,
|
90
|
+
:remove_check_constraint, :rename_table_indexes, :rename_column_indexes,
|
91
|
+
:create_alter_table, :insert_fixture, :insert_fixtures_set, :bulk_change_table,
|
92
|
+
:dump_schema_information
|
13
93
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
94
|
+
def assume_migrated_upto_version(version)
|
95
|
+
version = version.to_i
|
96
|
+
migrated = migration_context.get_all_versions
|
97
|
+
versions = migration_context.migrations.map(&:version)
|
19
98
|
|
99
|
+
unless migrated.include?(version)
|
100
|
+
# use a ActiveRecord syntax to create a new version
|
101
|
+
schema_migration.create(version: version)
|
102
|
+
end
|
20
103
|
|
104
|
+
inserting = (versions - migrated).select { |v| v < version }
|
105
|
+
if inserting.any?
|
106
|
+
if (duplicate = inserting.detect { |v| inserting.count(v) > 1 })
|
107
|
+
raise "Duplicate migration #{duplicate}. Please renumber your migrations to resolve the conflict."
|
108
|
+
end
|
21
109
|
|
110
|
+
# use a ActiveRecord syntax to create new versions
|
111
|
+
inserting.each {|iversion| schema_migration.create(version: iversion) }
|
112
|
+
end
|
22
113
|
|
114
|
+
true
|
115
|
+
end
|
23
116
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
117
|
+
# Returns the relation names usable to back Active Record models.
|
118
|
+
# For Elasticsearch this means all indices - which also includes system +dot+ '.' indices.
|
119
|
+
# @see ActiveRecord::ConnectionAdapters::SchemaStatements#data_sources
|
120
|
+
# @return [Array<String>]
|
121
|
+
def data_sources
|
122
|
+
api(:indices, :get, { index: :_all, expand_wildcards: [:open, :closed] }, 'SCHEMA').keys
|
123
|
+
end
|
31
124
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
125
|
+
# Returns an array of table names defined in the database.
|
126
|
+
# For Elasticsearch this means all normal indices (no system +dot+ '.' indices)
|
127
|
+
# @see ActiveRecord::ConnectionAdapters::SchemaStatements#tables
|
128
|
+
# @return [Array<String>]
|
129
|
+
def tables
|
130
|
+
data_sources.reject { |key| key[0] == '.' }
|
131
|
+
end
|
38
132
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
133
|
+
# returns a hash of all mappings by provided table_name (index)
|
134
|
+
# @param [String] table_name
|
135
|
+
# @return [Hash]
|
136
|
+
def table_mappings(table_name)
|
137
|
+
api(:indices, :get_mapping, { index: table_name, expand_wildcards: [:open, :closed] }, 'SCHEMA').dig(table_name, 'mappings')
|
138
|
+
end
|
45
139
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
raise(ActiveRecord::StatementInvalid, "Could not find elasticsearch index '#{table_name}'") if structure.blank? || structure['properties'].blank?
|
54
|
-
|
55
|
-
# since the received mappings do not have the "primary" +_id+-column we manually need to add this here
|
56
|
-
# The BASE_STRUCTURE will also include some meta keys like '_score', '_type', ...
|
57
|
-
ActiveRecord::ConnectionAdapters::ElasticsearchAdapter::BASE_STRUCTURE + structure['properties'].map { |key, prop|
|
58
|
-
# resolve (nested) fields and properties
|
59
|
-
fields, properties = resolve_fields_and_properties(key, prop, true)
|
60
|
-
|
61
|
-
# fallback for possible empty type
|
62
|
-
type = prop['type'].presence || (properties.present? ? 'object' : 'nested')
|
63
|
-
|
64
|
-
# return a new hash
|
65
|
-
prop.merge('name' => key, 'type' => type, 'fields' => fields, 'properties' => properties)
|
66
|
-
}
|
67
|
-
end
|
140
|
+
# returns a hash of all settings by provided table_name
|
141
|
+
# @param [String] table_name
|
142
|
+
# @param [Boolean] flat_settings (default: true)
|
143
|
+
# @return [Hash]
|
144
|
+
def table_settings(table_name, flat_settings = true)
|
145
|
+
api(:indices, :get_settings, { index: table_name, expand_wildcards: [:open, :closed], flat_settings: flat_settings }, 'SCHEMA').dig(table_name, 'settings')
|
146
|
+
end
|
68
147
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
def new_column_from_field(_table_name, field)
|
76
|
-
ActiveRecord::ConnectionAdapters::Elasticsearch::Column.new(
|
77
|
-
field["name"],
|
78
|
-
field["null_value"],
|
79
|
-
fetch_type_metadata(field["type"]),
|
80
|
-
field['null'].nil? ? true : field['null'],
|
81
|
-
nil,
|
82
|
-
comment: field['meta'] ? field['meta'].map { |k, v| "#{k}: #{v}" }.join(' | ') : nil,
|
83
|
-
virtual: field['virtual'],
|
84
|
-
fields: field['fields'],
|
85
|
-
properties: field['properties']
|
86
|
-
)
|
87
|
-
end
|
148
|
+
# returns a hash of all aliases by provided table_name (index).
|
149
|
+
# @param [String] table_name
|
150
|
+
# @return [Hash]
|
151
|
+
def table_aliases(table_name)
|
152
|
+
api(:indices, :get_alias, { index: table_name, expand_wildcards: [:open, :closed] }, 'SCHEMA').dig(table_name, 'aliases')
|
153
|
+
end
|
88
154
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
def lookup_cast_type_from_column(column)
|
95
|
-
type_map.lookup(:multicast_value, super)
|
96
|
-
end
|
155
|
+
# returns information about number of primaries and replicas, document counts, disk size, ... by provided table_name (index).
|
156
|
+
# @param [String] table_name
|
157
|
+
# @return [Hash]
|
158
|
+
def table_state(table_name)
|
159
|
+
response = api(:cat, :indices, { index: table_name, expand_wildcards: [:open, :closed] }, 'SCHEMA')
|
97
160
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
# We know, we can just return '_id' here ...
|
103
|
-
# @see ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter#primary_keys
|
104
|
-
# @param [String] _table_name
|
105
|
-
def primary_keys(_table_name)
|
106
|
-
ActiveRecord::ConnectionAdapters::ElasticsearchAdapter::BASE_STRUCTURE
|
107
|
-
.select { |f| f["primary"] }
|
108
|
-
.map { |f| f["name"] }
|
109
|
-
end
|
161
|
+
[:health, :status, :name, :uuid, :pri, :rep, :docs_count, :docs_deleted, :store_size, :pri_store_size].zip(
|
162
|
+
response.body.split(' ')
|
163
|
+
).to_h
|
164
|
+
end
|
110
165
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
166
|
+
# returns a hash of the full definition of the provided table_name (index).
|
167
|
+
# (includes settings, mappings & aliases)
|
168
|
+
# @param [String] table_name
|
169
|
+
# @param [Array, Symbol] features
|
170
|
+
# @return [Hash]
|
171
|
+
def table_schema(table_name, features = [:aliases, :mappings, :settings])
|
172
|
+
if cluster_info[:version] >= '8.5.0'
|
173
|
+
response = api(:indices, :get, { index: table_name, expand_wildcards: [:open, :closed], features: features, flat_settings: true }, 'SCHEMA')
|
174
|
+
else
|
175
|
+
response = api(:indices, :get, { index: table_name, expand_wildcards: [:open, :closed], flat_settings: true }, 'SCHEMA')
|
176
|
+
end
|
121
177
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
end
|
178
|
+
{
|
179
|
+
settings: response.dig(table_name, 'settings'),
|
180
|
+
mappings: response.dig(table_name, 'mappings'),
|
181
|
+
aliases: response.dig(table_name, 'aliases')
|
182
|
+
}
|
183
|
+
end
|
129
184
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
def table_exists?(table_name)
|
138
|
-
# just reference to the data sources
|
139
|
-
data_source_exists?(table_name)
|
140
|
-
end
|
185
|
+
# Returns the list of a table's column names, data types, and default values.
|
186
|
+
# @see ActiveRecord::ConnectionAdapters::SchemaStatements#columns
|
187
|
+
# @see ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter#column_definitions
|
188
|
+
# @param [String] table_name
|
189
|
+
# @return [Array<Hash>]
|
190
|
+
def column_definitions(table_name)
|
191
|
+
mappings = table_mappings(table_name)
|
141
192
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
193
|
+
# prevent exceptions on missing mappings, to provide the possibility to create them
|
194
|
+
# otherwise loading the table (index) will always fail!
|
195
|
+
mappings = { 'properties' => {} } if mappings.blank? || mappings['properties'].blank?
|
196
|
+
# raise(ActiveRecord::StatementInvalid, "Could not find valid mappings for '#{table_name}'") if mappings.blank? || mappings['properties'].blank?
|
197
|
+
|
198
|
+
# since the received mappings do not have the "primary" +_id+-column we manually need to add this here
|
199
|
+
# The BASE_STRUCTURE will also include some meta keys like '_score', '_type', ...
|
200
|
+
ActiveRecord::ConnectionAdapters::ElasticsearchAdapter::BASE_STRUCTURE + mappings['properties'].map { |key, prop|
|
201
|
+
# resolve (nested) fields and properties
|
202
|
+
fields, properties = resolve_fields_and_properties(key, prop, true)
|
203
|
+
|
204
|
+
# fallback for possible empty type
|
205
|
+
type = prop['type'].presence || (properties.present? ? 'object' : 'nested')
|
206
|
+
|
207
|
+
# return a new hash
|
208
|
+
prop.merge('name' => key, 'type' => type, 'fields' => fields, 'properties' => properties)
|
209
|
+
}
|
210
|
+
end
|
211
|
+
|
212
|
+
# creates a new column object from provided field Hash
|
213
|
+
# @see ActiveRecord::ConnectionAdapters::SchemaStatements#columns
|
214
|
+
# @see ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements#new_column_from_field
|
215
|
+
# @param [String] _table_name
|
216
|
+
# @param [Hash] field
|
217
|
+
# @return [ActiveRecord::ConnectionAdapters::Column]
|
218
|
+
def new_column_from_field(_table_name, field)
|
219
|
+
ActiveRecord::ConnectionAdapters::Elasticsearch::Column.new(
|
220
|
+
field["name"],
|
221
|
+
field["null_value"],
|
222
|
+
fetch_type_metadata(field["type"]),
|
223
|
+
meta: field['meta'],
|
224
|
+
virtual: field['virtual'],
|
225
|
+
fields: field['fields'],
|
226
|
+
properties: field['properties']
|
227
|
+
)
|
228
|
+
end
|
229
|
+
|
230
|
+
# lookups from building the @columns_hash.
|
231
|
+
# since Elasticsearch has the "feature" to provide multicast values on any type, we need to fetch them ...
|
232
|
+
# you know, ES can return an integer or an array of integers for any column ...
|
233
|
+
# @param [ActiveRecord::ConnectionAdapters::Elasticsearch::Column] column
|
234
|
+
# @return [ActiveRecord::ConnectionAdapters::Elasticsearch::Type::MulticastValue]
|
235
|
+
def lookup_cast_type_from_column(column)
|
236
|
+
type_map.lookup(:multicast_value, super)
|
237
|
+
end
|
238
|
+
|
239
|
+
# Returns a array of tables primary keys.
|
240
|
+
# PLEASE NOTE: Elasticsearch does not have a concept of primary key.
|
241
|
+
# The only thing that uniquely identifies a document is the index together with the +_id+.
|
242
|
+
# To not break the "ConnectionAdapters" concept we simulate this through the +meta+ attribute.
|
243
|
+
# @see ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter#primary_keys
|
244
|
+
# @param [String] table_name
|
245
|
+
def primary_keys(table_name)
|
246
|
+
column_definitions(table_name)
|
247
|
+
# ActiveRecord::ConnectionAdapters::ElasticsearchAdapter::BASE_STRUCTURE
|
248
|
+
.select { |f| f['meta'] && f['meta']['primary_key'] == 'true' }
|
249
|
+
# only take the last found primary key (if no custom primary_key was provided this will return +_id+ )
|
250
|
+
.map { |f| f["name"] }[-1..-1]
|
251
|
+
end
|
252
|
+
|
253
|
+
# Checks to see if the data source +name+ exists on the database.
|
254
|
+
#
|
255
|
+
# data_source_exists?(:ebooks)
|
256
|
+
# @see ActiveRecord::ConnectionAdapters::SchemaStatements#data_source_exists?
|
257
|
+
# @param [String, Symbol] name
|
258
|
+
# @return [Boolean]
|
259
|
+
def data_source_exists?(name)
|
260
|
+
# response returns boolean
|
261
|
+
api(:indices, :exists?, { index: name, expand_wildcards: [:open, :closed] }, 'SCHEMA')
|
262
|
+
end
|
263
|
+
|
264
|
+
# Checks to see if the table +table_name+ exists on the database.
|
265
|
+
#
|
266
|
+
# table_exists?(:developers)
|
267
|
+
#
|
268
|
+
# @see ActiveRecord::ConnectionAdapters::SchemaStatements#table_exists?
|
269
|
+
# @param [String, Symbol] table_name
|
270
|
+
# @return [Boolean]
|
271
|
+
def table_exists?(table_name)
|
272
|
+
# just reference to the data sources
|
273
|
+
data_source_exists?(table_name)
|
274
|
+
end
|
275
|
+
|
276
|
+
# Checks to see if a alias +alias_name+ within a table +table_name+ exists on the database.
|
277
|
+
#
|
278
|
+
# alias_exists?(:developers, 'my-alias')
|
279
|
+
#
|
280
|
+
# @param [String] table_name
|
281
|
+
# @param [String, Symbol] alias_name
|
282
|
+
# @return [Boolean]
|
283
|
+
def alias_exists?(table_name, alias_name)
|
284
|
+
table_aliases(table_name).keys.include?(alias_name.to_s)
|
285
|
+
end
|
286
|
+
|
287
|
+
# Checks to see if a setting +setting_name+ within a table +table_name+ exists on the database.
|
288
|
+
# The provided +setting_name+ must be flat!
|
289
|
+
#
|
290
|
+
# setting_exists?(:developers, 'index.number_of_replicas')
|
291
|
+
#
|
292
|
+
# @param [String] table_name
|
293
|
+
# @param [String,Symbol] setting_name
|
294
|
+
# @return [Boolean]
|
295
|
+
def setting_exists?(table_name, setting_name)
|
296
|
+
table_settings(table_name).keys.include?(setting_name.to_s)
|
297
|
+
end
|
298
|
+
|
299
|
+
# Checks to see if a mapping +mapping_name+ within a table +table_name+ exists on the database.
|
300
|
+
#
|
301
|
+
# mapping_exists?(:developers, :status, :integer)
|
302
|
+
#
|
303
|
+
# @param [String, Symbol] table_name
|
304
|
+
# @param [String, Symbol] mapping_name
|
305
|
+
# @return [Boolean]
|
306
|
+
def mapping_exists?(table_name, mapping_name, type = nil)
|
307
|
+
column_exists?(table_name, mapping_name, type)
|
308
|
+
end
|
309
|
+
|
310
|
+
# overwrite original methods to provide a elasticsearch version
|
311
|
+
def create_schema_dumper(options)
|
312
|
+
ActiveRecord::ConnectionAdapters::Elasticsearch::SchemaDumper.create(self, options)
|
313
|
+
end
|
314
|
+
|
315
|
+
# overwrite original methods to provide a elasticsearch version
|
316
|
+
def create_table_definition(name, **options)
|
317
|
+
::ActiveRecord::ConnectionAdapters::Elasticsearch::CreateTableDefinition.new(self, name, **options)
|
318
|
+
end
|
319
|
+
|
320
|
+
# overwrite original methods to provide a elasticsearch version
|
321
|
+
def update_table_definition(name, base = self, **options)
|
322
|
+
# :nodoc:
|
323
|
+
::ActiveRecord::ConnectionAdapters::Elasticsearch::UpdateTableDefinition.new(base, name, **options)
|
324
|
+
end
|
148
325
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
properties = []
|
188
|
-
|
189
|
-
if prop['properties'].present?
|
190
|
-
prop['properties'].each do |nested_key, nested_prop|
|
191
|
-
nested_fields, nested_properties = resolve_fields_and_properties("#{key}.#{nested_key}", nested_prop)
|
192
|
-
fields |= nested_fields
|
193
|
-
properties |= nested_properties
|
326
|
+
# overwrite original methods to provide a elasticsearch version
|
327
|
+
def schema_creation
|
328
|
+
::ActiveRecord::ConnectionAdapters::Elasticsearch::SchemaCreation.new(self)
|
329
|
+
end
|
330
|
+
|
331
|
+
# returns the maximum allowed size for queries for the provided +table_name+.
|
332
|
+
# The query will raise an ActiveRecord::StatementInvalid if the requested limit is above this value.
|
333
|
+
# @return [Integer]
|
334
|
+
def max_result_window(table_name)
|
335
|
+
table_settings(table_name).dig('index', 'max_result_window').presence || 10000
|
336
|
+
end
|
337
|
+
|
338
|
+
# Returns basic information about the cluster.
|
339
|
+
# @return [Hash{Symbol->Unknown}]
|
340
|
+
def cluster_info
|
341
|
+
@cluster_info ||= begin
|
342
|
+
response = api(:core, :info, {}, 'CLUSTER')
|
343
|
+
|
344
|
+
{
|
345
|
+
name: response.dig('name'),
|
346
|
+
cluster_name: response.dig('cluster_name'),
|
347
|
+
cluster_uuid: response.dig('cluster_uuid'),
|
348
|
+
version: Gem::Version.new(response.dig('version', 'number')),
|
349
|
+
lucene_version: response.dig('version', 'lucene_version')
|
350
|
+
}
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
# transforms provided schema-type to a sql-type
|
355
|
+
# @param [String, Symbol] type
|
356
|
+
# @param [String]
|
357
|
+
def type_to_sql(type, **)
|
358
|
+
return '' if type.blank?
|
359
|
+
|
360
|
+
if (native = native_database_types[type.to_sym])
|
361
|
+
(native.is_a?(Hash) ? native[:name] : native).dup
|
362
|
+
else
|
363
|
+
type.to_s
|
194
364
|
end
|
195
|
-
elsif !root # don't add the root property as sub-property
|
196
|
-
properties << { 'name' => key, 'type' => prop['type'] }
|
197
365
|
end
|
198
366
|
|
199
|
-
|
367
|
+
private
|
368
|
+
|
369
|
+
# returns a multidimensional array with fields & properties from the provided +prop+.
|
370
|
+
# Nested fields & properties will be also detected.
|
371
|
+
# .
|
372
|
+
# resolve_fields_and_properties('user', {...})
|
373
|
+
# # > [
|
374
|
+
# # fields
|
375
|
+
# [0] [
|
376
|
+
# [0] {
|
377
|
+
# "name" => "user.name.analyzed",
|
378
|
+
# "type" => "text"
|
379
|
+
# }
|
380
|
+
# ],
|
381
|
+
# # properties
|
382
|
+
# [1] [
|
383
|
+
# [0] {
|
384
|
+
# "name" => "user.id",
|
385
|
+
# "type" => "integer"
|
386
|
+
# },
|
387
|
+
# [1] {
|
388
|
+
# "name" => "user.name",
|
389
|
+
# "type" => "keyword"
|
390
|
+
# }
|
391
|
+
# ]
|
392
|
+
# ]
|
393
|
+
#
|
394
|
+
# @param [String] key
|
395
|
+
# @param [Hash] prop
|
396
|
+
# @param [Boolean] root - provide true, if this is a top property entry (default: false)
|
397
|
+
# @return [[Array, Array]]
|
398
|
+
def resolve_fields_and_properties(key, prop, root = false)
|
399
|
+
# mappings can have +fields+ - we also want them for 'query-conditions'
|
400
|
+
fields = (prop['fields'] || {}).map { |field_key, field_def|
|
401
|
+
{ 'name' => "#{key}.#{field_key}", 'type' => field_def['type'] }
|
402
|
+
}
|
403
|
+
|
404
|
+
# initial empty array
|
405
|
+
properties = []
|
406
|
+
|
407
|
+
if prop['properties'].present?
|
408
|
+
prop['properties'].each do |nested_key, nested_prop|
|
409
|
+
nested_fields, nested_properties = resolve_fields_and_properties("#{key}.#{nested_key}", nested_prop)
|
410
|
+
fields |= nested_fields
|
411
|
+
properties |= nested_properties
|
412
|
+
end
|
413
|
+
elsif !root # don't add the root property as sub-property
|
414
|
+
properties << { 'name' => key, 'type' => prop['type'] }
|
415
|
+
end
|
416
|
+
|
417
|
+
[fields, properties]
|
418
|
+
end
|
419
|
+
|
420
|
+
# overwrite original methods to provide a elasticsearch version
|
421
|
+
def extract_table_options!(options)
|
422
|
+
options.extract!(:settings, :mappings, :aliases, :force, :strict)
|
423
|
+
end
|
200
424
|
end
|
201
425
|
end
|
202
426
|
end
|
203
427
|
end
|
204
|
-
end
|
428
|
+
end
|