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,7 +3,7 @@
|
|
3
3
|
module ElasticsearchRecord # :nodoc:
|
4
4
|
module Relation
|
5
5
|
class QueryClauseTree
|
6
|
-
delegate :any?, :empty?, :key?, :each, to: :predicates
|
6
|
+
delegate :any?, :empty?, :key?, :keys, :each, to: :predicates
|
7
7
|
|
8
8
|
def self.empty
|
9
9
|
@empty ||= new({}).freeze
|
@@ -39,6 +39,12 @@ module ElasticsearchRecord # :nodoc:
|
|
39
39
|
QueryClauseTree.new(dups)
|
40
40
|
end
|
41
41
|
|
42
|
+
def [](key)
|
43
|
+
return nil unless key?(key)
|
44
|
+
|
45
|
+
dupredicates[key]
|
46
|
+
end
|
47
|
+
|
42
48
|
def +(other)
|
43
49
|
dups = dupredicates
|
44
50
|
|
@@ -52,6 +58,17 @@ module ElasticsearchRecord # :nodoc:
|
|
52
58
|
end
|
53
59
|
|
54
60
|
def -(other)
|
61
|
+
# check for provided :tree
|
62
|
+
if other.key == :tree
|
63
|
+
scope = self
|
64
|
+
|
65
|
+
(scope.keys & other.keys).each do |key|
|
66
|
+
scope -= other[key]
|
67
|
+
end
|
68
|
+
|
69
|
+
return scope
|
70
|
+
end
|
71
|
+
|
55
72
|
dups = dupredicates
|
56
73
|
|
57
74
|
if key?(other.key)
|
@@ -79,6 +96,26 @@ module ElasticsearchRecord # :nodoc:
|
|
79
96
|
predicates == other.predicates
|
80
97
|
end
|
81
98
|
|
99
|
+
def or(other)
|
100
|
+
left = self - other
|
101
|
+
common = self - left
|
102
|
+
right = other - common
|
103
|
+
|
104
|
+
if left.empty? || right.empty?
|
105
|
+
common
|
106
|
+
else
|
107
|
+
key = other.keys[0]
|
108
|
+
|
109
|
+
left = left[key]
|
110
|
+
right = right[key]
|
111
|
+
|
112
|
+
or_clause = Arel::Nodes::Or.new(left, right)
|
113
|
+
|
114
|
+
common.predicates[key] = ElasticsearchRecord::Relation::QueryClause.new(key, [Arel::Nodes::Grouping.new(or_clause)])
|
115
|
+
common
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
82
119
|
protected
|
83
120
|
|
84
121
|
attr_reader :predicates
|
@@ -4,11 +4,11 @@ module ElasticsearchRecord
|
|
4
4
|
# aggregate pluck provided columns.
|
5
5
|
# returns a hash of values for each provided column
|
6
6
|
#
|
7
|
-
#
|
8
|
-
#
|
7
|
+
# Person.agg_pluck(:name)
|
8
|
+
# #> {"name" => ['David', 'Jeremy', 'Jose']}
|
9
9
|
#
|
10
|
-
#
|
11
|
-
#
|
10
|
+
# Person.agg_pluck(:id, :name)
|
11
|
+
# #> {"id" => ['11', '2', '5'], "name" => ['David', 'Jeremy', 'Jose']}
|
12
12
|
#
|
13
13
|
# @param [Array] column_names
|
14
14
|
# @return [Hash]
|
@@ -32,11 +32,11 @@ module ElasticsearchRecord
|
|
32
32
|
# For a single column_name a hash with the distinct key and the +doc_count+ as value is returned.
|
33
33
|
# For multiple column_names a hash with the distinct keys (as hash) and the +doc_count+ as value is returned.
|
34
34
|
#
|
35
|
-
#
|
36
|
-
#
|
35
|
+
# Person.composite(:name)
|
36
|
+
# #> {"David" => 10, "Jeremy" => 1, "Jose" => 24}
|
37
37
|
#
|
38
|
-
#
|
39
|
-
#
|
38
|
+
# Person.composite(:name, :age)
|
39
|
+
# #> {
|
40
40
|
# {name: "David", age: "16"} => 3,
|
41
41
|
# {name: "David", age: "18"} => 6,
|
42
42
|
# {name: "David", age: "20"} => 1,
|
@@ -89,7 +89,7 @@ module ElasticsearchRecord
|
|
89
89
|
# @param [String] keep_alive - how long to keep alive (for each single request) - default: '1m'
|
90
90
|
# @param [Integer] batch_size - how many results per query (default: 1000 - this means at least 10 queries before reaching the +max_result_window+)
|
91
91
|
def pit_results(keep_alive: '1m', batch_size: 1000)
|
92
|
-
raise ArgumentError, "Batch size cannot be above the 'max_result_window' (#{klass.
|
92
|
+
raise ArgumentError, "Batch size cannot be above the 'max_result_window' (#{klass.max_result_window}) !" if batch_size > klass.max_result_window
|
93
93
|
|
94
94
|
# check if a limit or offset values was provided
|
95
95
|
results_limit = limit_value ? limit_value : Float::INFINITY
|
@@ -182,6 +182,12 @@ module ElasticsearchRecord
|
|
182
182
|
spawn.aggs_only!.resolve('Aggregations').aggregations
|
183
183
|
end
|
184
184
|
|
185
|
+
# returns the response aggregations and resolve the buckets as key->value hash.
|
186
|
+
# @return [ActiveSupport::HashWithIndifferentAccess, Hash]
|
187
|
+
def buckets
|
188
|
+
spawn.aggs_only!.resolve('Buckets').buckets
|
189
|
+
end
|
190
|
+
|
185
191
|
# returns the RAW hits for the current query
|
186
192
|
# @return [Array]
|
187
193
|
def hits
|
@@ -48,9 +48,8 @@ module ElasticsearchRecord
|
|
48
48
|
response.key?('hits') ? response['hits'].with_indifferent_access : {}
|
49
49
|
end
|
50
50
|
|
51
|
-
# Returns the RAW
|
51
|
+
# Returns the RAW +_source+ data from each hit - aka. +rows+.
|
52
52
|
# PLEASE NOTE: The array will only contain the RAW data from each +_source+ (meta info like '_score' is not included)
|
53
|
-
# The +rows+ alias use used by the ActiveRecord ConnectionAdapters and must not be removed!
|
54
53
|
# @return [Array]
|
55
54
|
def results
|
56
55
|
return [] unless response['hits']
|
@@ -58,6 +57,7 @@ module ElasticsearchRecord
|
|
58
57
|
response['hits']['hits'].map { |result| result['_source'] }
|
59
58
|
end
|
60
59
|
|
60
|
+
# The +rows+ alias is used by the ActiveRecord ConnectionAdapters and must not be removed!
|
61
61
|
alias_method :rows, :results
|
62
62
|
|
63
63
|
# returns the response RAW aggregations hash.
|
@@ -66,6 +66,31 @@ module ElasticsearchRecord
|
|
66
66
|
response.key?('aggregations') ? response['aggregations'].with_indifferent_access : {}
|
67
67
|
end
|
68
68
|
|
69
|
+
# returns the (nested) bucket values (and aggregated values) from the response aggregations.
|
70
|
+
# @return [ActiveSupport::HashWithIndifferentAccess]
|
71
|
+
def buckets
|
72
|
+
# aggregations are already a hash with key => data, but to prevent reference manipulation on the hash
|
73
|
+
# we have to create a new one here...
|
74
|
+
aggregations.reduce({}) { |buckets, (key, agg)|
|
75
|
+
# check if this agg has a bucket
|
76
|
+
if agg.key?(:buckets)
|
77
|
+
buckets[key] = agg[:buckets].reduce({}) { |m, b|
|
78
|
+
# buckets can be a Hash or Array (of Hashes)
|
79
|
+
bucket_key, bucket = b.is_a?(Hash) ? [b[:key], b] : b
|
80
|
+
m[bucket_key] = bucket.except(:key, :doc_count).transform_values { |val| val[:value] }
|
81
|
+
|
82
|
+
m
|
83
|
+
}
|
84
|
+
elsif agg.key?(:value)
|
85
|
+
buckets[key] = agg[:value]
|
86
|
+
elsif agg.key?(:values)
|
87
|
+
buckets[key] = agg[:values]
|
88
|
+
end
|
89
|
+
|
90
|
+
buckets
|
91
|
+
}.with_indifferent_access
|
92
|
+
end
|
93
|
+
|
69
94
|
# Returns true if this result set includes the column named +name+.
|
70
95
|
# used by ActiveRecord
|
71
96
|
def includes_column?(name)
|
@@ -119,9 +144,10 @@ module ElasticsearchRecord
|
|
119
144
|
n ? computed_results.last(n) : computed_results.last
|
120
145
|
end
|
121
146
|
|
122
|
-
#
|
123
|
-
|
124
|
-
|
147
|
+
# returns the response result string
|
148
|
+
# @return [String]
|
149
|
+
def result
|
150
|
+
response['result'] || ''
|
125
151
|
end
|
126
152
|
|
127
153
|
# used by ActiveRecord
|
@@ -176,6 +202,7 @@ module ElasticsearchRecord
|
|
176
202
|
return self.response['total'] if self.response.key?('total')
|
177
203
|
return self.response['hits']['total']['value'] if self.response.key?('hits')
|
178
204
|
return self.response['aggregations'].count if self.response.key?('aggregations')
|
205
|
+
return self.response['_shards']['total'] if self.response.key?('_shards')
|
179
206
|
|
180
207
|
0
|
181
208
|
end
|
@@ -37,7 +37,8 @@ module ElasticsearchRecord
|
|
37
37
|
if ActiveModel::Attribute === value
|
38
38
|
value = value.value_for_database
|
39
39
|
end
|
40
|
-
|
40
|
+
value
|
41
|
+
# connection.quote(value)
|
41
42
|
elsif thing.is_a?(Hash)
|
42
43
|
thing.transform_values { |val|
|
43
44
|
deep_substitute_binds(val, binds, connection)
|
data/lib/elasticsearch_record.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# VERSION
|
4
3
|
require_relative 'elasticsearch_record/version'
|
4
|
+
require_relative "elasticsearch_record/errors"
|
5
5
|
|
6
6
|
require 'active_record'
|
7
7
|
|
@@ -27,7 +27,6 @@ module ElasticsearchRecord
|
|
27
27
|
autoload :Querying
|
28
28
|
autoload :Query
|
29
29
|
autoload :Result
|
30
|
-
autoload :SchemaMigration
|
31
30
|
autoload :StatementCache
|
32
31
|
end
|
33
32
|
|
@@ -59,6 +58,7 @@ end
|
|
59
58
|
ActiveSupport.on_load(:active_record) do
|
60
59
|
# load patches
|
61
60
|
require 'elasticsearch_record/patches/active_record/relation_merger_patch'
|
61
|
+
|
62
62
|
require 'elasticsearch_record/patches/arel/select_core_patch'
|
63
63
|
require 'elasticsearch_record/patches/arel/select_manager_patch'
|
64
64
|
require 'elasticsearch_record/patches/arel/select_statement_patch'
|
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.0
|
4
|
+
version: 1.1.0
|
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-
|
11
|
+
date: 2022-12-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -53,33 +53,33 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0
|
61
|
+
version: '13.0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0
|
68
|
+
version: '13.0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: yard
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '0.9'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '0.9'
|
83
83
|
description: 'ElasticsearchRecord is a ActiveRecord adapter and provides similar functionality
|
84
84
|
for Elasticsearch.
|
85
85
|
|
@@ -91,7 +91,7 @@ extensions: []
|
|
91
91
|
extra_rdoc_files: []
|
92
92
|
files:
|
93
93
|
- ".rspec"
|
94
|
-
- ".
|
94
|
+
- ".yardopts"
|
95
95
|
- Gemfile
|
96
96
|
- Gemfile.lock
|
97
97
|
- README.md
|
@@ -99,16 +99,30 @@ files:
|
|
99
99
|
- docs/CHANGELOG.md
|
100
100
|
- docs/CODE_OF_CONDUCT.md
|
101
101
|
- docs/LICENSE.txt
|
102
|
+
- elasticsearch_record.gemspec
|
102
103
|
- lib/active_record/connection_adapters/elasticsearch/column.rb
|
103
104
|
- lib/active_record/connection_adapters/elasticsearch/database_statements.rb
|
104
105
|
- lib/active_record/connection_adapters/elasticsearch/quoting.rb
|
106
|
+
- lib/active_record/connection_adapters/elasticsearch/schema_creation.rb
|
107
|
+
- lib/active_record/connection_adapters/elasticsearch/schema_definitions.rb
|
108
|
+
- lib/active_record/connection_adapters/elasticsearch/schema_definitions/attribute_methods.rb
|
109
|
+
- lib/active_record/connection_adapters/elasticsearch/schema_definitions/column_methods.rb
|
110
|
+
- lib/active_record/connection_adapters/elasticsearch/schema_definitions/create_table_definition.rb
|
111
|
+
- lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_alias_definition.rb
|
112
|
+
- lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_definition.rb
|
113
|
+
- lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_mapping_definition.rb
|
114
|
+
- lib/active_record/connection_adapters/elasticsearch/schema_definitions/table_setting_definition.rb
|
115
|
+
- lib/active_record/connection_adapters/elasticsearch/schema_definitions/update_table_definition.rb
|
116
|
+
- lib/active_record/connection_adapters/elasticsearch/schema_dumper.rb
|
105
117
|
- lib/active_record/connection_adapters/elasticsearch/schema_statements.rb
|
118
|
+
- lib/active_record/connection_adapters/elasticsearch/table_statements.rb
|
106
119
|
- lib/active_record/connection_adapters/elasticsearch/type.rb
|
107
120
|
- lib/active_record/connection_adapters/elasticsearch/type/format_string.rb
|
108
121
|
- lib/active_record/connection_adapters/elasticsearch/type/multicast_value.rb
|
109
122
|
- lib/active_record/connection_adapters/elasticsearch/type/nested.rb
|
110
123
|
- lib/active_record/connection_adapters/elasticsearch/type/object.rb
|
111
124
|
- lib/active_record/connection_adapters/elasticsearch/type/range.rb
|
125
|
+
- lib/active_record/connection_adapters/elasticsearch/unsupported_implementation.rb
|
112
126
|
- lib/active_record/connection_adapters/elasticsearch_adapter.rb
|
113
127
|
- lib/arel/collectors/elasticsearch_query.rb
|
114
128
|
- lib/arel/nodes/select_agg.rb
|
@@ -116,9 +130,13 @@ files:
|
|
116
130
|
- lib/arel/nodes/select_kind.rb
|
117
131
|
- lib/arel/nodes/select_query.rb
|
118
132
|
- lib/arel/visitors/elasticsearch.rb
|
133
|
+
- lib/arel/visitors/elasticsearch_base.rb
|
134
|
+
- lib/arel/visitors/elasticsearch_query.rb
|
135
|
+
- lib/arel/visitors/elasticsearch_schema.rb
|
119
136
|
- lib/elasticsearch_record.rb
|
120
137
|
- lib/elasticsearch_record/base.rb
|
121
138
|
- lib/elasticsearch_record/core.rb
|
139
|
+
- lib/elasticsearch_record/errors.rb
|
122
140
|
- lib/elasticsearch_record/extensions/relation.rb
|
123
141
|
- lib/elasticsearch_record/gem_version.rb
|
124
142
|
- lib/elasticsearch_record/instrumentation.rb
|
@@ -143,7 +161,6 @@ files:
|
|
143
161
|
- lib/elasticsearch_record/relation/result_methods.rb
|
144
162
|
- lib/elasticsearch_record/relation/value_methods.rb
|
145
163
|
- lib/elasticsearch_record/result.rb
|
146
|
-
- lib/elasticsearch_record/schema_migration.rb
|
147
164
|
- lib/elasticsearch_record/statement_cache.rb
|
148
165
|
- lib/elasticsearch_record/tasks/elasticsearch_database_tasks.rb
|
149
166
|
- lib/elasticsearch_record/version.rb
|
@@ -155,6 +172,7 @@ metadata:
|
|
155
172
|
allowed_push_host: https://rubygems.org
|
156
173
|
homepage_uri: https://github.com/ruby-smart/elasticsearch_record
|
157
174
|
source_code_uri: https://github.com/ruby-smart/elasticsearch_record
|
175
|
+
documentation_uri: https://rubydoc.info/gems/elasticsearch_record
|
158
176
|
changelog_uri: https://github.com/ruby-smart/elasticsearch_record/blob/main/docs/CHANGELOG.md
|
159
177
|
post_install_message:
|
160
178
|
rdoc_options: []
|
@@ -171,7 +189,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
171
189
|
- !ruby/object:Gem::Version
|
172
190
|
version: '0'
|
173
191
|
requirements: []
|
174
|
-
rubygems_version: 3.
|
192
|
+
rubygems_version: 3.2.22
|
175
193
|
signing_key:
|
176
194
|
specification_version: 4
|
177
195
|
summary: ActiveRecord adapter for Elasticsearch
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
3.1.2
|
@@ -1,30 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'active_record/schema_migration'
|
3
|
-
|
4
|
-
module ElasticsearchRecord
|
5
|
-
# temporary workaround
|
6
|
-
# toDo: fixme
|
7
|
-
class SchemaMigration < ActiveRecord::SchemaMigration # :nodoc:
|
8
|
-
class << self
|
9
|
-
def create_table
|
10
|
-
$stdout.puts "\n>>> 'create_table' elasticsearch is not supported - the following message is insignificant!"
|
11
|
-
end
|
12
|
-
|
13
|
-
def drop_table
|
14
|
-
$stdout.puts "\n>>> 'drop_table' elasticsearch is not supported - the following message is insignificant!"
|
15
|
-
end
|
16
|
-
|
17
|
-
def normalized_versions
|
18
|
-
[]
|
19
|
-
end
|
20
|
-
|
21
|
-
def all_versions
|
22
|
-
[]
|
23
|
-
end
|
24
|
-
|
25
|
-
def table_exists?
|
26
|
-
true
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|