elastic-rails 0.6.4 → 0.7.0
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/README.md +10 -0
- data/lib/elastic/commands/build_agg_from_params.rb +11 -2
- data/lib/elastic/commands/compare_mappings.rb +44 -0
- data/lib/elastic/commands/import_index_documents.rb +8 -10
- data/lib/elastic/configuration.rb +28 -35
- data/lib/elastic/core/connector.rb +253 -0
- data/lib/elastic/core/definition.rb +0 -4
- data/lib/elastic/core/query_assembler.rb +1 -1
- data/lib/elastic/core/serializer.rb +17 -3
- data/lib/elastic/datatypes/date.rb +9 -3
- data/lib/elastic/datatypes/time.rb +10 -3
- data/lib/elastic/errors.rb +4 -0
- data/lib/elastic/fields/nested.rb +1 -5
- data/lib/elastic/fields/value.rb +0 -4
- data/lib/elastic/nodes/agg/date_histogram.rb +10 -2
- data/lib/elastic/nodes/boolean.rb +1 -1
- data/lib/elastic/query.rb +1 -1
- data/lib/elastic/railtie.rb +6 -3
- data/lib/elastic/railties/configuration_extensions.rb +3 -6
- data/lib/elastic/railties/indexable_record.rb +18 -8
- data/lib/elastic/railties/tasks/es.rake +12 -6
- data/lib/elastic/railties/utils.rb +15 -3
- data/lib/elastic/type.rb +47 -48
- data/lib/elastic/version.rb +1 -1
- data/lib/elastic.rb +14 -4
- data/lib/generators/elastic/templates/elastic.yml +1 -0
- metadata +5 -4
- data/lib/elastic/core/adaptor.rb +0 -126
- data/lib/elastic/core/mapping_manager.rb +0 -120
data/lib/elastic/query.rb
CHANGED
data/lib/elastic/railtie.rb
CHANGED
@@ -4,13 +4,16 @@ require "elastic/railties/ar_middleware"
|
|
4
4
|
require "elastic/railties/configuration_extensions"
|
5
5
|
require "elastic/railties/type_extensions"
|
6
6
|
require "elastic/railties/query_extensions"
|
7
|
-
require "elastic/railties/indexing_job"
|
7
|
+
# disabled for now: require "elastic/railties/indexing_job"
|
8
8
|
require "elastic/railties/indexable_record"
|
9
9
|
|
10
10
|
module Elastic
|
11
11
|
class Railtie < Rails::Railtie
|
12
12
|
initializer "elastic.configure_rails_initialization" do
|
13
|
-
Elastic.configure Rails.application.config_for(:elastic).merge(
|
13
|
+
Elastic.configure Rails.application.config_for(:elastic).merge(
|
14
|
+
time_zone: Rails.application.config.time_zone,
|
15
|
+
logger: Rails.logger
|
16
|
+
)
|
14
17
|
|
15
18
|
# Make every activerecord model indexable
|
16
19
|
ActiveRecord::Base.send(:include, Elastic::Railties::IndexableRecord)
|
@@ -30,7 +33,7 @@ module Elastic
|
|
30
33
|
end
|
31
34
|
|
32
35
|
# Add activerecord related configuration parameters
|
33
|
-
|
36
|
+
class Elastic::Configuration
|
34
37
|
include Elastic::Railties::ConfigurationExtensions
|
35
38
|
end
|
36
39
|
|
@@ -1,13 +1,10 @@
|
|
1
1
|
module Elastic::Railties
|
2
2
|
module ConfigurationExtensions
|
3
3
|
def self.included(_klass)
|
4
|
-
_klass
|
4
|
+
_klass::DEFAULTS[:active_job_queue] = :default
|
5
|
+
_klass::DEFAULTS[:indices_path] = 'app/indices'
|
5
6
|
end
|
6
7
|
|
7
|
-
|
8
|
-
def active_job_queue
|
9
|
-
config[:active_job_queue] || :default
|
10
|
-
end
|
11
|
-
end
|
8
|
+
attr_accessor :active_job_queue, :indices_path
|
12
9
|
end
|
13
10
|
end
|
@@ -18,21 +18,31 @@ module Elastic::Railties
|
|
18
18
|
@constantized_index_class ||= index_class.constantize
|
19
19
|
end
|
20
20
|
|
21
|
-
def index(
|
22
|
-
|
21
|
+
def index(on: nil, unindex: true, delayed: false)
|
22
|
+
raise NotImplementedError, 'delayed indexing not implemented' if delayed
|
23
|
+
|
23
24
|
if on == :create
|
24
|
-
index_on_create
|
25
|
+
index_on_create
|
25
26
|
elsif on == :save
|
26
|
-
index_on_save
|
27
|
+
index_on_save
|
28
|
+
else
|
29
|
+
raise ArgumentError, 'must provide an indexing target when calling index \
|
30
|
+
(ie: `index on: :save`)'
|
27
31
|
end
|
32
|
+
|
33
|
+
unindex_on_destroy if unindex
|
28
34
|
end
|
29
35
|
|
30
36
|
def index_on_create(_options = {})
|
31
|
-
after_create(_options) {
|
37
|
+
after_create(_options) { index_now }
|
32
38
|
end
|
33
39
|
|
34
40
|
def index_on_save(_options = {})
|
35
|
-
after_save(_options) {
|
41
|
+
after_save(_options) { index_now }
|
42
|
+
end
|
43
|
+
|
44
|
+
def unindex_on_destroy(_options = {})
|
45
|
+
before_destroy(_options) { unindex_now }
|
36
46
|
end
|
37
47
|
end
|
38
48
|
|
@@ -40,8 +50,8 @@ module Elastic::Railties
|
|
40
50
|
self.class.constantized_index_class.index self
|
41
51
|
end
|
42
52
|
|
43
|
-
def
|
44
|
-
|
53
|
+
def unindex_now
|
54
|
+
self.class.constantized_index_class.delete self
|
45
55
|
end
|
46
56
|
end
|
47
57
|
end
|
@@ -1,19 +1,25 @@
|
|
1
1
|
namespace :es do
|
2
2
|
desc "Elastic: Updates indices mappings"
|
3
|
-
task
|
3
|
+
task :remap, [:index] => :environment do |_, args|
|
4
4
|
Elastic.configure logger: Logger.new(STDOUT)
|
5
|
-
Elastic.
|
5
|
+
Elastic.remap args.index
|
6
|
+
end
|
7
|
+
|
8
|
+
desc "Elastic: Updates indices mappings, rebuilding index if necessary"
|
9
|
+
task :migrate, [:index] => :environment do |_, args|
|
10
|
+
Elastic.configure logger: Logger.new(STDOUT)
|
11
|
+
Elastic.migrate args.index
|
6
12
|
end
|
7
13
|
|
8
14
|
desc "Elastic: Rebuilds indices from source data"
|
9
|
-
task reindex: :environment do
|
15
|
+
task :reindex, [:index] => :environment do |_, args|
|
10
16
|
Elastic.configure logger: Logger.new(STDOUT)
|
11
|
-
Elastic.reindex
|
17
|
+
Elastic.reindex args.index
|
12
18
|
end
|
13
19
|
|
14
20
|
desc "Elastic: Lists indices stats"
|
15
|
-
task stats: :environment do
|
21
|
+
task :stats, [:index] => :environment do |_, args|
|
16
22
|
Elastic.configure logger: Logger.new(STDOUT)
|
17
|
-
Elastic.stats
|
23
|
+
Elastic.stats args.index
|
18
24
|
end
|
19
25
|
end
|
@@ -8,11 +8,23 @@ module Elastic::Railties
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
+
def remap(_index = nil)
|
12
|
+
logger.info "Remapping all indices" if _index.nil?
|
13
|
+
indices(_index).each do |index|
|
14
|
+
logger.info "Remapping index #{index.suffix}"
|
15
|
+
handle_errors do
|
16
|
+
unless index.connector.remap
|
17
|
+
logger.info 'Mapping couldnt be changed, make sure you call migrate'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
11
23
|
def migrate(_index = nil)
|
12
24
|
logger.info "Migrating all indices" if _index.nil?
|
13
25
|
indices(_index).each do |index|
|
14
26
|
logger.info "Migrating index #{index.suffix}"
|
15
|
-
handle_errors { index.
|
27
|
+
handle_errors { index.migrate }
|
16
28
|
end
|
17
29
|
end
|
18
30
|
|
@@ -45,7 +57,7 @@ module Elastic::Railties
|
|
45
57
|
end
|
46
58
|
|
47
59
|
def indices_paths
|
48
|
-
Rails.root.join(Elastic
|
60
|
+
Rails.root.join(Elastic.config.indices_path)
|
49
61
|
end
|
50
62
|
|
51
63
|
def handle_errors
|
@@ -56,7 +68,7 @@ module Elastic::Railties
|
|
56
68
|
end
|
57
69
|
|
58
70
|
def logger
|
59
|
-
Elastic
|
71
|
+
Elastic.logger
|
60
72
|
end
|
61
73
|
end
|
62
74
|
end
|
data/lib/elastic/type.rb
CHANGED
@@ -10,6 +10,10 @@ module Elastic
|
|
10
10
|
:coord_similarity, :limit, :offset, :pluck, :ids, :total
|
11
11
|
end
|
12
12
|
|
13
|
+
def self.default_suffix
|
14
|
+
to_s.underscore
|
15
|
+
end
|
16
|
+
|
13
17
|
def self.suffix
|
14
18
|
@suffix || default_suffix
|
15
19
|
end
|
@@ -19,38 +23,49 @@ module Elastic
|
|
19
23
|
end
|
20
24
|
|
21
25
|
def self.import_batch_size
|
22
|
-
@import_batch_size ||
|
26
|
+
@import_batch_size || Elastic.config.import_batch_size
|
23
27
|
end
|
24
28
|
|
25
29
|
def self.import_batch_size=(_value)
|
26
30
|
@import_batch_size = _value
|
27
31
|
end
|
28
32
|
|
29
|
-
def self.
|
30
|
-
@
|
33
|
+
def self.connector
|
34
|
+
@connector ||= begin
|
35
|
+
Elastic::Core::Connector.new(
|
36
|
+
suffix,
|
37
|
+
definition.types,
|
38
|
+
definition.as_es_mapping
|
39
|
+
).tap do |conn|
|
40
|
+
if Elastic.config.whiny_indices && conn.status != :ready
|
41
|
+
raise 'elastic index out of sync, try migrating'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
31
45
|
end
|
32
46
|
|
33
|
-
def self.
|
34
|
-
|
47
|
+
def self.index_name
|
48
|
+
connector.index_name
|
35
49
|
end
|
36
50
|
|
37
|
-
def self.
|
38
|
-
|
39
|
-
|
40
|
-
|
51
|
+
def self.migrate
|
52
|
+
connector.migrate(batch_size: import_batch_size)
|
53
|
+
self
|
54
|
+
end
|
41
55
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
56
|
+
def self.reindex(verbose: true)
|
57
|
+
connector.rollover do
|
58
|
+
Commands::ImportIndexDocuments.for(
|
59
|
+
index: self,
|
60
|
+
verbose: verbose,
|
61
|
+
batch_size: import_batch_size
|
62
|
+
)
|
63
|
+
end
|
47
64
|
|
48
|
-
ensure_full_mapping
|
49
65
|
self
|
50
66
|
end
|
51
67
|
|
52
68
|
def self.import(_collection, batch_size: nil)
|
53
|
-
enforce_mapping!
|
54
69
|
batch_size = batch_size || import_batch_size
|
55
70
|
|
56
71
|
Commands::ImportIndexDocuments.for(
|
@@ -59,7 +74,6 @@ module Elastic
|
|
59
74
|
batch_size: batch_size
|
60
75
|
)
|
61
76
|
|
62
|
-
ensure_full_mapping
|
63
77
|
self
|
64
78
|
end
|
65
79
|
|
@@ -67,52 +81,37 @@ module Elastic
|
|
67
81
|
new(_object).save
|
68
82
|
end
|
69
83
|
|
84
|
+
def self.delete(_object)
|
85
|
+
wrapper = new(_object)
|
86
|
+
id = wrapper.read_elastic_id
|
87
|
+
raise ArgumentError, 'index does not provide an id' if id.nil?
|
88
|
+
|
89
|
+
connector.delete(
|
90
|
+
wrapper.read_elastic_type,
|
91
|
+
wrapper.read_elastic_id
|
92
|
+
)
|
93
|
+
|
94
|
+
nil
|
95
|
+
end
|
96
|
+
|
70
97
|
def self.query
|
71
|
-
enforce_mapping!
|
72
|
-
ensure_full_mapping
|
73
98
|
Query.new self
|
74
99
|
end
|
75
100
|
|
76
101
|
def self.drop
|
77
|
-
|
102
|
+
connector.drop
|
78
103
|
self
|
79
104
|
end
|
80
105
|
|
81
106
|
def self.refresh
|
82
|
-
|
107
|
+
connector.refresh
|
83
108
|
self
|
84
109
|
end
|
85
110
|
|
86
|
-
def self.enforce_mapping!
|
87
|
-
if mapping.out_of_sync?
|
88
|
-
raise 'elastic mapping out of sync, run `rake es:migrate`'
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def self.ensure_full_mapping
|
93
|
-
if mapping.incomplete?
|
94
|
-
mapping.fetch
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
111
|
def save
|
99
112
|
self.class.tap do |klass|
|
100
|
-
klass.
|
101
|
-
klass.adaptor.index as_es_document
|
102
|
-
klass.ensure_full_mapping
|
113
|
+
klass.connector.index as_elastic_document
|
103
114
|
end
|
104
115
|
end
|
105
|
-
|
106
|
-
def self.load_mapping
|
107
|
-
Elastic::Core::MappingManager.new(adaptor, definition).tap(&:fetch)
|
108
|
-
end
|
109
|
-
|
110
|
-
private_class_method :load_mapping
|
111
|
-
|
112
|
-
def self.default_suffix
|
113
|
-
to_s.underscore
|
114
|
-
end
|
115
|
-
|
116
|
-
private_class_method :default_suffix
|
117
116
|
end
|
118
117
|
end
|
data/lib/elastic/version.rb
CHANGED
data/lib/elastic.rb
CHANGED
@@ -2,6 +2,7 @@ require "elasticsearch"
|
|
2
2
|
|
3
3
|
require "elastic/version"
|
4
4
|
require "elastic/configuration"
|
5
|
+
require "elastic/errors"
|
5
6
|
|
6
7
|
require "elastic/support/command"
|
7
8
|
require "elastic/support/transform"
|
@@ -11,6 +12,7 @@ require "elastic/commands/import_index_documents"
|
|
11
12
|
require "elastic/commands/build_query_from_params"
|
12
13
|
require "elastic/commands/build_agg_from_params"
|
13
14
|
require "elastic/commands/build_sort_from_params"
|
15
|
+
require "elastic/commands/compare_mappings"
|
14
16
|
|
15
17
|
require "elastic/results/base"
|
16
18
|
require "elastic/results/scored_item"
|
@@ -64,9 +66,8 @@ require "elastic/datatypes/time"
|
|
64
66
|
require "elastic/fields/value"
|
65
67
|
require "elastic/fields/nested"
|
66
68
|
|
69
|
+
require "elastic/core/connector"
|
67
70
|
require "elastic/core/definition"
|
68
|
-
require "elastic/core/adaptor"
|
69
|
-
require "elastic/core/mapping_manager"
|
70
71
|
require "elastic/core/serializer"
|
71
72
|
require "elastic/core/middleware"
|
72
73
|
require "elastic/core/base_middleware"
|
@@ -89,8 +90,17 @@ require "elastic/query"
|
|
89
90
|
require "elastic/nested_query"
|
90
91
|
|
91
92
|
module Elastic
|
92
|
-
def self.
|
93
|
-
Configuration.
|
93
|
+
def self.config
|
94
|
+
@config ||= Configuration.new
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.logger
|
98
|
+
config.logger
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.configure(_options = nil, &_block)
|
102
|
+
config.assign_attributes(_options) unless _options.nil?
|
103
|
+
_block.call(config) unless _block.nil?
|
94
104
|
end
|
95
105
|
|
96
106
|
def self.register_middleware(_middleware)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elastic-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ignacio Baixas
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-08-
|
11
|
+
date: 2016-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: elasticsearch
|
@@ -228,13 +228,13 @@ files:
|
|
228
228
|
- lib/elastic/commands/build_agg_from_params.rb
|
229
229
|
- lib/elastic/commands/build_query_from_params.rb
|
230
230
|
- lib/elastic/commands/build_sort_from_params.rb
|
231
|
+
- lib/elastic/commands/compare_mappings.rb
|
231
232
|
- lib/elastic/commands/import_index_documents.rb
|
232
233
|
- lib/elastic/configuration.rb
|
233
|
-
- lib/elastic/core/adaptor.rb
|
234
234
|
- lib/elastic/core/base_middleware.rb
|
235
|
+
- lib/elastic/core/connector.rb
|
235
236
|
- lib/elastic/core/default_middleware.rb
|
236
237
|
- lib/elastic/core/definition.rb
|
237
|
-
- lib/elastic/core/mapping_manager.rb
|
238
238
|
- lib/elastic/core/middleware.rb
|
239
239
|
- lib/elastic/core/query_assembler.rb
|
240
240
|
- lib/elastic/core/query_config.rb
|
@@ -248,6 +248,7 @@ files:
|
|
248
248
|
- lib/elastic/dsl/bool_query_builder.rb
|
249
249
|
- lib/elastic/dsl/bool_query_context.rb
|
250
250
|
- lib/elastic/dsl/metric_builder.rb
|
251
|
+
- lib/elastic/errors.rb
|
251
252
|
- lib/elastic/fields/nested.rb
|
252
253
|
- lib/elastic/fields/value.rb
|
253
254
|
- lib/elastic/nested_query.rb
|
data/lib/elastic/core/adaptor.rb
DELETED
@@ -1,126 +0,0 @@
|
|
1
|
-
module Elastic::Core
|
2
|
-
class Adaptor
|
3
|
-
DEFAULT_SETTINGS = {
|
4
|
-
refresh_interval: '1s',
|
5
|
-
number_of_replicas: 1
|
6
|
-
}
|
7
|
-
|
8
|
-
def initialize(_suffix)
|
9
|
-
@suffix = _suffix
|
10
|
-
end
|
11
|
-
|
12
|
-
def index_name
|
13
|
-
@index_name ||= "#{Elastic::Configuration.index_name}_#{@suffix}"
|
14
|
-
end
|
15
|
-
|
16
|
-
def remap(_type, _mapping)
|
17
|
-
# TODO
|
18
|
-
end
|
19
|
-
|
20
|
-
def exists?
|
21
|
-
api_client.indices.exists? build_options
|
22
|
-
end
|
23
|
-
|
24
|
-
def ensure_index
|
25
|
-
create unless exists?
|
26
|
-
self
|
27
|
-
end
|
28
|
-
|
29
|
-
def create
|
30
|
-
api_client.indices.create build_options
|
31
|
-
api_client.cluster.health wait_for_status: 'yellow'
|
32
|
-
self
|
33
|
-
end
|
34
|
-
|
35
|
-
def drop
|
36
|
-
api_client.indices.delete build_options
|
37
|
-
self
|
38
|
-
end
|
39
|
-
|
40
|
-
def exists_type?(_type)
|
41
|
-
api_client.indices.exists_type build_options(type: _type)
|
42
|
-
end
|
43
|
-
|
44
|
-
def exists_mapping?(_type)
|
45
|
-
!api_client.indices.get_mapping(build_options(type: _type)).empty?
|
46
|
-
end
|
47
|
-
|
48
|
-
def get_mappings(type: nil)
|
49
|
-
mappings = api_client.indices.get_mapping build_options(type: type)
|
50
|
-
mappings[index_name]['mappings']
|
51
|
-
end
|
52
|
-
|
53
|
-
def set_mapping(_type, _mapping)
|
54
|
-
api_client.indices.put_mapping build_options(
|
55
|
-
type: _type,
|
56
|
-
body: _mapping
|
57
|
-
)
|
58
|
-
self
|
59
|
-
end
|
60
|
-
|
61
|
-
def index(_document)
|
62
|
-
api_client.index build_options(
|
63
|
-
id: _document['_id'],
|
64
|
-
type: _document['_type'],
|
65
|
-
body: _document['data']
|
66
|
-
)
|
67
|
-
self
|
68
|
-
end
|
69
|
-
|
70
|
-
def bulk_index(_documents)
|
71
|
-
body = _documents.map { |doc| { 'index' => doc } }
|
72
|
-
|
73
|
-
retry_on_temporary_error('bulk indexing') do
|
74
|
-
api_client.bulk build_options(body: body)
|
75
|
-
end
|
76
|
-
|
77
|
-
self
|
78
|
-
end
|
79
|
-
|
80
|
-
def with_settings(_options)
|
81
|
-
_options = DEFAULT_SETTINGS.merge _options
|
82
|
-
api_client.indices.put_settings build_options(body: { index: _options })
|
83
|
-
yield
|
84
|
-
ensure
|
85
|
-
api_client.indices.put_settings build_options(body: { index: DEFAULT_SETTINGS })
|
86
|
-
end
|
87
|
-
|
88
|
-
def refresh
|
89
|
-
api_client.indices.refresh build_options
|
90
|
-
self
|
91
|
-
end
|
92
|
-
|
93
|
-
def find(_id, type: '_all')
|
94
|
-
api_client.get build_options(type: type, id: _id)
|
95
|
-
end
|
96
|
-
|
97
|
-
def count(type: nil, query: nil)
|
98
|
-
api_client.count(build_options(type: type, body: query))['count']
|
99
|
-
end
|
100
|
-
|
101
|
-
def query(type: nil, query: nil)
|
102
|
-
api_client.search build_options(type: type, body: query)
|
103
|
-
end
|
104
|
-
|
105
|
-
private
|
106
|
-
|
107
|
-
def retry_on_temporary_error(_action, retries: 3)
|
108
|
-
return yield
|
109
|
-
rescue Elasticsearch::Transport::Transport::Errors::ServiceUnavailable,
|
110
|
-
Elasticsearch::Transport::Transport::Errors::GatewayTimeout => exc
|
111
|
-
raise if retries <= 0
|
112
|
-
|
113
|
-
Configuration.logger.warn("#{exc.class} error during '#{_action}', retrying!")
|
114
|
-
retries -= 1
|
115
|
-
retry
|
116
|
-
end
|
117
|
-
|
118
|
-
def api_client
|
119
|
-
Elastic::Configuration.api_client
|
120
|
-
end
|
121
|
-
|
122
|
-
def build_options(_options = {})
|
123
|
-
{ index: index_name }.merge! _options
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
@@ -1,120 +0,0 @@
|
|
1
|
-
module Elastic::Core
|
2
|
-
class MappingManager
|
3
|
-
attr_reader :adaptor, :definition
|
4
|
-
|
5
|
-
def initialize(_adaptor, _definition)
|
6
|
-
@adaptor = _adaptor
|
7
|
-
@definition = _definition
|
8
|
-
@status = :pending
|
9
|
-
end
|
10
|
-
|
11
|
-
def out_of_sync?
|
12
|
-
@status == :out_of_sync
|
13
|
-
end
|
14
|
-
|
15
|
-
def incomplete?
|
16
|
-
@status == :incomplete
|
17
|
-
end
|
18
|
-
|
19
|
-
def fetch
|
20
|
-
begin
|
21
|
-
mappings = @adaptor.get_mappings
|
22
|
-
mappings = @definition.types.map { |t| mappings[t] }.reject(&:nil?)
|
23
|
-
@index = merge_mappings_into_index mappings
|
24
|
-
rescue Elasticsearch::Transport::Transport::Errors::NotFound
|
25
|
-
# ignore not-found errors when fetching mappings
|
26
|
-
@index = nil
|
27
|
-
end
|
28
|
-
|
29
|
-
@status = compute_status
|
30
|
-
self
|
31
|
-
end
|
32
|
-
|
33
|
-
def unmapped_fields
|
34
|
-
@definition.expanded_field_names.reject { |f| has_field? f }
|
35
|
-
end
|
36
|
-
|
37
|
-
def has_field?(_name)
|
38
|
-
@index.key? _name
|
39
|
-
end
|
40
|
-
|
41
|
-
def get_field_options(_name)
|
42
|
-
@index[_name]
|
43
|
-
end
|
44
|
-
|
45
|
-
def migrate
|
46
|
-
# TODO: make this a command
|
47
|
-
@adaptor.create unless @adaptor.exists?
|
48
|
-
begin
|
49
|
-
@definition.types.each { |t| @adaptor.set_mapping(t, user_mapping) }
|
50
|
-
rescue Elasticsearch::Transport::Transport::Errors::BadRequest
|
51
|
-
# TODO: https://www.elastic.co/guide/en/elasticsearch/guide/current/reindex.html
|
52
|
-
end
|
53
|
-
fetch
|
54
|
-
end
|
55
|
-
|
56
|
-
private
|
57
|
-
|
58
|
-
def compute_status
|
59
|
-
if !synchronized?
|
60
|
-
:out_of_sync
|
61
|
-
elsif unmapped_fields.count > 0
|
62
|
-
:incomplete
|
63
|
-
else
|
64
|
-
:ready
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def synchronized?
|
69
|
-
return false if @index.nil?
|
70
|
-
flatten(user_mapping).all? do |field, properties|
|
71
|
-
compare_field_properties(@index[field], properties)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def compare_field_properties(_current, _user)
|
76
|
-
return false if _current.nil?
|
77
|
-
|
78
|
-
case _current['type']
|
79
|
-
when 'date'
|
80
|
-
_current = { 'format' => 'dateOptionalTime' }.merge(_user)
|
81
|
-
else
|
82
|
-
_current == _user
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def user_mapping
|
87
|
-
@user_mapping ||= definition.as_es_mapping
|
88
|
-
end
|
89
|
-
|
90
|
-
def flatten(_raw, _prefix = '')
|
91
|
-
_raw['properties'].flat_map do |name, raw_field|
|
92
|
-
if raw_field['type'] == 'nested'
|
93
|
-
childs = flatten(raw_field, name + '.')
|
94
|
-
childs << [
|
95
|
-
_prefix + name,
|
96
|
-
raw_field.slice(*(raw_field.keys - ['properties']))
|
97
|
-
]
|
98
|
-
else
|
99
|
-
[[_prefix + name, raw_field.dup]]
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
def merge_mappings_into_index(_mappings)
|
105
|
-
{}.tap do |result|
|
106
|
-
_mappings.each do |mapping|
|
107
|
-
index = flatten(mapping)
|
108
|
-
index.each do |field, properties|
|
109
|
-
if result.key? field
|
110
|
-
result[field].merge! properties
|
111
|
-
else
|
112
|
-
result[field] = properties
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
result.each_value(&:freeze)
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|