esse 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/esse/backend/index/aliases.rb +8 -8
- data/lib/esse/backend/index/close.rb +3 -3
- data/lib/esse/backend/index/create.rb +4 -4
- data/lib/esse/backend/index/delete.rb +4 -4
- data/lib/esse/backend/index/documents.rb +253 -6
- data/lib/esse/backend/index/existance.rb +3 -3
- data/lib/esse/backend/index/open.rb +3 -3
- data/lib/esse/backend/index/refresh.rb +7 -5
- data/lib/esse/backend/index/reset.rb +4 -4
- data/lib/esse/backend/index/update.rb +7 -7
- data/lib/esse/backend/index.rb +16 -14
- data/lib/esse/backend/repository_backend.rb +105 -0
- data/lib/esse/cli/event_listener.rb +14 -0
- data/lib/esse/cli/generate.rb +53 -12
- data/lib/esse/cli/index/base_operation.rb +5 -13
- data/lib/esse/cli/index/import.rb +6 -2
- data/lib/esse/cli/index/update_mapping.rb +3 -4
- data/lib/esse/cli/index.rb +2 -0
- data/lib/esse/cli/templates/{type_collection.rb.erb → collection.rb.erb} +6 -18
- data/lib/esse/cli/templates/config.rb.erb +13 -3
- data/lib/esse/cli/templates/index.rb.erb +53 -109
- data/lib/esse/cli/templates/mappings.json +27 -0
- data/lib/esse/cli/templates/serializer.rb.erb +34 -0
- data/lib/esse/cli/templates/settings.json +62 -0
- data/lib/esse/client_proxy/search.rb +44 -0
- data/lib/esse/client_proxy.rb +32 -0
- data/lib/esse/cluster.rb +64 -9
- data/lib/esse/cluster_engine.rb +42 -0
- data/lib/esse/collection.rb +18 -0
- data/lib/esse/config.rb +14 -2
- data/lib/esse/core.rb +23 -6
- data/lib/esse/deprecations/cluster.rb +27 -0
- data/lib/esse/deprecations/index.rb +19 -0
- data/lib/esse/deprecations/repository.rb +19 -0
- data/lib/esse/deprecations.rb +3 -0
- data/lib/esse/dynamic_template.rb +39 -0
- data/lib/esse/errors.rb +53 -2
- data/lib/esse/events/event.rb +4 -19
- data/lib/esse/events.rb +3 -0
- data/lib/esse/hash_document.rb +38 -0
- data/lib/esse/import/bulk.rb +96 -0
- data/lib/esse/import/request_body.rb +60 -0
- data/lib/esse/index/attributes.rb +98 -0
- data/lib/esse/index/base.rb +1 -1
- data/lib/esse/index/inheritance.rb +30 -0
- data/lib/esse/index/mappings.rb +6 -19
- data/lib/esse/index/object_document_mapper.rb +95 -0
- data/lib/esse/index/plugins.rb +42 -0
- data/lib/esse/index/search.rb +27 -0
- data/lib/esse/index/settings.rb +2 -2
- data/lib/esse/index/type.rb +52 -11
- data/lib/esse/index.rb +10 -6
- data/lib/esse/index_mapping.rb +10 -2
- data/lib/esse/index_setting.rb +3 -1
- data/lib/esse/null_document.rb +35 -0
- data/lib/esse/plugins.rb +12 -0
- data/lib/esse/primitives/hstring.rb +1 -1
- data/lib/esse/{index_type → repository}/actions.rb +1 -1
- data/lib/esse/{index_type → repository}/backend.rb +2 -2
- data/lib/esse/repository/object_document_mapper.rb +157 -0
- data/lib/esse/repository.rb +18 -0
- data/lib/esse/search/query.rb +105 -0
- data/lib/esse/search/response.rb +46 -0
- data/lib/esse/serializer.rb +76 -0
- data/lib/esse/version.rb +1 -1
- data/lib/esse.rb +20 -5
- metadata +35 -30
- data/lib/esse/backend/index_type/documents.rb +0 -214
- data/lib/esse/backend/index_type.rb +0 -37
- data/lib/esse/cli/templates/type_mappings.json +0 -6
- data/lib/esse/cli/templates/type_serializer.rb.erb +0 -23
- data/lib/esse/index/naming.rb +0 -64
- data/lib/esse/index_type/mappings.rb +0 -42
- data/lib/esse/index_type.rb +0 -15
- data/lib/esse/object_document_mapper.rb +0 -110
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a9a18ea9cc75f6e98edecd0c151fe3077dc362529dc562e380855ec651b898e
|
4
|
+
data.tar.gz: 3d1a96c3ba0a088e2a88b5e7aa3c1440662877d6ab2dc3e1edbd7276fe39611e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a70c285401ed1f1d3c43ebb73970339d9c48344d1872a8f5c8391ead77c75a3aeabbc8391acd88971e8bdfcc370abafdab726884deb86d713aabe75bf553c3da
|
7
|
+
data.tar.gz: 6ca5282a53d4e7b29bbe29e149fd5405c9a25a6bd561bc803969e173955f83625c33a6f5b1116280f5a327b54ad4ec5923b58844543da63c51ff029e805e64ec
|
@@ -11,12 +11,12 @@ module Esse
|
|
11
11
|
#
|
12
12
|
# @see https://www.elastic.co/guide/en/elasticsearch/reference/7.5/indices-aliases.html
|
13
13
|
def aliases(**options)
|
14
|
-
response = client.indices.get_alias({ index: index_name, name: '*' }.merge(options))
|
14
|
+
response = coerce_exception { client.indices.get_alias({ index: index_name, name: '*' }.merge(options)) }
|
15
15
|
idx_name = response.keys.find { |idx| idx.start_with?(index_name) }
|
16
16
|
return [] unless idx_name
|
17
17
|
|
18
18
|
response.dig(idx_name, 'aliases')&.keys || []
|
19
|
-
rescue
|
19
|
+
rescue NotFoundError
|
20
20
|
[]
|
21
21
|
end
|
22
22
|
|
@@ -25,8 +25,8 @@ module Esse
|
|
25
25
|
# @param options [Hash] Hash of paramenters that will be passed along to elasticsearch request
|
26
26
|
# @return [Array] list of indices that match with `index_name`.
|
27
27
|
def indices(**options)
|
28
|
-
client.indices.get_alias({ name: index_name }.merge(options)).keys
|
29
|
-
rescue
|
28
|
+
coerce_exception { client.indices.get_alias({ name: index_name }.merge(options)).keys }
|
29
|
+
rescue NotFoundError
|
30
30
|
[]
|
31
31
|
end
|
32
32
|
|
@@ -34,7 +34,7 @@ module Esse
|
|
34
34
|
#
|
35
35
|
# @param options [Hash] Hash of paramenters that will be passed along to elasticsearch request
|
36
36
|
# @option [String] :suffix The suffix of the index used for versioning.
|
37
|
-
# @raise [
|
37
|
+
# @raise [Esse::Backend::NotFoundError] in case of failure
|
38
38
|
# @return [Hash] the elasticsearch response
|
39
39
|
def update_aliases!(suffix:, **options)
|
40
40
|
raise(ArgumentError, 'index suffix cannot be nil') if suffix.nil?
|
@@ -50,7 +50,7 @@ module Esse
|
|
50
50
|
|
51
51
|
Esse::Events.instrument('elasticsearch.update_aliases') do |payload|
|
52
52
|
payload[:request] = options
|
53
|
-
payload[:response] = client.indices.update_aliases(options)
|
53
|
+
payload[:response] = coerce_exception { client.indices.update_aliases(options)}
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
@@ -58,11 +58,11 @@ module Esse
|
|
58
58
|
#
|
59
59
|
# @param options [Hash] Hash of paramenters that will be passed along to elasticsearch request
|
60
60
|
# @option [String] :suffix The suffix of the index used for versioning.
|
61
|
-
# @raise [
|
61
|
+
# @raise [Esse::Backend::NotFoundError] in case of failure
|
62
62
|
# @return [Hash] the elasticsearch response, or an hash with 'errors' as true in case of failure
|
63
63
|
def update_aliases(suffix:, **options)
|
64
64
|
update_aliases!(suffix: suffix, **options)
|
65
|
-
rescue
|
65
|
+
rescue NotFoundError
|
66
66
|
{ 'errors' => true }
|
67
67
|
end
|
68
68
|
end
|
@@ -15,7 +15,7 @@ module Esse
|
|
15
15
|
# @option options [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
|
16
16
|
# unavailable (missing, closed, etc)
|
17
17
|
# @option options [Time] :timeout Explicit operation timeout
|
18
|
-
# @raise [
|
18
|
+
# @raise [Esse::Backend::ServerError]
|
19
19
|
# in case of failure
|
20
20
|
# @return [Hash] the elasticsearch response
|
21
21
|
#
|
@@ -23,7 +23,7 @@ module Esse
|
|
23
23
|
def close!(suffix: index_version, **options)
|
24
24
|
Esse::Events.instrument('elasticsearch.close') do |payload|
|
25
25
|
payload[:request] = attributes = options.merge(index: index_name(suffix: suffix))
|
26
|
-
payload[:response] = client.indices.close(**attributes)
|
26
|
+
payload[:response] = coerce_exception { client.indices.close(**attributes) }
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -43,7 +43,7 @@ module Esse
|
|
43
43
|
# @see https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-open-close.html
|
44
44
|
def close(suffix: index_version, **options)
|
45
45
|
close!(suffix: suffix, **options)
|
46
|
-
rescue
|
46
|
+
rescue ServerError
|
47
47
|
{ 'errors' => true }
|
48
48
|
end
|
49
49
|
end
|
@@ -21,7 +21,7 @@ module Esse
|
|
21
21
|
# @see http://www.elasticsearch.org/blog/changing-mapping-with-zero-downtime/
|
22
22
|
def create_index(suffix: index_version, **options)
|
23
23
|
create_index!(suffix: suffix, **options)
|
24
|
-
rescue
|
24
|
+
rescue ServerError
|
25
25
|
{ 'errors' => true }
|
26
26
|
end
|
27
27
|
|
@@ -39,7 +39,7 @@ module Esse
|
|
39
39
|
# @option arguments [Time] :master_timeout Specify timeout for connection to master
|
40
40
|
# @option arguments [Hash] :headers Custom HTTP headers
|
41
41
|
# @option arguments [Hash] :body The configuration for the index (`settings` and `mappings`)
|
42
|
-
# @raise [
|
42
|
+
# @raise [Esse::Backend::NotFoundError] when index already exists
|
43
43
|
# @return [Hash] the elasticsearch response
|
44
44
|
#
|
45
45
|
# @see http://www.elasticsearch.org/blog/changing-mapping-with-zero-downtime/
|
@@ -54,8 +54,8 @@ module Esse
|
|
54
54
|
|
55
55
|
Esse::Events.instrument('elasticsearch.create_index') do |payload|
|
56
56
|
payload[:request] = opts = options.merge(index: name, body: definition)
|
57
|
-
payload[:response] = response = client.indices.create(**opts)
|
58
|
-
cluster.wait_for_status! if response
|
57
|
+
payload[:response] = response = coerce_exception { client.indices.create(**opts) }
|
58
|
+
coerce_exception { cluster.wait_for_status! } if response
|
59
59
|
response
|
60
60
|
end
|
61
61
|
end
|
@@ -9,13 +9,13 @@ module Esse
|
|
9
9
|
# UsersIndex.elasticsearch.delete_index! # deletes `<prefix_>users<_suffix|_index_version|_timestamp>` index
|
10
10
|
#
|
11
11
|
# @param suffix [String, nil] The index suffix Use nil if you want to delete the current index.
|
12
|
-
# @raise [
|
12
|
+
# @raise [Esse::Backend::NotFoundError] when index does not exists
|
13
13
|
# @return [Hash] elasticsearch response
|
14
14
|
def delete_index!(suffix: index_version, **options)
|
15
15
|
Esse::Events.instrument('elasticsearch.delete_index') do |payload|
|
16
16
|
payload[:request] = opts = options.merge(index: index_name(suffix: suffix))
|
17
|
-
payload[:response] = response = client.indices.delete(**opts)
|
18
|
-
cluster.wait_for_status! if response
|
17
|
+
payload[:response] = response = coerce_exception { client.indices.delete(**opts) }
|
18
|
+
coerce_exception { cluster.wait_for_status! } if response
|
19
19
|
response
|
20
20
|
end
|
21
21
|
end
|
@@ -28,7 +28,7 @@ module Esse
|
|
28
28
|
# @return [Hash] the elasticsearch response, or an hash with 'errors' as true in case of failure
|
29
29
|
def delete_index(suffix: index_version, **options)
|
30
30
|
delete_index!(suffix: suffix, **options)
|
31
|
-
rescue
|
31
|
+
rescue ServerError
|
32
32
|
{ 'errors' => true }
|
33
33
|
end
|
34
34
|
end
|
@@ -4,17 +4,264 @@ module Esse
|
|
4
4
|
module Backend
|
5
5
|
class Index
|
6
6
|
module InstanceMethods
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
# Resolve collection and index data
|
8
|
+
#
|
9
|
+
# @param types [Array<String>] List of document types. Defaults to all types.
|
10
|
+
# @param options [Hash] Hash of paramenters that will be passed along to elasticsearch request
|
11
|
+
# @option [String, nil] :suffix The index suffix. Defaults to the nil.
|
12
|
+
# @option [Hash] :context The collection context. This value will be passed as argument to the collection
|
13
|
+
# May be SQL condition or any other filter you have defined on the collection.
|
14
|
+
# @return [Numeric] The number of documents imported
|
15
|
+
def import(*types, context: {}, suffix: nil, **options)
|
16
|
+
types = repo_hash.keys if types.empty?
|
17
|
+
count = 0
|
18
|
+
types.each do |type|
|
19
|
+
each_serialized_batch(type, **(context || {})) do |batch|
|
20
|
+
bulk(type: type, index: batch, suffix: suffix, **options)
|
21
|
+
count += batch.size
|
22
|
+
end
|
10
23
|
end
|
24
|
+
count
|
11
25
|
end
|
26
|
+
alias_method :import!, :import
|
12
27
|
|
13
|
-
|
14
|
-
|
15
|
-
|
28
|
+
# Performs multiple indexing or delete operations in a single API call.
|
29
|
+
# This reduces overhead and can greatly increase indexing speed.
|
30
|
+
#
|
31
|
+
# @param options [Hash] Hash of paramenters that will be passed along to elasticsearch request
|
32
|
+
# @option [String, nil] :suffix The index suffix. Defaults to the nil.
|
33
|
+
# @option [Array] :index list of serialized documents to be indexed(Optional)
|
34
|
+
# @option [Array] :delete list of serialized documents to be deleted(Optional)
|
35
|
+
# @option [Array] :create list of serialized documents to be created(Optional)
|
36
|
+
# @option [String, NilClass] :type The type of the document (Optional for elasticsearch >= 7)
|
37
|
+
# @return [Hash, nil] the elasticsearch response or nil if there is no data.
|
38
|
+
#
|
39
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/7.5/docs-bulk.html
|
40
|
+
# @see https://github.com/elastic/elasticsearch-ruby/blob/main/elasticsearch-api/lib/elasticsearch/api/utils.rb
|
41
|
+
# @see https://github.com/elastic/elasticsearch-ruby/blob/main/elasticsearch-api/lib/elasticsearch/api/actions/bulk.rb
|
42
|
+
def bulk(index: nil, delete: nil, create: nil, type: nil, suffix: nil, **options)
|
43
|
+
definition = {
|
44
|
+
index: index_name(suffix: suffix),
|
45
|
+
}.merge(options)
|
46
|
+
definition[:type] = type if document_type?
|
47
|
+
|
48
|
+
Esse::Import::Bulk.new(
|
49
|
+
index: index,
|
50
|
+
delete: delete,
|
51
|
+
create: create,
|
52
|
+
).each_request do |request_body|
|
53
|
+
Esse::Events.instrument('elasticsearch.bulk') do |payload|
|
54
|
+
payload[:request] = definition.merge(body_stats: request_body.stats)
|
55
|
+
payload[:response] = resp = coerce_exception { client.bulk(**definition, body: request_body.body) }
|
56
|
+
# @todo move it to a BulkRequest class
|
57
|
+
if resp&.[]('errors')
|
58
|
+
payload[:error] = resp['errors']
|
59
|
+
raise resp&.fetch('items', [])&.select { |item| item.values.first['error'] }.join("\n")
|
60
|
+
end
|
61
|
+
if bulk_wait_interval > 0
|
62
|
+
payload[:wait_interval] = bulk_wait_interval
|
63
|
+
sleep(bulk_wait_interval)
|
64
|
+
else
|
65
|
+
payload[:wait_interval] = 0.0
|
66
|
+
end
|
67
|
+
resp
|
68
|
+
end
|
16
69
|
end
|
17
70
|
end
|
71
|
+
alias_method :bulk!, :bulk
|
72
|
+
|
73
|
+
# Adds a JSON document to the specified index and makes it searchable. If the document
|
74
|
+
# already exists, updates the document and increments its version.
|
75
|
+
#
|
76
|
+
# UsersIndex::User.index(id: 1, body: { name: 'name' }) # { '_id' => 1, ...}
|
77
|
+
#
|
78
|
+
# @param options [Hash] Hash of paramenters that will be passed along to elasticsearch request
|
79
|
+
# @option [String, Integer] :id The `_id` of the elasticsearch document
|
80
|
+
# @option [Hash] :body The JSON document that will be indexed (Required)
|
81
|
+
# @option [String, NilClass] :type The type of the document (Optional for elasticsearch >= 7)
|
82
|
+
# @option [String, nil] :suffix The index suffix. Defaults to the nil.
|
83
|
+
# @return [Hash] the elasticsearch response Hash
|
84
|
+
#
|
85
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/7.5/docs-index_.html
|
86
|
+
# @todo update to allow serialized document as parameter
|
87
|
+
def index(id:, body:, type: nil, suffix: nil, **options)
|
88
|
+
params = {
|
89
|
+
index: index_name(suffix: suffix),
|
90
|
+
id: id,
|
91
|
+
body: body,
|
92
|
+
}
|
93
|
+
params[:type] = type if document_type?
|
94
|
+
coerce_exception { client.index(**options, **params) }
|
95
|
+
end
|
96
|
+
alias_method :index!, :index
|
97
|
+
|
98
|
+
# Updates a document using the specified script.
|
99
|
+
#
|
100
|
+
# UsersIndex::User.update!(id: 1, body: { doc: { ... } }) # { '_id' => 1, ...}
|
101
|
+
#
|
102
|
+
# @param options [Hash] Hash of paramenters that will be passed along to elasticsearch request
|
103
|
+
# @option [String, Integer] :id The `_id` of the elasticsearch document
|
104
|
+
# @option [Hash] :body the body of the request
|
105
|
+
# @option [String, NilClass] :type The type of the document (Optional for elasticsearch >= 7)
|
106
|
+
# @option [String, nil] :suffix The index suffix. Defaults to the nil.
|
107
|
+
# @raise [Esse::Backend::NotFoundError] when the doc does not exist
|
108
|
+
# @return [Hash] elasticsearch response hash
|
109
|
+
#
|
110
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/7.5/docs-update.html
|
111
|
+
# @todo update to allow serialized document as parameter
|
112
|
+
def update!(id:, body:, type: nil, suffix: nil, **options)
|
113
|
+
params = {
|
114
|
+
index: index_name(suffix: suffix),
|
115
|
+
id: id,
|
116
|
+
body: body,
|
117
|
+
}
|
118
|
+
params[:type] = type if document_type?
|
119
|
+
coerce_exception { client.update(**options, **params) }
|
120
|
+
end
|
121
|
+
|
122
|
+
# Updates a document using the specified script.
|
123
|
+
#
|
124
|
+
# UsersIndex::User.update(id: 1, body: { doc: { ... } }) # { '_id' => 1, ...}
|
125
|
+
#
|
126
|
+
# @param options [Hash] Hash of paramenters that will be passed along to elasticsearch request
|
127
|
+
# @option [String, Integer] :id The `_id` of the elasticsearch document
|
128
|
+
# @option [String, NilClass] :type The type of the document (Optional for elasticsearch >= 7)
|
129
|
+
# @option [Hash] :body the body of the request
|
130
|
+
# @option [String, nil] :suffix The index suffix. Defaults to the nil.
|
131
|
+
# @return [Hash] the elasticsearch response, or an hash with 'errors' as true in case of failure
|
132
|
+
#
|
133
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/7.5/docs-update.html
|
134
|
+
# @todo update to allow serialized document as parameter
|
135
|
+
def update(id:, body:, suffix: nil, **options)
|
136
|
+
update!(id: id, body: body, suffix: suffix, **options)
|
137
|
+
rescue NotFoundError
|
138
|
+
{ 'errors' => true }
|
139
|
+
end
|
140
|
+
|
141
|
+
# Removes a JSON document from the specified index.
|
142
|
+
#
|
143
|
+
# UsersIndex::User.delete!(id: 1) # true
|
144
|
+
# UsersIndex::User.delete!(id: 'missing') # raise Esse::Backend::NotFoundError
|
145
|
+
#
|
146
|
+
# @param options [Hash] Hash of paramenters that will be passed along to elasticsearch request
|
147
|
+
# @option [String, Integer] :id The `_id` of the elasticsearch document
|
148
|
+
# @option [String, NilClass] :type The type of the document (Optional for elasticsearch >= 7)
|
149
|
+
# @option [String, nil] :suffix The index suffix. Defaults to the nil.
|
150
|
+
# @raise [Esse::Backend::NotFoundError] when the doc does not exist
|
151
|
+
# @return [Boolean] true when the operation is successfully completed
|
152
|
+
#
|
153
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/7.5/docs-delete.html
|
154
|
+
# @todo update to allow serialized document as parameter
|
155
|
+
def delete!(id:, type: nil, suffix: nil, **options)
|
156
|
+
params = {
|
157
|
+
index: index_name(suffix: suffix),
|
158
|
+
id: id,
|
159
|
+
}
|
160
|
+
params[:type] = type if document_type?
|
161
|
+
coerce_exception { client.delete(**options, **params) }
|
162
|
+
end
|
163
|
+
|
164
|
+
# Removes a JSON document from the specified index.
|
165
|
+
#
|
166
|
+
# UsersIndex::User.delete(id: 1) # true
|
167
|
+
# UsersIndex::User.delete(id: 'missing') # false
|
168
|
+
#
|
169
|
+
# @param options [Hash] Hash of paramenters that will be passed along to elasticsearch request
|
170
|
+
# @option [String, Integer] :id The `_id` of the elasticsearch document
|
171
|
+
# @option [String, NilClass] :type The type of the document (Optional for elasticsearch >= 7)
|
172
|
+
# @option [String, nil] :suffix The index suffix. Defaults to the nil.
|
173
|
+
# @raise [Esse::Backend::NotFoundError] when the doc does not exist
|
174
|
+
# @return [Boolean] true when the operation is successfully completed
|
175
|
+
#
|
176
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/7.5/docs-delete.html
|
177
|
+
# @todo update to allow serialized document as parameter
|
178
|
+
def delete(id:, type: nil, suffix: nil, **options)
|
179
|
+
delete!(id: id, type: type, suffix: suffix, **options)
|
180
|
+
rescue NotFoundError
|
181
|
+
false
|
182
|
+
end
|
183
|
+
|
184
|
+
# Gets the number of matches for a search query.
|
185
|
+
#
|
186
|
+
# UsersIndex::User.count # 999
|
187
|
+
# UsersIndex::User.count(body: { ... }) # 32
|
188
|
+
#
|
189
|
+
# @param options [Hash] Hash of paramenters that will be passed along to elasticsearch request
|
190
|
+
# @option [Hash] :body A query to restrict the results specified with the Query DSL (optional)
|
191
|
+
# @option [String, NilClass] :type The type of the document (Optional for elasticsearch >= 7)
|
192
|
+
# @option [String, nil] :suffix The index suffix. Defaults to the nil.
|
193
|
+
# @return [Integer] amount of documents found
|
194
|
+
#
|
195
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/7.5/search-count.html
|
196
|
+
def count(type: nil, suffix: nil, **options)
|
197
|
+
params = {
|
198
|
+
index: index_name(suffix: suffix),
|
199
|
+
}
|
200
|
+
params[:type] = type if document_type?
|
201
|
+
response = coerce_exception { client.count(**options, **params) }
|
202
|
+
response['count']
|
203
|
+
rescue NotFoundError
|
204
|
+
0
|
205
|
+
end
|
206
|
+
|
207
|
+
# Check if a JSON document exists
|
208
|
+
#
|
209
|
+
# UsersIndex::User.elasticsearch.exist?(id: 1) # true
|
210
|
+
# UsersIndex::User.elasticsearch.exist?(id: 'missing') # false
|
211
|
+
#
|
212
|
+
# @param options [Hash] Hash of paramenters that will be passed along to elasticsearch request
|
213
|
+
# @option [String, Integer] :id The `_id` of the elasticsearch document
|
214
|
+
# @option [String, NilClass] :type The type of the document (Optional for elasticsearch >= 7)
|
215
|
+
# @option [String, nil] :suffix The index suffix. Defaults to the nil.
|
216
|
+
# @return [Boolean] true if the document exists
|
217
|
+
def exist?(id:, type: nil, suffix: nil, **options)
|
218
|
+
params = {
|
219
|
+
index: index_name(suffix: suffix),
|
220
|
+
id: id,
|
221
|
+
}
|
222
|
+
params[:type] = type if document_type?
|
223
|
+
coerce_exception { client.exists(**options, **params) }
|
224
|
+
end
|
225
|
+
|
226
|
+
# Retrieves the specified JSON document from an index.
|
227
|
+
#
|
228
|
+
# UsersIndex::User.find!(id: 1) # { '_id' => 1, ... }
|
229
|
+
# UsersIndex::User.find!(id: 'missing') # raise Esse::Backend::NotFoundError
|
230
|
+
#
|
231
|
+
# @param options [Hash] Hash of paramenters that will be passed along to elasticsearch request
|
232
|
+
# @option [String, Integer] :id The `_id` of the elasticsearch document
|
233
|
+
# @option [String, NilClass] :type The type of the document (Optional for elasticsearch >= 7)
|
234
|
+
# @option [String, nil] :suffix The index suffix. Defaults to the nil.
|
235
|
+
# @raise [Esse::Backend::NotFoundError] when the doc does not exist
|
236
|
+
# @return [Hash] The elasticsearch document.
|
237
|
+
#
|
238
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/7.5/docs-get.html
|
239
|
+
def find!(id:, type: nil, suffix: nil, **options)
|
240
|
+
params = {
|
241
|
+
index: index_name(suffix: suffix),
|
242
|
+
id: id,
|
243
|
+
}
|
244
|
+
params[:type] = type if document_type?
|
245
|
+
coerce_exception { client.get(**options, **params) }
|
246
|
+
end
|
247
|
+
|
248
|
+
# Retrieves the specified JSON document from an index.
|
249
|
+
#
|
250
|
+
# UsersIndex::User.find(id: 1) # { '_id' => 1, ... }
|
251
|
+
# UsersIndex::User.find(id: 'missing') # nil
|
252
|
+
#
|
253
|
+
# @param options [Hash] Hash of paramenters that will be passed along to elasticsearch request
|
254
|
+
# @option [String, Integer] :id The `_id` of the elasticsearch document
|
255
|
+
# @option [String, NilClass] :type The type of the document (Optional for elasticsearch >= 7)
|
256
|
+
# @option [String, nil] :suffix The index suffix. Defaults to the nil.
|
257
|
+
# @return [Hash, nil] The elasticsearch document
|
258
|
+
#
|
259
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/7.5/docs-get.html
|
260
|
+
def find(id:, suffix: nil, **options)
|
261
|
+
find!(id: id, suffix: suffix, **options)
|
262
|
+
rescue NotFoundError
|
263
|
+
nil
|
264
|
+
end
|
18
265
|
end
|
19
266
|
|
20
267
|
include InstanceMethods
|
@@ -6,13 +6,13 @@ module Esse
|
|
6
6
|
module InstanceMethods
|
7
7
|
# Checks the index existance. Returns true or false
|
8
8
|
#
|
9
|
-
# UsersIndex.elasticsearch.
|
9
|
+
# UsersIndex.elasticsearch.index_exist? #=> true
|
10
10
|
#
|
11
11
|
# @param options [Hash] Options hash
|
12
12
|
# @option options [String, nil] :suffix The index suffix. Defaults to the index_version.
|
13
13
|
# Use nil if you want to check existence of the `index_name` index or alias.
|
14
|
-
def
|
15
|
-
client.indices.exists(index: index_name(suffix: suffix))
|
14
|
+
def index_exist?(suffix: index_version)
|
15
|
+
coerce_exception { client.indices.exists(index: index_name(suffix: suffix)) }
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
@@ -15,7 +15,7 @@ module Esse
|
|
15
15
|
# @option options [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
|
16
16
|
# unavailable (missing, closed, etc)
|
17
17
|
# @option options [Time] :timeout Explicit operation timeout
|
18
|
-
# @raise [
|
18
|
+
# @raise [Esse::Backend::ServerError]
|
19
19
|
# in case of failure
|
20
20
|
# @return [Hash] the elasticsearch response
|
21
21
|
#
|
@@ -23,7 +23,7 @@ module Esse
|
|
23
23
|
def open!(suffix: index_version, **options)
|
24
24
|
Esse::Events.instrument('elasticsearch.open') do |payload|
|
25
25
|
payload[:request] = attributes = options.merge(index: index_name(suffix: suffix))
|
26
|
-
payload[:response] = client.indices.open(**attributes)
|
26
|
+
payload[:response] = coerce_exception { client.indices.open(**attributes) }
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -43,7 +43,7 @@ module Esse
|
|
43
43
|
# @see https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-open-open.html
|
44
44
|
def open(suffix: index_version, **options)
|
45
45
|
open!(suffix: suffix, **options)
|
46
|
-
rescue
|
46
|
+
rescue ServerError
|
47
47
|
{ 'errors' => true }
|
48
48
|
end
|
49
49
|
end
|
@@ -10,15 +10,17 @@ module Esse
|
|
10
10
|
# @param :suffix [String, nil] :suffix The index suffix. Defaults to the index_version.
|
11
11
|
# A uniq index name will be generated if one index already exist with the given alias.
|
12
12
|
# @param options [Hash] Options hash
|
13
|
-
# @raise [
|
13
|
+
# @raise [Esse::Backend::ServerError]
|
14
14
|
# in case of failure
|
15
15
|
# @return [Hash] the elasticsearch response
|
16
16
|
#
|
17
17
|
# @see https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-refresh.html
|
18
18
|
def refresh!(suffix: index_version, **options)
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
coerce_exception do
|
20
|
+
client.indices.refresh(
|
21
|
+
options.merge(index: index_name(suffix: suffix)),
|
22
|
+
)
|
23
|
+
end
|
22
24
|
end
|
23
25
|
|
24
26
|
# Performs the refresh operation in one or more indices.
|
@@ -32,7 +34,7 @@ module Esse
|
|
32
34
|
# @see https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-refresh.html
|
33
35
|
def refresh(suffix: index_version, **options)
|
34
36
|
refresh!(suffix: suffix, **options)
|
35
|
-
rescue
|
37
|
+
rescue ServerError
|
36
38
|
{ 'errors' => true }
|
37
39
|
end
|
38
40
|
end
|
@@ -9,18 +9,18 @@ module Esse
|
|
9
9
|
# @option options [String, nil] :suffix The index suffix. Defaults to the index_version.
|
10
10
|
# A uniq index name will be generated if one index already exist with the given alias.
|
11
11
|
# @option options [Time] :timeout Explicit operation timeout
|
12
|
-
# @raise [
|
12
|
+
# @raise [Esse::Backend::ServerError]
|
13
13
|
# in case of failure
|
14
14
|
# @return [Hash] the elasticsearch response
|
15
15
|
#
|
16
16
|
# @see https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-open-close.html
|
17
|
-
def reset_index!(suffix: index_version, **options)
|
17
|
+
def reset_index!(suffix: index_version, import: true, **options)
|
18
18
|
existing = []
|
19
19
|
suffix ||= Esse.timestamp
|
20
|
-
suffix = Esse.timestamp while
|
20
|
+
suffix = Esse.timestamp while index_exist?(suffix: suffix).tap { |exist| existing << suffix if exist }
|
21
21
|
|
22
22
|
create_index!(**options, suffix: suffix, alias: false)
|
23
|
-
import!(**options, suffix: suffix)
|
23
|
+
import!(**options, suffix: suffix) if import
|
24
24
|
update_aliases!(suffix: suffix)
|
25
25
|
existing.each { |_s| delete_index!(**options, suffix: suffix) }
|
26
26
|
true
|
@@ -21,7 +21,7 @@ module Esse
|
|
21
21
|
# with the same name across all types
|
22
22
|
# @option options [Time] :timeout Explicit operation timeout
|
23
23
|
# @option options [Boolean] :master_timeout Timeout for connection to master
|
24
|
-
# @raise [
|
24
|
+
# @raise [Esse::Backend::ServerError]
|
25
25
|
# in case of failure
|
26
26
|
# @return [Hash] the elasticsearch response
|
27
27
|
#
|
@@ -33,7 +33,7 @@ module Esse
|
|
33
33
|
body = body[type.to_s] || body[type.to_sym]
|
34
34
|
end
|
35
35
|
payload[:request] = opts = options.merge(index: index_name(suffix: suffix), body: body)
|
36
|
-
payload[:response] = client.indices.put_mapping(**opts)
|
36
|
+
payload[:response] = coerce_exception { client.indices.put_mapping(**opts) }
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -59,7 +59,7 @@ module Esse
|
|
59
59
|
# @see http://www.elasticsearch.org/guide/reference/api/admin-indices-put-mapping/
|
60
60
|
def update_mapping(suffix: index_version, **options)
|
61
61
|
update_mapping!(suffix: suffix, **options)
|
62
|
-
rescue
|
62
|
+
rescue ServerError
|
63
63
|
{ 'errors' => true }
|
64
64
|
end
|
65
65
|
|
@@ -76,7 +76,7 @@ module Esse
|
|
76
76
|
# If set to `true` existing settings on an index remain unchanged, the default is `false`
|
77
77
|
# @option options [Time] :master_timeout Specify timeout for connection to master
|
78
78
|
# @option options [Boolean] :flat_settings Return settings in flat format (default: false)
|
79
|
-
# @raise [
|
79
|
+
# @raise [Esse::Backend::ServerError]
|
80
80
|
# in case of failure
|
81
81
|
# @return [Hash] the elasticsearch response
|
82
82
|
#
|
@@ -93,7 +93,7 @@ module Esse
|
|
93
93
|
# closed index might prevent the index to be opened correctly again.
|
94
94
|
Esse::Events.instrument('elasticsearch.update_settings') do |payload|
|
95
95
|
payload[:request] = opts = options.merge(index: index_name(suffix: suffix), body: { index: settings })
|
96
|
-
payload[:response] = response = client.indices.put_settings(**opts)
|
96
|
+
payload[:response] = response = coerce_exception { client.indices.put_settings(**opts) }
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
@@ -104,7 +104,7 @@ module Esse
|
|
104
104
|
begin
|
105
105
|
Esse::Events.instrument('elasticsearch.update_settings') do |payload|
|
106
106
|
payload[:request] = opts = options.merge(index: index_name(suffix: suffix), body: { analysis: analysis })
|
107
|
-
payload[:response] = response = client.indices.put_settings(**opts)
|
107
|
+
payload[:response] = response = coerce_exception { client.indices.put_settings(**opts) }
|
108
108
|
end
|
109
109
|
ensure
|
110
110
|
open!(suffix: suffix)
|
@@ -132,7 +132,7 @@ module Esse
|
|
132
132
|
# @see http://www.elasticsearch.org/guide/reference/api/admin-indices-update-settings/
|
133
133
|
def update_settings(suffix: index_version, **options)
|
134
134
|
update_settings!(suffix: suffix, **options)
|
135
|
-
rescue
|
135
|
+
rescue ServerError
|
136
136
|
{ 'errors' => true }
|
137
137
|
end
|
138
138
|
end
|
data/lib/esse/backend/index.rb
CHANGED
@@ -20,8 +20,10 @@ module Esse
|
|
20
20
|
|
21
21
|
NAMING = %i[index_version].freeze
|
22
22
|
DEFINITION = %i[settings_hash mappings_hash].freeze
|
23
|
+
DOCUMENTS = %i[each_serialized_batch].freeze
|
23
24
|
|
24
|
-
def_delegators :@index, :
|
25
|
+
def_delegators :@index, :index_name, :cluster, :repo_hash, :bulk_wait_interval, *(NAMING + DEFINITION + DOCUMENTS)
|
26
|
+
def_delegators :cluster, :document_type?, :client
|
25
27
|
|
26
28
|
def initialize(index)
|
27
29
|
@index = index
|
@@ -29,25 +31,25 @@ module Esse
|
|
29
31
|
|
30
32
|
protected
|
31
33
|
|
32
|
-
def index_name(suffix: nil)
|
33
|
-
suffix = Hstring.new(suffix).underscore.presence
|
34
|
-
return @index.index_name unless suffix
|
35
|
-
|
36
|
-
[@index.index_name, suffix].join('_')
|
37
|
-
end
|
38
|
-
|
39
34
|
def build_real_index_name(suffix = nil)
|
40
35
|
suffix = Hstring.new(suffix).underscore.presence || index_version || Esse.timestamp
|
41
36
|
|
42
37
|
index_name(suffix: suffix)
|
43
38
|
end
|
44
39
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
40
|
+
# Elasticsearch::Transport was renamed to Elastic::Transport in 8.0
|
41
|
+
# This lib should support both versions that's why we are wrapping up the transport
|
42
|
+
# errors to local errors.
|
43
|
+
def coerce_exception
|
44
|
+
yield
|
45
|
+
rescue => exception
|
46
|
+
name = Hstring.new(exception.class.name)
|
47
|
+
if /^(Elasticsearch|Elastic|OpenSearch)?::Transport::Transport::Errors/.match?(name.value) && \
|
48
|
+
(exception_class = ERRORS[name.demodulize.value])
|
49
|
+
raise exception_class.new(exception.message)
|
50
|
+
else
|
51
|
+
raise exception
|
52
|
+
end
|
51
53
|
end
|
52
54
|
end
|
53
55
|
end
|