esse 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/lib/esse/backend/index/aliases.rb +8 -8
  3. data/lib/esse/backend/index/close.rb +3 -3
  4. data/lib/esse/backend/index/create.rb +4 -4
  5. data/lib/esse/backend/index/delete.rb +4 -4
  6. data/lib/esse/backend/index/documents.rb +253 -6
  7. data/lib/esse/backend/index/existance.rb +3 -3
  8. data/lib/esse/backend/index/open.rb +3 -3
  9. data/lib/esse/backend/index/refresh.rb +7 -5
  10. data/lib/esse/backend/index/reset.rb +4 -4
  11. data/lib/esse/backend/index/update.rb +7 -7
  12. data/lib/esse/backend/index.rb +16 -14
  13. data/lib/esse/backend/repository_backend.rb +105 -0
  14. data/lib/esse/cli/event_listener.rb +14 -0
  15. data/lib/esse/cli/generate.rb +53 -12
  16. data/lib/esse/cli/index/base_operation.rb +5 -13
  17. data/lib/esse/cli/index/import.rb +6 -2
  18. data/lib/esse/cli/index/update_mapping.rb +3 -4
  19. data/lib/esse/cli/index.rb +2 -0
  20. data/lib/esse/cli/templates/{type_collection.rb.erb → collection.rb.erb} +6 -18
  21. data/lib/esse/cli/templates/config.rb.erb +13 -3
  22. data/lib/esse/cli/templates/index.rb.erb +53 -109
  23. data/lib/esse/cli/templates/mappings.json +27 -0
  24. data/lib/esse/cli/templates/serializer.rb.erb +34 -0
  25. data/lib/esse/cli/templates/settings.json +62 -0
  26. data/lib/esse/client_proxy/search.rb +44 -0
  27. data/lib/esse/client_proxy.rb +32 -0
  28. data/lib/esse/cluster.rb +64 -9
  29. data/lib/esse/cluster_engine.rb +42 -0
  30. data/lib/esse/collection.rb +18 -0
  31. data/lib/esse/config.rb +14 -2
  32. data/lib/esse/core.rb +23 -6
  33. data/lib/esse/deprecations/cluster.rb +27 -0
  34. data/lib/esse/deprecations/index.rb +19 -0
  35. data/lib/esse/deprecations/repository.rb +19 -0
  36. data/lib/esse/deprecations.rb +3 -0
  37. data/lib/esse/dynamic_template.rb +39 -0
  38. data/lib/esse/errors.rb +53 -2
  39. data/lib/esse/events/event.rb +4 -19
  40. data/lib/esse/events.rb +3 -0
  41. data/lib/esse/hash_document.rb +38 -0
  42. data/lib/esse/import/bulk.rb +96 -0
  43. data/lib/esse/import/request_body.rb +60 -0
  44. data/lib/esse/index/attributes.rb +98 -0
  45. data/lib/esse/index/base.rb +1 -1
  46. data/lib/esse/index/inheritance.rb +30 -0
  47. data/lib/esse/index/mappings.rb +6 -19
  48. data/lib/esse/index/object_document_mapper.rb +95 -0
  49. data/lib/esse/index/plugins.rb +42 -0
  50. data/lib/esse/index/search.rb +27 -0
  51. data/lib/esse/index/settings.rb +2 -2
  52. data/lib/esse/index/type.rb +52 -11
  53. data/lib/esse/index.rb +10 -6
  54. data/lib/esse/index_mapping.rb +10 -2
  55. data/lib/esse/index_setting.rb +3 -1
  56. data/lib/esse/null_document.rb +35 -0
  57. data/lib/esse/plugins.rb +12 -0
  58. data/lib/esse/primitives/hstring.rb +1 -1
  59. data/lib/esse/{index_type → repository}/actions.rb +1 -1
  60. data/lib/esse/{index_type → repository}/backend.rb +2 -2
  61. data/lib/esse/repository/object_document_mapper.rb +157 -0
  62. data/lib/esse/repository.rb +18 -0
  63. data/lib/esse/search/query.rb +105 -0
  64. data/lib/esse/search/response.rb +46 -0
  65. data/lib/esse/serializer.rb +76 -0
  66. data/lib/esse/version.rb +1 -1
  67. data/lib/esse.rb +20 -5
  68. metadata +35 -30
  69. data/lib/esse/backend/index_type/documents.rb +0 -214
  70. data/lib/esse/backend/index_type.rb +0 -37
  71. data/lib/esse/cli/templates/type_mappings.json +0 -6
  72. data/lib/esse/cli/templates/type_serializer.rb.erb +0 -23
  73. data/lib/esse/index/naming.rb +0 -64
  74. data/lib/esse/index_type/mappings.rb +0 -42
  75. data/lib/esse/index_type.rb +0 -15
  76. 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
@@ -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
- @types.each do |type|
31
- @type = Hstring.new(type).underscore
40
+
41
+ if options[:settings]
32
42
  copy_file(
33
- 'templates/type_mappings.json',
34
- base_dir.join(index_name, 'templates', "#{@type}_mapping.json"),
43
+ 'templates/settings.json',
44
+ base_dir.join(index_name, 'templates', 'settings.json'),
35
45
  )
36
- template(
37
- 'templates/type_serializer.rb.erb',
38
- base_dir.join(index_name, 'serializers', "#{@type}_serializer.rb"),
39
- )
40
- template(
41
- 'templates/type_collection.rb.erb',
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
- index.elasticsearch.import!(**options)
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.type_hash.any?
12
- index.type_hash.each_value do |type|
13
- # @idea Add update_mapping! to IndexType and use it here
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)
@@ -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
- include Enumerable
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
- yield(rows, **params)
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.index_settings = {
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
- # plugin :active_record
12
- # plugin :sequel
10
+ <%- if @cli_options[:active_record] -%>
11
+ plugin :active_record
13
12
 
13
+ <%- end -%>
14
14
  <%- if @types.empty? -%>
15
- # Collection
16
- # ==========
17
- #
18
- # Collection is the source of data for the index. We hightly recommend using a
19
- # another class that implements the Enumerable interface to better split the
20
- # responsabilities and easy to test.
21
- #
22
- # collection Collections::DocumentCollection
23
- #
24
- # but you can also use block definition style:
25
- # collection do |**context, &block|
26
- # block.call [{ title: 'foo' }, { title: 'bar' }], extra: 'info'
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
- define_type :<%= type.underscore %> do
73
- # Collection
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
- # Serializer
90
- # ==========
91
- #
92
- # The serializer can be any class that respond with the `to_h` class method.
93
- # And the result of its to_h is a Hash.
94
- #
95
- # Here is an example of a simple serializer:
96
- # app/serializers/<%= type %>_serializer.rb
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
- <%- end -%>
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
+ }