esse 0.2.0 → 0.2.3
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/cli/event_listener.rb +13 -0
- data/lib/esse/cli/generate.rb +53 -14
- data/lib/esse/cli/index/base_operation.rb +5 -13
- data/lib/esse/cli/index/close.rb +1 -1
- data/lib/esse/cli/index/create.rb +1 -1
- data/lib/esse/cli/index/delete.rb +1 -1
- data/lib/esse/cli/index/import.rb +6 -2
- data/lib/esse/cli/index/open.rb +1 -1
- data/lib/esse/cli/index/reset.rb +1 -1
- data/lib/esse/cli/index/update_aliases.rb +2 -2
- data/lib/esse/cli/index/update_mapping.rb +9 -5
- data/lib/esse/cli/index/update_settings.rb +1 -1
- data/lib/esse/cli/index.rb +11 -4
- data/lib/esse/cli/templates/collection.rb.erb +29 -0
- data/lib/esse/cli/templates/config.rb.erb +13 -3
- data/lib/esse/cli/templates/document.rb.erb +34 -0
- data/lib/esse/cli/templates/index.rb.erb +63 -114
- data/lib/esse/cli/templates/mappings.json +27 -0
- data/lib/esse/cli/templates/settings.json +62 -0
- data/lib/esse/cli.rb +5 -0
- data/lib/esse/cluster.rb +93 -12
- 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 +28 -7
- data/lib/esse/deprecations/cluster.rb +27 -0
- data/lib/esse/deprecations/deprecate.rb +29 -0
- data/lib/esse/deprecations/index.rb +37 -0
- data/lib/esse/deprecations/index_backend_delegator.rb +217 -0
- data/lib/esse/deprecations/repository.rb +34 -0
- data/lib/esse/deprecations/repository_backend_delegator.rb +110 -0
- data/lib/esse/deprecations/serializer.rb +14 -0
- data/lib/esse/deprecations.rb +7 -0
- data/lib/esse/document.rb +91 -0
- data/lib/esse/dynamic_template.rb +43 -0
- data/lib/esse/errors.rb +60 -2
- data/lib/esse/events/event.rb +4 -19
- data/lib/esse/events.rb +13 -2
- data/lib/esse/hash_document.rb +38 -0
- data/lib/esse/import/bulk.rb +106 -0
- data/lib/esse/import/request_body.rb +60 -0
- data/lib/esse/index/aliases.rb +50 -0
- data/lib/esse/index/attributes.rb +107 -0
- data/lib/esse/index/base.rb +17 -53
- data/lib/esse/index/documents.rb +236 -0
- data/lib/esse/index/indices.rb +171 -0
- data/lib/esse/index/inheritance.rb +30 -0
- data/lib/esse/index/mappings.rb +6 -19
- data/lib/esse/index/object_document_mapper.rb +36 -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 +51 -11
- data/lib/esse/index.rb +14 -9
- 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/repository/documents.rb +13 -0
- data/lib/esse/repository/object_document_mapper.rb +157 -0
- data/lib/esse/repository.rb +17 -0
- data/lib/esse/search/query.rb +105 -0
- data/lib/esse/search/response.rb +46 -0
- data/lib/esse/template_loader.rb +1 -1
- data/lib/esse/transport/aliases.rb +36 -0
- data/lib/esse/transport/documents.rb +199 -0
- data/lib/esse/transport/health.rb +30 -0
- data/lib/esse/transport/indices.rb +192 -0
- data/lib/esse/transport/search.rb +48 -0
- data/lib/esse/transport.rb +44 -0
- data/lib/esse/version.rb +1 -1
- data/lib/esse.rb +20 -5
- metadata +55 -50
- data/lib/esse/backend/index/aliases.rb +0 -73
- data/lib/esse/backend/index/close.rb +0 -54
- data/lib/esse/backend/index/create.rb +0 -67
- data/lib/esse/backend/index/delete.rb +0 -39
- data/lib/esse/backend/index/documents.rb +0 -23
- data/lib/esse/backend/index/existance.rb +0 -22
- data/lib/esse/backend/index/open.rb +0 -54
- data/lib/esse/backend/index/refresh.rb +0 -43
- data/lib/esse/backend/index/reset.rb +0 -33
- data/lib/esse/backend/index/update.rb +0 -143
- data/lib/esse/backend/index.rb +0 -54
- 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_collection.rb.erb +0 -41
- 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/backend.rb +0 -14
- data/lib/esse/index/naming.rb +0 -64
- data/lib/esse/index_type/backend.rb +0 -14
- 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
@@ -0,0 +1,171 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Esse
|
4
|
+
class Index
|
5
|
+
module ClassMethods
|
6
|
+
CREATE_INDEX_RESERVED_KEYWORDS = {
|
7
|
+
alias: true,
|
8
|
+
}.freeze
|
9
|
+
|
10
|
+
# Creates index and applies mappings and settings.
|
11
|
+
#
|
12
|
+
# UsersIndex.create_index # creates index named `<cluster.index_prefix>users<index_suffix>`
|
13
|
+
#
|
14
|
+
# @param options [Hash] Options hash
|
15
|
+
# @option options [Boolean] :alias Update `index_name` alias along with the new index
|
16
|
+
# @option options [String] :suffix The index suffix. Defaults to the `IndexClass#index_suffix` or
|
17
|
+
# `Esse.timestamp`. Suffixed index names might be used for zero-downtime mapping change.
|
18
|
+
# @option arguments [String] :wait_for_active_shards Set the number of active shards
|
19
|
+
# to wait for before the operation returns.
|
20
|
+
# @option arguments [Time] :timeout Explicit operation timeout
|
21
|
+
# @option arguments [Time] :master_timeout Specify timeout for connection to master
|
22
|
+
# @option arguments [Hash] :headers Custom HTTP headers
|
23
|
+
# @option arguments [Hash] :body The configuration for the index (`settings` and `mappings`)
|
24
|
+
# @raise [Esse::Transport::NotFoundError] when index already exists
|
25
|
+
# @return [Hash] the elasticsearch response
|
26
|
+
#
|
27
|
+
# @see http://www.elasticsearch.org/blog/changing-mapping-with-zero-downtime/
|
28
|
+
# @see Esse::Transport#create_index
|
29
|
+
def create_index(suffix: nil, **options)
|
30
|
+
options = CREATE_INDEX_RESERVED_KEYWORDS.merge(options)
|
31
|
+
name = build_real_index_name(suffix)
|
32
|
+
definition = [settings_hash, mappings_hash].reduce(&:merge)
|
33
|
+
|
34
|
+
if options.delete(:alias) && name != index_name
|
35
|
+
definition[:aliases] = { index_name => {} }
|
36
|
+
end
|
37
|
+
|
38
|
+
cluster.api.create_index(index: name, body: definition, **options)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Deletes, creates and imports data to the index. Performs zero-downtime index resetting.
|
42
|
+
#
|
43
|
+
# @option options [String, nil] :suffix The index suffix. Defaults to the index_suffix.
|
44
|
+
# A uniq index name will be generated if one index already exist with the given alias.
|
45
|
+
# @option options [Time] :timeout Explicit operation timeout
|
46
|
+
# @raise [Esse::Transport::ServerError]
|
47
|
+
# in case of failure
|
48
|
+
# @return [Hash] the elasticsearch response
|
49
|
+
#
|
50
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-open-close.html
|
51
|
+
def reset_index(suffix: index_suffix, import: true, reindex: false, **options)
|
52
|
+
cluster.throw_error_when_readonly!
|
53
|
+
existing = []
|
54
|
+
suffix ||= Esse.timestamp
|
55
|
+
suffix = Esse.timestamp while index_exist?(suffix: suffix).tap { |exist| existing << suffix if exist }
|
56
|
+
|
57
|
+
create_index(**options, suffix: suffix, alias: false)
|
58
|
+
if index_exist? && aliases.none?
|
59
|
+
cluster.api.delete_index(index: index_name)
|
60
|
+
end
|
61
|
+
if import
|
62
|
+
import(**options, suffix: suffix)
|
63
|
+
elsif reindex && (_from = indices_pointing_to_alias).any?
|
64
|
+
# @TODO: Reindex using the reindex API
|
65
|
+
end
|
66
|
+
update_aliases(suffix: suffix)
|
67
|
+
existing.each { |_s| delete_index!(**options, suffix: suffix) }
|
68
|
+
true
|
69
|
+
end
|
70
|
+
|
71
|
+
# Checks the index existance. Returns true or false
|
72
|
+
#
|
73
|
+
# UsersIndex.index_exist? #=> true
|
74
|
+
#
|
75
|
+
# @param options [Hash] Options hash
|
76
|
+
# @option options [String, nil] :suffix The index suffix
|
77
|
+
# @see Esse::Transport#index_exist?
|
78
|
+
def index_exist?(suffix: nil)
|
79
|
+
cluster.api.index_exist?(index: index_name(suffix: suffix))
|
80
|
+
end
|
81
|
+
|
82
|
+
# Deletes an existing index.
|
83
|
+
#
|
84
|
+
# UsersIndex.delete_index # deletes `<cluster.index_prefix>users<index_suffix>` index
|
85
|
+
#
|
86
|
+
# @param suffix [String, nil] The index suffix Use nil if you want to delete the current index.
|
87
|
+
# @raise [Esse::Transport::NotFoundError] when index does not exists
|
88
|
+
# @return [Hash] elasticsearch response
|
89
|
+
def delete_index(suffix: nil, **options)
|
90
|
+
index = suffix ? index_name(suffix: suffix) : indices_pointing_to_alias.first
|
91
|
+
index ||= index_name
|
92
|
+
cluster.api.delete_index(**options, index: index)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Open a previously closed index
|
96
|
+
#
|
97
|
+
# @option options [String, nil] :suffix The index suffix
|
98
|
+
# @see Esse::Transport#open
|
99
|
+
def open(suffix: nil, **options)
|
100
|
+
cluster.api.open(index: index_name(suffix: suffix), **options)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Close an index (keep the data on disk, but deny operations with the index).
|
104
|
+
#
|
105
|
+
# @option options [String, nil] :suffix The index suffix
|
106
|
+
# @see Esse::Transport#close
|
107
|
+
def close(suffix: nil, **options)
|
108
|
+
cluster.api.close(index: index_name(suffix: suffix), **options)
|
109
|
+
end
|
110
|
+
|
111
|
+
# Performs the refresh operation in one or more indices.
|
112
|
+
#
|
113
|
+
# @note The refresh operation can adversely affect indexing throughput when used too frequently.
|
114
|
+
# @param :suffix [String, nil] :suffix The index suffix
|
115
|
+
# @see Esse::Transport#refresh
|
116
|
+
def refresh(suffix: nil, **options)
|
117
|
+
cluster.api.refresh(index: index_name(suffix: suffix), **options)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Updates index mappings
|
121
|
+
#
|
122
|
+
# @param :suffix [String, nil] :suffix The index suffix
|
123
|
+
# @see Esse::Transport#update_mapping
|
124
|
+
def update_mapping(suffix: nil, **options)
|
125
|
+
body = mappings_hash.fetch(Esse::MAPPING_ROOT_KEY)
|
126
|
+
if (type = options[:type])
|
127
|
+
# Elasticsearch <= 5.x should submit request with type both in the path and in the body
|
128
|
+
# Elasticsearch 6.x should submit request with type in the path but not in the body
|
129
|
+
# Elasticsearch >= 7.x does not support type in the mapping
|
130
|
+
body = body[type.to_s] || body[type.to_sym] || body
|
131
|
+
end
|
132
|
+
cluster.api.update_mapping(index: index_name(suffix: suffix), body: body, **options)
|
133
|
+
end
|
134
|
+
|
135
|
+
# Updates index settings
|
136
|
+
#
|
137
|
+
# @param :suffix [String, nil] :suffix The index suffix
|
138
|
+
# @see Esse::Transport#update_settings
|
139
|
+
def update_settings(suffix: nil, **options)
|
140
|
+
response = nil
|
141
|
+
|
142
|
+
settings = HashUtils.deep_transform_keys(settings_hash.fetch(Esse::SETTING_ROOT_KEY), &:to_s)
|
143
|
+
if options[:body]
|
144
|
+
settings = settings.merge(HashUtils.deep_transform_keys(options.delete(:body), &:to_s))
|
145
|
+
end
|
146
|
+
settings.delete('number_of_shards') # Can't change number of shards for an index
|
147
|
+
settings['index']&.delete('number_of_shards')
|
148
|
+
analysis = settings.delete('analysis')
|
149
|
+
|
150
|
+
if settings.any?
|
151
|
+
response = cluster.api.update_settings(index: index_name(suffix: suffix), body: settings, **options)
|
152
|
+
end
|
153
|
+
|
154
|
+
if analysis
|
155
|
+
# It is also possible to define new analyzers for the index. But it is required to close the
|
156
|
+
# index first and open it after the changes are made.
|
157
|
+
close(suffix: suffix)
|
158
|
+
begin
|
159
|
+
response = cluster.api.update_settings(index: index_name(suffix: suffix), body: { analysis: analysis }, **options)
|
160
|
+
ensure
|
161
|
+
self.open(suffix: suffix)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
response
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
extend ClassMethods
|
170
|
+
end
|
171
|
+
end
|
@@ -11,6 +11,36 @@ module Esse
|
|
11
11
|
|
12
12
|
!index_name?
|
13
13
|
end
|
14
|
+
|
15
|
+
def inherited(subclass)
|
16
|
+
super
|
17
|
+
|
18
|
+
inherited_instance_variables.each do |variable_name, should_duplicate|
|
19
|
+
if (variable_value = instance_variable_get(variable_name)) && should_duplicate
|
20
|
+
value = case variable_value
|
21
|
+
when Hash
|
22
|
+
h = {}
|
23
|
+
variable_value.each { |k, v| h[k] = v.dup }
|
24
|
+
h
|
25
|
+
else
|
26
|
+
variable_value.dup
|
27
|
+
end
|
28
|
+
end
|
29
|
+
subclass.instance_variable_set(variable_name, value)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def inherited_instance_variables
|
36
|
+
{
|
37
|
+
:@repo_hash => nil,
|
38
|
+
:@setting => nil,
|
39
|
+
:@mapping => nil,
|
40
|
+
:@cluster_id => :dup,
|
41
|
+
:@plugins => :dup,
|
42
|
+
}
|
43
|
+
end
|
14
44
|
end
|
15
45
|
|
16
46
|
extend ClassMethods
|
data/lib/esse/index/mappings.rb
CHANGED
@@ -7,36 +7,23 @@
|
|
7
7
|
module Esse
|
8
8
|
class Index
|
9
9
|
module ClassMethods
|
10
|
-
# This is the actually content that will be passed through the ES api
|
11
|
-
def mappings_hash
|
12
|
-
{ Esse::MAPPING_ROOT_KEY => (index_mapping || type_mapping) }
|
13
|
-
end
|
14
|
-
|
15
10
|
# This method is only used to define mapping
|
16
11
|
def mappings(hash = {}, &block)
|
17
|
-
@mapping = Esse::IndexMapping.new(body: hash, paths: template_dirs)
|
12
|
+
@mapping = Esse::IndexMapping.new(body: hash, paths: template_dirs, globals: -> { cluster.mappings })
|
18
13
|
return unless block
|
19
14
|
|
20
15
|
@mapping.define_singleton_method(:to_h, &block)
|
21
16
|
end
|
22
17
|
|
23
|
-
|
24
|
-
|
25
|
-
def mapping
|
26
|
-
@mapping ||= Esse::IndexMapping.new(paths: template_dirs)
|
27
|
-
end
|
28
|
-
|
29
|
-
def index_mapping
|
30
|
-
return if mapping.empty?
|
31
|
-
|
18
|
+
def mappings_hash
|
32
19
|
hash = mapping.body
|
33
|
-
hash.key?(Esse::MAPPING_ROOT_KEY) ? hash[Esse::MAPPING_ROOT_KEY] : hash
|
20
|
+
{ Esse::MAPPING_ROOT_KEY => (hash.key?(Esse::MAPPING_ROOT_KEY) ? hash[Esse::MAPPING_ROOT_KEY] : hash) }
|
34
21
|
end
|
35
22
|
|
36
|
-
|
37
|
-
return {} if type_hash.empty?
|
23
|
+
private
|
38
24
|
|
39
|
-
|
25
|
+
def mapping
|
26
|
+
@mapping ||= Esse::IndexMapping.new(paths: template_dirs, globals: -> { cluster.mappings })
|
40
27
|
end
|
41
28
|
end
|
42
29
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Esse
|
4
|
+
class Index
|
5
|
+
module ObjectDocumentMapper
|
6
|
+
# Wrap collection data into serialized batches
|
7
|
+
#
|
8
|
+
# @param [String, NilClass] repo_name The repository identifier
|
9
|
+
# @param [Hash] kwargs The context
|
10
|
+
# @return [Enumerator] The enumerator
|
11
|
+
# @yield [Array, **context] serialized collection and the optional context from the collection
|
12
|
+
def each_serialized_batch(repo_name = nil, **kwargs, &block)
|
13
|
+
(repo_name ? [repo(repo_name)] : repo_hash.values).each do |repo|
|
14
|
+
repo.each_serialized_batch(**kwargs, &block)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Wrap collection data into serialized documents
|
19
|
+
#
|
20
|
+
# Example:
|
21
|
+
# GeosIndex.documents(id: 1).first
|
22
|
+
#
|
23
|
+
# @param [String, NilClass] repo_name The repository identifier
|
24
|
+
# @return [Enumerator] All serialized entries
|
25
|
+
def documents(repo_name = nil, **kwargs)
|
26
|
+
Enumerator.new do |yielder|
|
27
|
+
each_serialized_batch(repo_name, **kwargs) do |documents, **_collection_kargs|
|
28
|
+
documents.each { |document| yielder.yield(document) }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
extend ObjectDocumentMapper
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Esse
|
4
|
+
class Index
|
5
|
+
module ClassMethods
|
6
|
+
attr_reader :plugins
|
7
|
+
|
8
|
+
def plugin(plugin, **kwargs, &block)
|
9
|
+
mod = plugin.is_a?(Module) ? plugin : load_plugin_module(plugin)
|
10
|
+
|
11
|
+
unless @plugins.include?(mod)
|
12
|
+
@plugins << mod
|
13
|
+
mod.apply(self, **kwargs, &block) if mod.respond_to?(:apply)
|
14
|
+
extend(mod::IndexClassMethods) if mod.const_defined?(:IndexClassMethods, false)
|
15
|
+
if mod.const_defined?(:RepositoryClassMethods, false)
|
16
|
+
repo_hash.each_value.each { |repo| repository_plugin_extend(repo, mod::RepositoryClassMethods) }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
mod.configure(self, **kwargs, &block) if mod.respond_to?(:configure)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def repository_plugin_extend(repo_class, mod)
|
26
|
+
return if repo_class.singleton_class.included_modules.include?(mod)
|
27
|
+
|
28
|
+
repo_class.extend(mod)
|
29
|
+
end
|
30
|
+
|
31
|
+
def load_plugin_module(name)
|
32
|
+
module_name = Hstring.new(name)
|
33
|
+
unless Esse::Plugins.const_defined?(module_name.camelize.to_s, false)
|
34
|
+
require "esse/plugins/#{module_name.underscore}"
|
35
|
+
end
|
36
|
+
Esse::Plugins.const_get(module_name.camelize.to_s)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
extend ClassMethods
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Esse
|
4
|
+
class Index
|
5
|
+
module ClassMethods
|
6
|
+
# @param query_or_payload [String,Hash] The search request definition or query in the Lucene query string syntax
|
7
|
+
# @param kwargs [Hash] The options to pass to the search.
|
8
|
+
def search(*args, &block)
|
9
|
+
query_or_payload = args.shift
|
10
|
+
kwargs = args.last.is_a?(Hash) ? args.pop : {}
|
11
|
+
|
12
|
+
if query_or_payload.respond_to?(:to_hash) && (hash = query_or_payload.to_hash) && (hash.key?(:body) || hash.key?('body') || hash.key?(:q) || hash.key?('q'))
|
13
|
+
kwargs.merge!(hash.transform_keys(&:to_sym))
|
14
|
+
elsif query_or_payload.respond_to?(:to_hash)
|
15
|
+
kwargs[:body] = query_or_payload.to_hash
|
16
|
+
elsif query_or_payload.is_a?(String) && query_or_payload =~ /^\s*{/
|
17
|
+
kwargs[:body] = MultiJson.load(query_or_payload)
|
18
|
+
elsif query_or_payload.is_a?(String)
|
19
|
+
kwargs[:q] = query_or_payload
|
20
|
+
end
|
21
|
+
cluster.search(self, **kwargs, &block)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
extend ClassMethods
|
26
|
+
end
|
27
|
+
end
|
data/lib/esse/index/settings.rb
CHANGED
@@ -28,7 +28,7 @@ module Esse
|
|
28
28
|
# end
|
29
29
|
# end
|
30
30
|
def settings(hash = {}, &block)
|
31
|
-
@setting = Esse::IndexSetting.new(body: hash, paths: template_dirs, globals: -> { cluster.
|
31
|
+
@setting = Esse::IndexSetting.new(body: hash, paths: template_dirs, globals: -> { cluster.settings })
|
32
32
|
return unless block
|
33
33
|
|
34
34
|
@setting.define_singleton_method(:to_h, &block)
|
@@ -37,7 +37,7 @@ module Esse
|
|
37
37
|
private
|
38
38
|
|
39
39
|
def setting
|
40
|
-
@setting ||= Esse::IndexSetting.new(paths: template_dirs, globals: -> { cluster.
|
40
|
+
@setting ||= Esse::IndexSetting.new(paths: template_dirs, globals: -> { cluster.settings })
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
data/lib/esse/index/type.rb
CHANGED
@@ -3,26 +3,66 @@
|
|
3
3
|
module Esse
|
4
4
|
class Index
|
5
5
|
module ClassMethods
|
6
|
-
attr_writer :
|
6
|
+
attr_writer :repo_hash
|
7
7
|
|
8
|
-
def
|
9
|
-
@
|
8
|
+
def repo_hash
|
9
|
+
@repo_hash ||= {}
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
|
12
|
+
def repo(name = nil)
|
13
|
+
if name.nil? && repo_hash.size == 1
|
14
|
+
name = repo_hash.keys.first
|
15
|
+
elsif name.nil? && repo_hash.size > 1
|
16
|
+
raise ArgumentError, "You can only call `repo' with a name when there is only one type defined."
|
17
|
+
end
|
18
|
+
name ||= DEFAULT_REPO_NAME
|
14
19
|
|
15
|
-
|
20
|
+
repo_hash.fetch(name.to_s)
|
21
|
+
rescue KeyError
|
22
|
+
raise ArgumentError, <<~MSG
|
23
|
+
No repo named "#{name}" found. Use the `repository' method to define one:
|
24
|
+
|
25
|
+
repository :#{name} do
|
26
|
+
# collection ...
|
27
|
+
# document ...
|
28
|
+
end
|
29
|
+
MSG
|
30
|
+
end
|
31
|
+
|
32
|
+
def repo?(name = nil)
|
33
|
+
return repo_hash.size > 0 if name.nil?
|
34
|
+
|
35
|
+
repo_hash.key?(name.to_s)
|
36
|
+
end
|
37
|
+
|
38
|
+
def repository(repo_name, *_args, **kwargs, &block)
|
39
|
+
repo_class = Class.new(Esse::Repository)
|
40
|
+
kwargs[:const] = true unless kwargs.key?(:const) # TODO Change this to false to avoid collisions with application classes
|
41
|
+
kwargs[:lazy_evaluate] ||= false
|
42
|
+
|
43
|
+
if kwargs[:const]
|
44
|
+
const_set(Hstring.new(repo_name).camelize.demodulize.to_s, repo_class)
|
45
|
+
end
|
16
46
|
|
17
47
|
index = self
|
18
48
|
|
19
|
-
|
20
|
-
|
49
|
+
repo_class.send(:define_singleton_method, :index) { index }
|
50
|
+
repo_class.send(:define_singleton_method, :repo_name) { repo_name.to_s }
|
51
|
+
|
52
|
+
plugins.each do |mod|
|
53
|
+
next unless mod.const_defined?(:RepositoryClassMethods, false)
|
54
|
+
|
55
|
+
repository_plugin_extend(repo_class, mod::RepositoryClassMethods)
|
56
|
+
end
|
57
|
+
|
58
|
+
if kwargs[:lazy_evaluate]
|
21
59
|
|
22
|
-
|
60
|
+
elsif block
|
61
|
+
repo_class.class_eval(&block)
|
62
|
+
end
|
23
63
|
|
24
|
-
self.
|
25
|
-
|
64
|
+
self.repo_hash = repo_hash.merge(repo_class.repo_name => repo_class)
|
65
|
+
repo_class
|
26
66
|
end
|
27
67
|
end
|
28
68
|
|
data/lib/esse/index.rb
CHANGED
@@ -1,22 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'object_document_mapper'
|
4
|
-
|
5
3
|
module Esse
|
6
4
|
class Index
|
5
|
+
@repo_hash = {}
|
6
|
+
@setting = {}
|
7
|
+
@mapping = {}
|
8
|
+
@plugins = []
|
9
|
+
@cluster_id = nil
|
10
|
+
|
11
|
+
require_relative 'index/plugins'
|
7
12
|
require_relative 'index/base'
|
8
13
|
require_relative 'index/inheritance'
|
9
14
|
require_relative 'index/actions'
|
10
|
-
require_relative 'index/
|
15
|
+
require_relative 'index/attributes'
|
11
16
|
require_relative 'index/type'
|
12
17
|
require_relative 'index/settings'
|
13
18
|
require_relative 'index/mappings'
|
14
19
|
require_relative 'index/descendants'
|
15
|
-
require_relative 'index/
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
20
|
+
require_relative 'index/object_document_mapper'
|
21
|
+
# Methods that use the cluster API
|
22
|
+
require_relative 'index/aliases'
|
23
|
+
require_relative 'index/indices'
|
24
|
+
require_relative 'index/search'
|
25
|
+
require_relative 'index/documents'
|
21
26
|
end
|
22
27
|
end
|
data/lib/esse/index_mapping.rb
CHANGED
@@ -4,10 +4,11 @@ module Esse
|
|
4
4
|
class IndexMapping
|
5
5
|
FILENAMES = %w[mapping mappings].freeze
|
6
6
|
|
7
|
-
def initialize(body: {}, paths: [], filenames: FILENAMES)
|
7
|
+
def initialize(body: {}, paths: [], filenames: FILENAMES, globals: nil)
|
8
8
|
@paths = Array(paths)
|
9
9
|
@filenames = Array(filenames)
|
10
10
|
@mappings = body
|
11
|
+
@globals = globals || -> { {} }
|
11
12
|
end
|
12
13
|
|
13
14
|
# This method will be overwrited when passing a block during the
|
@@ -19,7 +20,14 @@ module Esse
|
|
19
20
|
end
|
20
21
|
|
21
22
|
def body
|
22
|
-
|
23
|
+
global = HashUtils.deep_transform_keys(@globals.call, &:to_sym)
|
24
|
+
local = HashUtils.deep_transform_keys(to_h.dup, &:to_sym)
|
25
|
+
dynamic_template = DynamicTemplate.new(global[:dynamic_templates])
|
26
|
+
dynamic_template.merge!(local.delete(:dynamic_templates))
|
27
|
+
if dynamic_template.any?
|
28
|
+
global[:dynamic_templates] = dynamic_template.to_a
|
29
|
+
end
|
30
|
+
HashUtils.deep_merge(global, local)
|
23
31
|
end
|
24
32
|
|
25
33
|
def empty?
|
data/lib/esse/index_setting.rb
CHANGED
@@ -30,7 +30,9 @@ module Esse
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def body
|
33
|
-
HashUtils.
|
33
|
+
global = HashUtils.deep_transform_keys(@globals.call, &:to_sym)
|
34
|
+
local = HashUtils.deep_transform_keys(to_h, &:to_sym)
|
35
|
+
HashUtils.deep_merge(global, local)
|
34
36
|
end
|
35
37
|
|
36
38
|
protected
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Esse
|
4
|
+
class NullDocument < Esse::Document
|
5
|
+
def initialize
|
6
|
+
@object = nil
|
7
|
+
@options = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [NilClass] the document ID
|
11
|
+
def id
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [NilClass] the document type
|
16
|
+
def type
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [NilClass] the document routing
|
21
|
+
def routing
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [NilClass] the document meta
|
26
|
+
def meta
|
27
|
+
{}
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [NilClass] the document source
|
31
|
+
def source
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/esse/plugins.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Esse
|
4
|
+
module Plugins
|
5
|
+
def self.inherited_instance_variables(mod, hash)
|
6
|
+
mod.send(:define_method, :inherited_instance_variables) do
|
7
|
+
super().merge!(hash)
|
8
|
+
end
|
9
|
+
mod.send(:private, :inherited_instance_variables)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -9,7 +9,7 @@ module Esse
|
|
9
9
|
class Hstring
|
10
10
|
extend Forwardable
|
11
11
|
|
12
|
-
def_delegators :@value, :==, :eq, :to_s, :to_sym, :inspect, :sub, :capitalize
|
12
|
+
def_delegators :@value, :==, :eq, :to_s, :to_sym, :inspect, :sub, :capitalize, :tr
|
13
13
|
attr_reader :value
|
14
14
|
|
15
15
|
def self.def_conventional(bang_method, conv_method = nil)
|