esse 0.2.0 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -0,0 +1,105 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module Esse
|
6
|
+
module Backend
|
7
|
+
class RepositoryBackend
|
8
|
+
extend Forwardable
|
9
|
+
|
10
|
+
# Type delegators
|
11
|
+
def_delegators :@repo, :document_type, :index, :serialize
|
12
|
+
|
13
|
+
def initialize(repo)
|
14
|
+
@repo = repo
|
15
|
+
end
|
16
|
+
|
17
|
+
def import(**kwargs)
|
18
|
+
elasticsearch.import(document_type, **kwargs)
|
19
|
+
end
|
20
|
+
|
21
|
+
def import!(**kwargs)
|
22
|
+
elasticsearch.import!(document_type, **kwargs)
|
23
|
+
end
|
24
|
+
|
25
|
+
def bulk!(**kwargs)
|
26
|
+
elasticsearch.bulk!(**kwargs, type: document_type)
|
27
|
+
end
|
28
|
+
|
29
|
+
def bulk(**kwargs)
|
30
|
+
elasticsearch.bulk(**kwargs, type: document_type)
|
31
|
+
end
|
32
|
+
|
33
|
+
def index!(**kwargs)
|
34
|
+
elasticsearch.index!(**kwargs, type: document_type)
|
35
|
+
end
|
36
|
+
|
37
|
+
def index(**kwargs)
|
38
|
+
elasticsearch.index(**kwargs, type: document_type)
|
39
|
+
end
|
40
|
+
|
41
|
+
# @param [Esse::Serializer] document A document instance
|
42
|
+
def index_document(document, **kwargs)
|
43
|
+
return unless document.is_a?(Esse::Serializer)
|
44
|
+
return if document.ignore_on_index?
|
45
|
+
return unless document.id
|
46
|
+
|
47
|
+
kwargs[:id] = document.id
|
48
|
+
kwargs[:routing] = document.routing if document.routing
|
49
|
+
kwargs[:type] = document.type || document_type
|
50
|
+
kwargs[:body] = document.source&.to_h
|
51
|
+
elasticsearch.index(**kwargs)
|
52
|
+
end
|
53
|
+
|
54
|
+
def update!(**kwargs)
|
55
|
+
elasticsearch.update!(**kwargs, type: document_type)
|
56
|
+
end
|
57
|
+
|
58
|
+
def update(**kwargs)
|
59
|
+
elasticsearch.update(**kwargs, type: document_type)
|
60
|
+
end
|
61
|
+
|
62
|
+
def delete!(**kwargs)
|
63
|
+
elasticsearch.delete!(**kwargs, type: document_type)
|
64
|
+
end
|
65
|
+
|
66
|
+
def delete(**kwargs)
|
67
|
+
elasticsearch.delete(**kwargs, type: document_type)
|
68
|
+
end
|
69
|
+
|
70
|
+
# @param [Esse::Serializer] document A document instance
|
71
|
+
def delete_document(document, **kwargs)
|
72
|
+
return unless document.is_a?(Esse::Serializer)
|
73
|
+
return if document.ignore_on_delete?
|
74
|
+
return unless document.id
|
75
|
+
|
76
|
+
kwargs[:id] = document.id
|
77
|
+
kwargs[:routing] = document.routing if document.routing
|
78
|
+
kwargs[:type] = document.type || document_type
|
79
|
+
elasticsearch.delete(**kwargs)
|
80
|
+
end
|
81
|
+
|
82
|
+
def exist?(**kwargs)
|
83
|
+
elasticsearch.exist?(**kwargs, type: document_type)
|
84
|
+
end
|
85
|
+
|
86
|
+
def count(**kwargs)
|
87
|
+
elasticsearch.count(**kwargs, type: document_type)
|
88
|
+
end
|
89
|
+
|
90
|
+
def find!(**kwargs)
|
91
|
+
elasticsearch.find!(**kwargs, type: document_type)
|
92
|
+
end
|
93
|
+
|
94
|
+
def find(**kwargs)
|
95
|
+
elasticsearch.find(**kwargs, type: document_type)
|
96
|
+
end
|
97
|
+
|
98
|
+
protected
|
99
|
+
|
100
|
+
def elasticsearch
|
101
|
+
@repo.index.elasticsearch
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -82,6 +82,20 @@ module Esse
|
|
82
82
|
padding: runtime_padding(event[:runtime])
|
83
83
|
end
|
84
84
|
end
|
85
|
+
|
86
|
+
def elasticsearch_bulk(event)
|
87
|
+
print_message("[%<runtime>s] Bulk index %<name>s%<type>s%<wait_interval>s: ",
|
88
|
+
runtime: formatted_runtime(event[:runtime]),
|
89
|
+
name: colorize(event[:request][:index], :bold),
|
90
|
+
type: (event[:request][:type] ? " for type #{colorize(event[:request][:type], :bold)}" : ''),
|
91
|
+
wait_interval: (event[:wait_interval].nonzero? ? " (wait interval #{event[:wait_interval]}s)" : ''),
|
92
|
+
newline: false,
|
93
|
+
)
|
94
|
+
stats = event[:request][:body_stats].select {|_, v| v.nonzero? }.map do |type, count|
|
95
|
+
"#{colorize(type, :bold)}: #{count} docs"
|
96
|
+
end
|
97
|
+
print_message(stats.join(", ") + ".")
|
98
|
+
end
|
85
99
|
end
|
86
100
|
end
|
87
101
|
end
|
data/lib/esse/cli/generate.rb
CHANGED
@@ -14,34 +14,75 @@ module Esse
|
|
14
14
|
end
|
15
15
|
|
16
16
|
desc 'index NAME *TYPES', 'Creates a new index'
|
17
|
+
option :settings, type: :boolean, default: false, desc: 'Generate settings'
|
18
|
+
option :mappings, type: :boolean, default: false, desc: 'Generate mappings'
|
19
|
+
option :serializers, type: :boolean, default: false, desc: 'Generate serializers'
|
20
|
+
option :collections, type: :boolean, default: false, desc: 'Generate collections'
|
21
|
+
option :active_record, type: :boolean, default: false, desc: 'Generate ActiveRecord models'
|
22
|
+
option :cluster_id, type: :string, desc: 'Elasticsearch cluster ID'
|
17
23
|
def index(name, *types)
|
18
24
|
ns_path = name.split(NAMESPACE_PATTERN_RE).tap(&:pop)
|
19
25
|
@index_name = Hstring.new(name.to_s).modulize.sub(/Index$/, '') + 'Index'
|
20
26
|
@index_name = Hstring.new(@index_name)
|
21
27
|
@types = types.map { |type| Hstring.new(type) }
|
22
28
|
@base_class = base_index_class(*ns_path)
|
29
|
+
if options[:cluster_id]
|
30
|
+
@base_class += format('(:%s)', options[:cluster_id])
|
31
|
+
end
|
32
|
+
@cli_options = options
|
23
33
|
|
24
|
-
base_dir = Esse.config.indices_directory.join(*ns_path)
|
34
|
+
base_dir = Esse.config.indices_directory.join(*ns_path.map { |n| Hstring.new(n).underscore.to_s })
|
25
35
|
index_name = @index_name.demodulize.underscore.to_s
|
26
36
|
template(
|
27
37
|
'templates/index.rb.erb',
|
28
38
|
base_dir.join("#{index_name}.rb"),
|
29
39
|
)
|
30
|
-
|
31
|
-
|
40
|
+
|
41
|
+
if options[:settings]
|
32
42
|
copy_file(
|
33
|
-
'templates/
|
34
|
-
base_dir.join(index_name, 'templates',
|
43
|
+
'templates/settings.json',
|
44
|
+
base_dir.join(index_name, 'templates', 'settings.json'),
|
35
45
|
)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
'templates
|
42
|
-
base_dir.join(index_name, 'collections', "#{@type}_collection.rb"),
|
46
|
+
end
|
47
|
+
|
48
|
+
if options[:mappings]
|
49
|
+
copy_file(
|
50
|
+
'templates/mappings.json',
|
51
|
+
base_dir.join(index_name, 'templates', 'mappings.json'),
|
43
52
|
)
|
44
53
|
end
|
54
|
+
|
55
|
+
if @types.empty?
|
56
|
+
if options[:serializers]
|
57
|
+
template(
|
58
|
+
'templates/serializer.rb.erb',
|
59
|
+
base_dir.join(index_name, 'serializers', 'serializer.rb'),
|
60
|
+
)
|
61
|
+
end
|
62
|
+
if options[:collections] && !options[:active_record]
|
63
|
+
template(
|
64
|
+
'templates/collection.rb.erb',
|
65
|
+
base_dir.join(index_name, 'collections', 'collection.rb'),
|
66
|
+
)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
@types.each do |type|
|
71
|
+
@type = Hstring.new(type).underscore
|
72
|
+
|
73
|
+
if options[:serializers]
|
74
|
+
template(
|
75
|
+
'templates/serializer.rb.erb',
|
76
|
+
base_dir.join(index_name, 'serializers', "#{@type}_serializer.rb"),
|
77
|
+
)
|
78
|
+
end
|
79
|
+
if options[:collections] && !options[:active_record]
|
80
|
+
template(
|
81
|
+
'templates/collection.rb.erb',
|
82
|
+
base_dir.join(index_name, 'collections', "#{@type}_collection.rb"),
|
83
|
+
)
|
84
|
+
end
|
85
|
+
end
|
45
86
|
end
|
46
87
|
|
47
88
|
protected
|
@@ -31,7 +31,10 @@ module Esse
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def indices
|
34
|
-
eager_load_indices!
|
34
|
+
Esse.eager_load_indices!
|
35
|
+
if @indices == ['all']
|
36
|
+
return Esse::Index.descendants.reject(&:abstract_class?)
|
37
|
+
end
|
35
38
|
@indices.map do |class_name|
|
36
39
|
const_exist = begin
|
37
40
|
Kernel.const_defined?(class_name)
|
@@ -58,18 +61,7 @@ module Esse
|
|
58
61
|
end
|
59
62
|
|
60
63
|
klass
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def eager_load_indices!
|
65
|
-
return false unless Esse.config.indices_directory.exist?
|
66
|
-
|
67
|
-
Esse.config.indices_directory.each_child do |path|
|
68
|
-
next unless path.extname == '.rb'
|
69
|
-
|
70
|
-
require(path.expand_path.to_s)
|
71
|
-
end
|
72
|
-
true
|
64
|
+
end.reject(&:abstract_class?)
|
73
65
|
end
|
74
66
|
end
|
75
67
|
end
|
@@ -8,14 +8,18 @@ module Esse
|
|
8
8
|
def run
|
9
9
|
validate_options!
|
10
10
|
indices.each do |index|
|
11
|
-
|
11
|
+
if (repo = @options[:repo])
|
12
|
+
index.elasticsearch.import!(repo, **options)
|
13
|
+
else
|
14
|
+
index.elasticsearch.import!(**options)
|
15
|
+
end
|
12
16
|
end
|
13
17
|
end
|
14
18
|
|
15
19
|
private
|
16
20
|
|
17
21
|
def options
|
18
|
-
@options.slice(*@options.keys - CLI_IGNORE_OPTS)
|
22
|
+
@options.slice(*@options.keys - CLI_IGNORE_OPTS - [:repo])
|
19
23
|
end
|
20
24
|
|
21
25
|
def validate_options!
|
@@ -8,10 +8,9 @@ module Esse
|
|
8
8
|
def run
|
9
9
|
validate_options!
|
10
10
|
indices.each do |index|
|
11
|
-
if index.
|
12
|
-
index.
|
13
|
-
|
14
|
-
index.elasticsearch.update_mapping!(type: type.type_name, **options)
|
11
|
+
if !index.mapping_single_type?
|
12
|
+
index.repo_hash.values.map(&:document_type).uniq.each do |doc_type|
|
13
|
+
index.elasticsearch.update_mapping!(type: doc_type, **options)
|
15
14
|
end
|
16
15
|
else
|
17
16
|
index.elasticsearch.update_mapping!(**options)
|
data/lib/esse/cli/index.rb
CHANGED
@@ -15,6 +15,7 @@ module Esse
|
|
15
15
|
* Delete the old index.
|
16
16
|
DESC
|
17
17
|
option :suffix, type: :string, default: nil, aliases: '-s', desc: 'Suffix to append to index name'
|
18
|
+
option :import, type: :boolean, default: true, desc: 'Import documents before point alias to the new index'
|
18
19
|
def reset(*index_classes)
|
19
20
|
require_relative 'index/reset'
|
20
21
|
Reset.new(indices: index_classes, **options.to_h.transform_keys(&:to_sym)).run
|
@@ -81,6 +82,7 @@ module Esse
|
|
81
82
|
desc 'import *INDEX_CLASSES', 'Import documents from the given classes'
|
82
83
|
option :suffix, type: :string, default: nil, aliases: '-s', desc: 'Suffix to append to index name'
|
83
84
|
option :context, type: :hash, default: {}, required: true, desc: 'List of options to pass to the index class'
|
85
|
+
option :repo, type: :string, default: nil, alias: '-r', desc: 'Repository to use for import'
|
84
86
|
def import(*index_classes)
|
85
87
|
require_relative 'index/import'
|
86
88
|
Import.new(indices: index_classes, **HashUtils.deep_transform_keys(options.to_h, &:to_sym)).run
|
@@ -2,36 +2,24 @@
|
|
2
2
|
|
3
3
|
class <%= @index_name %> < <%= @base_class %>
|
4
4
|
module Collections
|
5
|
-
class <%= @type.camelize %>Collection
|
6
|
-
|
7
|
-
|
8
|
-
# @param params [Hash] List of parameters
|
9
|
-
def initialize(**params)
|
10
|
-
@params = params
|
11
|
-
end
|
12
|
-
|
13
|
-
# Find all <%= @type %> in batches
|
14
|
-
#
|
5
|
+
class <%= @type.camelize if @type %>Collection < Esse::Collection
|
6
|
+
<%- if @type -%>
|
15
7
|
# @yield [Array<<%= @type.camelize %>>]
|
16
8
|
# @see <%= @index_name %>::<%= @type.camelize %>#collection
|
9
|
+
<%- end -%>
|
17
10
|
def each
|
18
11
|
offset = 0
|
19
12
|
while (rows = find_all(offset))
|
20
13
|
break if rows.none?
|
21
|
-
|
22
|
-
# You may preload associations before serialize them
|
23
|
-
# associations = preload_associations!(rows)
|
24
|
-
# yield(row, associations)
|
25
14
|
offset += 1
|
26
|
-
|
27
|
-
|
15
|
+
yield(rows)
|
16
|
+
# You may also preload associations here or add metadata useful for the serializer
|
17
|
+
# yield(rows, **preload_associations(rows))
|
28
18
|
end
|
29
19
|
end
|
30
20
|
|
31
21
|
protected
|
32
22
|
|
33
|
-
attr_reader :params
|
34
|
-
|
35
23
|
# @param offset [Number] Offset to start from
|
36
24
|
def find_all(offset)
|
37
25
|
# @TODO load data from persistent store
|
@@ -8,13 +8,23 @@ Esse.configure do |config|
|
|
8
8
|
# you also can add environment to the index prefix if available:
|
9
9
|
# cluster.index_prefix = "esse_#{ENV['RACK_ENV']}"
|
10
10
|
#
|
11
|
-
# Initialize the ElastiSearch client to be used by the default cluster
|
12
|
-
cluster.client = Elasticsearch::Client.new
|
11
|
+
# Initialize the ElastiSearch/OpenSearch client to be used by the default cluster
|
12
|
+
# cluster.client = Elasticsearch::Client.new or OpenSearch::Client.new
|
13
13
|
|
14
14
|
# Global index settings
|
15
|
-
# cluster.
|
15
|
+
# cluster.settings = {
|
16
16
|
# number_of_shards: 5,
|
17
17
|
# number_of_replicas: 0,
|
18
18
|
# }
|
19
|
+
|
20
|
+
# Global index mappings
|
21
|
+
# cluster.mappings = {
|
22
|
+
# dynamic_templates: [
|
23
|
+
# # ... Dynamic templates ...
|
24
|
+
# ],
|
25
|
+
# properties: {
|
26
|
+
# # ... Explicit mapping
|
27
|
+
# },
|
28
|
+
# }
|
19
29
|
end
|
20
30
|
end
|
@@ -2,123 +2,67 @@
|
|
2
2
|
|
3
3
|
<%- @types.each do |type| -%>
|
4
4
|
require_relative '<%= @index_name.demodulize.underscore.to_s %>/collections/<%= type.underscore %>_collection'
|
5
|
-
<%- end -%>
|
5
|
+
<%- end if @cli_options[:collections] && !@cli_options[:active_record] -%>
|
6
6
|
<%- @types.each do |type| -%>
|
7
7
|
require_relative '<%= @index_name.demodulize.underscore.to_s %>/serializers/<%= type.underscore %>_serializer'
|
8
|
-
<%- end -%>
|
9
|
-
|
8
|
+
<%- end if @cli_options[:serializers] -%>
|
10
9
|
class <%= @index_name %> < <%= @base_class %>
|
11
|
-
|
12
|
-
|
10
|
+
<%- if @cli_options[:active_record] -%>
|
11
|
+
plugin :active_record
|
13
12
|
|
13
|
+
<%- end -%>
|
14
14
|
<%- if @types.empty? -%>
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
# end
|
28
|
-
#
|
29
|
-
# Serializer block or class yielder should be called with an array of objects.
|
30
|
-
# Each these objects should be serialized using the serializer in described in the next section.
|
31
|
-
# The number of objects will be indexed to elasticsearch using the bulk api. So adjust the
|
32
|
-
# number of objects to be indexed accordingly.
|
33
|
-
#
|
34
|
-
# Here is a good place to eager loading data from database or any other repository.
|
35
|
-
# The bellow example is a rails like application that could preload using activerecord
|
36
|
-
#
|
37
|
-
# collection do |**context, &block|
|
38
|
-
# query = <%= @index_name.camelize %>.all
|
39
|
-
# query = query.where(**context[:conditions]) if context[:conditions]
|
40
|
-
# query = query.includes(:user) if context[:include_user]
|
41
|
-
# query.find_in_batches(batch_size: 5000) do |batch|
|
42
|
-
# block.call batch, context
|
43
|
-
# end
|
44
|
-
# end
|
45
|
-
|
46
|
-
|
47
|
-
# Serializer
|
48
|
-
# ==========
|
49
|
-
#
|
50
|
-
# Serializer is the class responsible for serializing indexing documents.
|
51
|
-
# Each object yielded by the collection will be serialized on this step.
|
52
|
-
# We recommend using a another class to handle the serialization. The only requirement is
|
53
|
-
# that the class implements the `#to_h` method.
|
54
|
-
# The serializer class may also be initialized with context if collection block is called with that extra parameter.
|
55
|
-
# Ability to call serializer with context is useful for preloading data from database or any other repository.
|
56
|
-
#
|
57
|
-
# serializer Serializers::DocumentSerializer
|
58
|
-
#
|
59
|
-
# You can also serialize the collection entry using a block:
|
60
|
-
#
|
61
|
-
# serializer do |model, context|
|
62
|
-
# hash = {
|
63
|
-
# name: <%= @index_name.underscore %>.name,
|
64
|
-
# }
|
65
|
-
# # Context is just an example here. But it's useful for eager loading data.
|
66
|
-
# # I'll think a better example when implement this idea.
|
67
|
-
# hash[:some_attribute] = <%= @index_name.underscore %>.some_attribute if context[:include_some_attribute]
|
68
|
-
# hash
|
69
|
-
# end
|
15
|
+
<%- if @cli_options[:active_record] -%>
|
16
|
+
collection ::<%= @index_name.camelize %>.all
|
17
|
+
<%- elsif @cli_options[:collections] -%>
|
18
|
+
collection Collections::Collection
|
19
|
+
<%- else -%>
|
20
|
+
collection do |**context, &block|
|
21
|
+
query = <%= @index_name.camelize.sub(/Index$/, '') %>.all
|
22
|
+
query = query.where(id: context[:id]) if context[:id]
|
23
|
+
query.find_in_batches(batch_size: 1_000) do |batch|
|
24
|
+
block.call(batch)
|
25
|
+
end
|
26
|
+
end
|
70
27
|
<%- end -%>
|
28
|
+
<%- if @cli_options[:serializers] -%>
|
29
|
+
serializer Serializers::Serializer
|
30
|
+
<%- else -%>
|
31
|
+
serializer do |object, **_context|
|
32
|
+
{
|
33
|
+
id: object.id,
|
34
|
+
name: object.name,
|
35
|
+
}
|
36
|
+
end
|
37
|
+
<%- end # if @cli_options[:serializers] -%>
|
38
|
+
<%- end # /@types.empty?-%>
|
39
|
+
|
71
40
|
<%- @types.each do |type| -%>
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
# Collection wraps the data into an array of items that should be serialized. The first argument that is
|
77
|
-
# yielded must extends Enumerable.
|
78
|
-
# Useful for eager loading data from database or any other repository. Below is an example of a rails like
|
79
|
-
# application could load using activerecord.
|
80
|
-
#
|
81
|
-
# collection do |**context, &block|
|
82
|
-
# <%= type.camelize %>.where(context[:conditions]).find_in_batches(batch_size: 5000) do |batch|
|
83
|
-
# block.call batch, context
|
84
|
-
# end
|
85
|
-
# end
|
41
|
+
repository :<%= type.underscore %> do
|
42
|
+
<%- if @cli_options[:active_record] -%>
|
43
|
+
collection ::<%= type.camelize %>.all
|
44
|
+
<%- elsif @cli_options[:collections] -%>
|
86
45
|
collection Collections::<%= type.camelize %>Collection
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
# class <%= type.camelize %>Serializer
|
98
|
-
# def initialize(<%= type %>, _context)
|
99
|
-
# @<%= type %> = <%= type %>
|
100
|
-
# end
|
101
|
-
#
|
102
|
-
# def to_h
|
103
|
-
# { '_id' => @<%= type %>.id, 'name' => @<%= type %>.name }
|
104
|
-
# end
|
105
|
-
# end
|
106
|
-
#
|
107
|
-
# And here you specify your serializer classe.
|
108
|
-
# serializer Serializers::<%= type.camelize %>Serializer
|
109
|
-
#
|
110
|
-
# You can also serialize the collection entry using a block:
|
111
|
-
#
|
112
|
-
# serializer do |model, **context|
|
113
|
-
# hash = {
|
114
|
-
# name: <%= type %>.name,
|
115
|
-
# }
|
116
|
-
# # Context is just an example here. But it's useful for eager loading data.
|
117
|
-
# # I'll think a better example when implement this idea.
|
118
|
-
# hash[:some_attribute] = <%= type %>.some_attribute if context[:include_some_attribute]
|
119
|
-
# hash
|
120
|
-
# end
|
46
|
+
<%- else -%>
|
47
|
+
collection do |**context, &block|
|
48
|
+
query = <%= type.camelize %>.all
|
49
|
+
query = query.where(id: context[:id]) if context[:id]
|
50
|
+
query.find_in_batches(batch_size: 1_000) do |batch|
|
51
|
+
block.call(batch)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
<%- end -%>
|
55
|
+
<%- if @cli_options[:serializers] -%>
|
121
56
|
serializer Serializers::<%= type.camelize %>Serializer
|
57
|
+
<%- else -%>
|
58
|
+
serializer do |<%= type.underscore %>, **_context|
|
59
|
+
{
|
60
|
+
id: <%= type.underscore %>.id,
|
61
|
+
name: <%= @index_name.underscore %>.name,
|
62
|
+
}
|
63
|
+
end
|
64
|
+
<%- end -%>
|
122
65
|
end
|
123
|
-
|
66
|
+
|
67
|
+
<%- end #@types.each do |type| -%>
|
124
68
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
{
|
2
|
+
"dynamic_templates": [
|
3
|
+
{
|
4
|
+
"string_template": {
|
5
|
+
"match": "*",
|
6
|
+
"match_mapping_type": "string",
|
7
|
+
"mapping": {
|
8
|
+
"fields": {
|
9
|
+
"analyzed": {
|
10
|
+
"analyzer": "esse_index",
|
11
|
+
"index": true,
|
12
|
+
"type": "text"
|
13
|
+
}
|
14
|
+
},
|
15
|
+
"ignore_above": 30000,
|
16
|
+
"type": "keyword"
|
17
|
+
}
|
18
|
+
}
|
19
|
+
}
|
20
|
+
],
|
21
|
+
"properties": {
|
22
|
+
"slug": {
|
23
|
+
"type": "keyword",
|
24
|
+
"ignore_above": 255
|
25
|
+
}
|
26
|
+
}
|
27
|
+
}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class <%= @index_name %> < <%= @base_class %>
|
4
|
+
module Serializers
|
5
|
+
class <%= @type.camelize if @type %>Serializer < Esse::Serializer
|
6
|
+
<%- if @cli_options[:active_record] -%>
|
7
|
+
delegate :id, to: :object
|
8
|
+
<%- else -%>
|
9
|
+
def id
|
10
|
+
object.id
|
11
|
+
end
|
12
|
+
<%- end -%>
|
13
|
+
|
14
|
+
def source
|
15
|
+
{
|
16
|
+
name: object.name,
|
17
|
+
<%- if @type -%>
|
18
|
+
type: "<%= @type %>",
|
19
|
+
<%- end -%>
|
20
|
+
<%- if @cli_options[:active_record] -%>
|
21
|
+
created_at: object.created_at,
|
22
|
+
updated_at: object.updated_at,
|
23
|
+
<%- end -%>
|
24
|
+
}
|
25
|
+
end
|
26
|
+
<%- if @type && defined?(Elasticsearch::VERSION) && Elasticsearch::VERSION <= '5' -%>
|
27
|
+
|
28
|
+
def type
|
29
|
+
'<%= @type %>'
|
30
|
+
end
|
31
|
+
<%- end -%>
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
{
|
2
|
+
"index": {
|
3
|
+
"max_ngram_diff": 5,
|
4
|
+
"max_shingle_diff": 3,
|
5
|
+
"analysis": {
|
6
|
+
"filter": {
|
7
|
+
"esse_search_shingle": {
|
8
|
+
"token_separator": "",
|
9
|
+
"output_unigrams_if_no_shingles": "true",
|
10
|
+
"output_unigrams": "false",
|
11
|
+
"type": "shingle"
|
12
|
+
},
|
13
|
+
"esse_index_shingle": {
|
14
|
+
"token_separator": "",
|
15
|
+
"type": "shingle"
|
16
|
+
},
|
17
|
+
"esse_stemmer": {
|
18
|
+
"type": "stemmer",
|
19
|
+
"language": "English"
|
20
|
+
}
|
21
|
+
},
|
22
|
+
"analyzer": {
|
23
|
+
"esse_index": {
|
24
|
+
"filter": [
|
25
|
+
"lowercase",
|
26
|
+
"asciifolding",
|
27
|
+
"english_stop",
|
28
|
+
"esse_index_shingle",
|
29
|
+
"esse_stemmer"
|
30
|
+
],
|
31
|
+
"char_filter": [
|
32
|
+
"ampersand"
|
33
|
+
],
|
34
|
+
"type": "custom",
|
35
|
+
"tokenizer": "standard"
|
36
|
+
},
|
37
|
+
"esse_search": {
|
38
|
+
"filter": [
|
39
|
+
"lowercase",
|
40
|
+
"asciifolding",
|
41
|
+
"english_stop",
|
42
|
+
"esse_search_shingle",
|
43
|
+
"esse_stemmer"
|
44
|
+
],
|
45
|
+
"char_filter": [
|
46
|
+
"ampersand"
|
47
|
+
],
|
48
|
+
"type": "custom",
|
49
|
+
"tokenizer": "standard"
|
50
|
+
}
|
51
|
+
},
|
52
|
+
"char_filter": {
|
53
|
+
"ampersand": {
|
54
|
+
"type": "mapping",
|
55
|
+
"mappings": [
|
56
|
+
"&=> and "
|
57
|
+
]
|
58
|
+
}
|
59
|
+
}
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}
|