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