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
@@ -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
|
+
}
|