esse 0.2.0 → 0.2.3

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 (98) hide show
  1. checksums.yaml +4 -4
  2. data/lib/esse/cli/event_listener.rb +13 -0
  3. data/lib/esse/cli/generate.rb +53 -14
  4. data/lib/esse/cli/index/base_operation.rb +5 -13
  5. data/lib/esse/cli/index/close.rb +1 -1
  6. data/lib/esse/cli/index/create.rb +1 -1
  7. data/lib/esse/cli/index/delete.rb +1 -1
  8. data/lib/esse/cli/index/import.rb +6 -2
  9. data/lib/esse/cli/index/open.rb +1 -1
  10. data/lib/esse/cli/index/reset.rb +1 -1
  11. data/lib/esse/cli/index/update_aliases.rb +2 -2
  12. data/lib/esse/cli/index/update_mapping.rb +9 -5
  13. data/lib/esse/cli/index/update_settings.rb +1 -1
  14. data/lib/esse/cli/index.rb +11 -4
  15. data/lib/esse/cli/templates/collection.rb.erb +29 -0
  16. data/lib/esse/cli/templates/config.rb.erb +13 -3
  17. data/lib/esse/cli/templates/document.rb.erb +34 -0
  18. data/lib/esse/cli/templates/index.rb.erb +63 -114
  19. data/lib/esse/cli/templates/mappings.json +27 -0
  20. data/lib/esse/cli/templates/settings.json +62 -0
  21. data/lib/esse/cli.rb +5 -0
  22. data/lib/esse/cluster.rb +93 -12
  23. data/lib/esse/cluster_engine.rb +42 -0
  24. data/lib/esse/collection.rb +18 -0
  25. data/lib/esse/config.rb +14 -2
  26. data/lib/esse/core.rb +28 -7
  27. data/lib/esse/deprecations/cluster.rb +27 -0
  28. data/lib/esse/deprecations/deprecate.rb +29 -0
  29. data/lib/esse/deprecations/index.rb +37 -0
  30. data/lib/esse/deprecations/index_backend_delegator.rb +217 -0
  31. data/lib/esse/deprecations/repository.rb +34 -0
  32. data/lib/esse/deprecations/repository_backend_delegator.rb +110 -0
  33. data/lib/esse/deprecations/serializer.rb +14 -0
  34. data/lib/esse/deprecations.rb +7 -0
  35. data/lib/esse/document.rb +91 -0
  36. data/lib/esse/dynamic_template.rb +43 -0
  37. data/lib/esse/errors.rb +60 -2
  38. data/lib/esse/events/event.rb +4 -19
  39. data/lib/esse/events.rb +13 -2
  40. data/lib/esse/hash_document.rb +38 -0
  41. data/lib/esse/import/bulk.rb +106 -0
  42. data/lib/esse/import/request_body.rb +60 -0
  43. data/lib/esse/index/aliases.rb +50 -0
  44. data/lib/esse/index/attributes.rb +107 -0
  45. data/lib/esse/index/base.rb +17 -53
  46. data/lib/esse/index/documents.rb +236 -0
  47. data/lib/esse/index/indices.rb +171 -0
  48. data/lib/esse/index/inheritance.rb +30 -0
  49. data/lib/esse/index/mappings.rb +6 -19
  50. data/lib/esse/index/object_document_mapper.rb +36 -0
  51. data/lib/esse/index/plugins.rb +42 -0
  52. data/lib/esse/index/search.rb +27 -0
  53. data/lib/esse/index/settings.rb +2 -2
  54. data/lib/esse/index/type.rb +51 -11
  55. data/lib/esse/index.rb +14 -9
  56. data/lib/esse/index_mapping.rb +10 -2
  57. data/lib/esse/index_setting.rb +3 -1
  58. data/lib/esse/null_document.rb +35 -0
  59. data/lib/esse/plugins.rb +12 -0
  60. data/lib/esse/primitives/hstring.rb +1 -1
  61. data/lib/esse/{index_type → repository}/actions.rb +1 -1
  62. data/lib/esse/repository/documents.rb +13 -0
  63. data/lib/esse/repository/object_document_mapper.rb +157 -0
  64. data/lib/esse/repository.rb +17 -0
  65. data/lib/esse/search/query.rb +105 -0
  66. data/lib/esse/search/response.rb +46 -0
  67. data/lib/esse/template_loader.rb +1 -1
  68. data/lib/esse/transport/aliases.rb +36 -0
  69. data/lib/esse/transport/documents.rb +199 -0
  70. data/lib/esse/transport/health.rb +30 -0
  71. data/lib/esse/transport/indices.rb +192 -0
  72. data/lib/esse/transport/search.rb +48 -0
  73. data/lib/esse/transport.rb +44 -0
  74. data/lib/esse/version.rb +1 -1
  75. data/lib/esse.rb +20 -5
  76. metadata +55 -50
  77. data/lib/esse/backend/index/aliases.rb +0 -73
  78. data/lib/esse/backend/index/close.rb +0 -54
  79. data/lib/esse/backend/index/create.rb +0 -67
  80. data/lib/esse/backend/index/delete.rb +0 -39
  81. data/lib/esse/backend/index/documents.rb +0 -23
  82. data/lib/esse/backend/index/existance.rb +0 -22
  83. data/lib/esse/backend/index/open.rb +0 -54
  84. data/lib/esse/backend/index/refresh.rb +0 -43
  85. data/lib/esse/backend/index/reset.rb +0 -33
  86. data/lib/esse/backend/index/update.rb +0 -143
  87. data/lib/esse/backend/index.rb +0 -54
  88. data/lib/esse/backend/index_type/documents.rb +0 -214
  89. data/lib/esse/backend/index_type.rb +0 -37
  90. data/lib/esse/cli/templates/type_collection.rb.erb +0 -41
  91. data/lib/esse/cli/templates/type_mappings.json +0 -6
  92. data/lib/esse/cli/templates/type_serializer.rb.erb +0 -23
  93. data/lib/esse/index/backend.rb +0 -14
  94. data/lib/esse/index/naming.rb +0 -64
  95. data/lib/esse/index_type/backend.rb +0 -14
  96. data/lib/esse/index_type/mappings.rb +0 -42
  97. data/lib/esse/index_type.rb +0 -15
  98. data/lib/esse/object_document_mapper.rb +0 -110
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a31d2a1c181dccd9c2acd7256d958010e7c636016b1d5a267597f7aec9ed3334
4
- data.tar.gz: cdb390a10b0492833a9360d4fd39df0c18df114a44b37554cba1dd39d229f75b
3
+ metadata.gz: 30ce86d71e0cf9b67506dd0caf1651b91ae836c9e7981e46a238446c8afde078
4
+ data.tar.gz: 9ec1069cbb8106743d5832f94fbce5d2c937037a62a746350e736385f3b78cdc
5
5
  SHA512:
6
- metadata.gz: 59ae5dcafd8998c69e5705910b119f5f9d1333899a4320b8f7afa4c5782aa435d820dde222726de111cee00c6d3b4bbed9d6fdd18dac6a6f740cf64138b70d53
7
- data.tar.gz: 84b876eaec5b090718e2d265dd5d9456c5dfaeedafdae6e9361ac790de91eab0ba46b9ceabee3c5e8a891c5027ff3ac8443217554219f8dce5f52c853912989c
6
+ metadata.gz: f2a5012e3d3dab0b3894f8e8fb1665be2a57c8538a3fc02bce2ac089510bd63b982f8f919554a9f16d6e8dafe5d93d9f5614d99ca4f170d82cc41e413fec0209
7
+ data.tar.gz: 034b15fd5cfc4f6ebdd97ba9d73ed284f50c209225b2c6a43b27216a57578ca1b91d9c92d4e020c4a1c7910038cf5978054bfa4b491bafb431bcfc1dcbc0a706
@@ -82,6 +82,19 @@ 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
+ stats = event[:request][:body_stats].select { |_, v| v.nonzero? }.map do |type, count|
94
+ "#{colorize(type, :bold)}: #{count} docs"
95
+ end
96
+ print_message(stats.join(', ') + '.')
97
+ end
85
98
  end
86
99
  end
87
100
  end
@@ -14,34 +14,73 @@ module Esse
14
14
  end
15
15
 
16
16
  desc 'index NAME *TYPES', 'Creates a new index'
17
- def index(name, *types)
17
+ option :settings, type: :boolean, default: false, desc: 'Generate settings'
18
+ option :mappings, type: :boolean, default: false, desc: 'Generate mappings'
19
+ option :documents, type: :boolean, default: false, desc: 'Generate documents'
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'
23
+ def index(name, *repos)
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
- @types = types.map { |type| Hstring.new(type) }
27
+ @repos = repos.map { |repo| Hstring.new(repo) }
22
28
  @base_class = base_index_class(*ns_path)
29
+ @index_cluster_id = options[:cluster_id]
30
+ @cli_options = options
23
31
 
24
- base_dir = Esse.config.indices_directory.join(*ns_path)
32
+ base_dir = Esse.config.indices_directory.join(*ns_path.map { |n| Hstring.new(n).underscore.to_s })
25
33
  index_name = @index_name.demodulize.underscore.to_s
26
34
  template(
27
35
  'templates/index.rb.erb',
28
36
  base_dir.join("#{index_name}.rb"),
29
37
  )
30
- @types.each do |type|
31
- @type = Hstring.new(type).underscore
38
+
39
+ if options[:settings]
32
40
  copy_file(
33
- 'templates/type_mappings.json',
34
- base_dir.join(index_name, 'templates', "#{@type}_mapping.json"),
35
- )
36
- template(
37
- 'templates/type_serializer.rb.erb',
38
- base_dir.join(index_name, 'serializers', "#{@type}_serializer.rb"),
41
+ 'templates/settings.json',
42
+ base_dir.join(index_name, 'templates', 'settings.json'),
39
43
  )
40
- template(
41
- 'templates/type_collection.rb.erb',
42
- base_dir.join(index_name, 'collections', "#{@type}_collection.rb"),
44
+ end
45
+
46
+ if options[:mappings]
47
+ copy_file(
48
+ 'templates/mappings.json',
49
+ base_dir.join(index_name, 'templates', 'mappings.json'),
43
50
  )
44
51
  end
52
+
53
+ if @repos.empty?
54
+ if options[:documents]
55
+ template(
56
+ 'templates/document.rb.erb',
57
+ base_dir.join(index_name, 'documents', 'document.rb'),
58
+ )
59
+ end
60
+ if options[:collections] && !options[:active_record]
61
+ template(
62
+ 'templates/collection.rb.erb',
63
+ base_dir.join(index_name, 'collections', 'collection.rb'),
64
+ )
65
+ end
66
+ end
67
+
68
+ @repos.each do |type|
69
+ @repo = Hstring.new(type).underscore
70
+
71
+ if options[:documents]
72
+ template(
73
+ 'templates/document.rb.erb',
74
+ base_dir.join(index_name, 'documents', "#{@repo}_document.rb"),
75
+ )
76
+ end
77
+ if options[:collections] && !options[:active_record]
78
+ template(
79
+ 'templates/collection.rb.erb',
80
+ base_dir.join(index_name, 'collections', "#{@repo}_collection.rb"),
81
+ )
82
+ end
83
+ end
45
84
  end
46
85
 
47
86
  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,7 +8,7 @@ module Esse
8
8
  def run
9
9
  validate_options!
10
10
  indices.each do |index|
11
- index.elasticsearch.close!(**options)
11
+ index.close(**options)
12
12
  end
13
13
  end
14
14
 
@@ -8,7 +8,7 @@ module Esse
8
8
  def run
9
9
  validate_options!
10
10
  indices.each do |index|
11
- index.elasticsearch.create_index!(**options)
11
+ index.create_index(**options)
12
12
  end
13
13
  end
14
14
 
@@ -8,7 +8,7 @@ module Esse
8
8
  def run
9
9
  validate_options!
10
10
  indices.each do |index|
11
- index.elasticsearch.delete_index!(**options)
11
+ index.delete_index(**options)
12
12
  end
13
13
  end
14
14
 
@@ -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.import(repo, **options)
13
+ else
14
+ index.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,7 +8,7 @@ module Esse
8
8
  def run
9
9
  validate_options!
10
10
  indices.each do |index|
11
- index.elasticsearch.open!(**options)
11
+ index.open(**options)
12
12
  end
13
13
  end
14
14
 
@@ -8,7 +8,7 @@ module Esse
8
8
  def run
9
9
  validate_options!
10
10
  indices.each do |index|
11
- index.elasticsearch.reset_index!(**options)
11
+ index.reset_index(**options)
12
12
  end
13
13
  end
14
14
 
@@ -8,7 +8,7 @@ module Esse
8
8
  def run
9
9
  validate_options!
10
10
  indices.each do |index|
11
- index.elasticsearch.update_aliases!(**options)
11
+ index.update_aliases(**options)
12
12
  end
13
13
  end
14
14
 
@@ -21,7 +21,7 @@ module Esse
21
21
  def validate_options!
22
22
  validate_indices_option!
23
23
 
24
- if @options[:suffix].nil?
24
+ if @options[:suffix].nil? || @options[:suffix].empty?
25
25
  raise InvalidOption.new(<<~END)
26
26
  You must specify a suffix to update the aliases.
27
27
  END
@@ -8,13 +8,17 @@ 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
+ # Elasticsearch 6.x and older have multiple types per index.
13
+ # This gem supports multiple types per index for backward compatibility, but we recommend to update
14
+ # your elasticsearch to a at least 7.x version and use a single type per index.
15
+ #
16
+ # Note that the repository name will be used as the document type.
17
+ index.repo_hash.keys.each do |doc_type|
18
+ index.update_mapping(type: doc_type, **options)
15
19
  end
16
20
  else
17
- index.elasticsearch.update_mapping!(**options)
21
+ index.update_mapping(**options)
18
22
  end
19
23
  end
20
24
  end
@@ -8,7 +8,7 @@ module Esse
8
8
  def run
9
9
  validate_options!
10
10
  indices.each do |index|
11
- index.elasticsearch.update_settings!(**options)
11
+ index.update_settings(**options)
12
12
  end
13
13
  end
14
14
 
@@ -15,17 +15,20 @@ 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
21
22
  end
22
23
 
24
+ # @TODO Add reindex task to create a new index and import documents from the old index using _reindex API
25
+
23
26
  desc 'create *INDEX_CLASSES', 'Creates indices for the given classes'
24
27
  long_desc <<-DESC
25
28
  Creates index and applies mapping and settings for the given classes.
26
29
 
27
30
  Indices are created with the following naming convention:
28
- <cluster.index_prefix>_<index_class.index_name>_<index_class.index_version>.
31
+ <cluster.index_prefix>_<index_class.index_name>_<index_class.index_suffix>.
29
32
  DESC
30
33
  option :suffix, type: :string, default: nil, aliases: '-s', desc: 'Suffix to append to index name'
31
34
  option :alias, type: :boolean, default: false, aliases: '-a', desc: 'Update alias after create index'
@@ -41,11 +44,14 @@ module Esse
41
44
  Delete.new(indices: index_classes, **options.to_h.transform_keys(&:to_sym)).run
42
45
  end
43
46
 
44
- desc 'update_aliases *INDEX_CLASS', 'Replaces all existing aliases by the given suffix'
45
- option :suffix, type: :string, aliases: '-s', desc: 'Suffix to append to index name'
47
+ desc 'update_aliases *INDEX_CLASS', 'Replaces all existing aliases by the given suffix/suffixes'
48
+ option :suffix, type: :string, aliases: '-s', repeatable: true, desc: 'Suffix to append to index name'
46
49
  def update_aliases(*index_classes)
47
50
  require_relative 'index/update_aliases'
48
- UpdateAliases.new(indices: index_classes, **options.to_h.transform_keys(&:to_sym)).run
51
+
52
+ kwargs = options.to_h.transform_keys(&:to_sym)
53
+ kwargs[:suffix] = (kwargs[:suffix] || []).flat_map { |s| s.split(',') }.uniq
54
+ UpdateAliases.new(indices: index_classes, **kwargs).run
49
55
  end
50
56
 
51
57
  desc 'update_settings *INDEX_CLASS', 'Closes the index for read/write operations, updates the index settings, and open it again'
@@ -81,6 +87,7 @@ module Esse
81
87
  desc 'import *INDEX_CLASSES', 'Import documents from the given classes'
82
88
  option :suffix, type: :string, default: nil, aliases: '-s', desc: 'Suffix to append to index name'
83
89
  option :context, type: :hash, default: {}, required: true, desc: 'List of options to pass to the index class'
90
+ option :repo, type: :string, default: nil, alias: '-r', desc: 'Repository to use for import'
84
91
  def import(*index_classes)
85
92
  require_relative 'index/import'
86
93
  Import.new(indices: index_classes, **HashUtils.deep_transform_keys(options.to_h, &:to_sym)).run
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ class <%= @index_name %> < <%= @base_class %>
4
+ module Collections
5
+ class <%= @repo.camelize if @repo %>Collection < Esse::Collection
6
+ <%- if @repo -%>
7
+ # @yield [Array<<%= @repo.camelize %>>]
8
+ # @see <%= @index_name %>::<%= @repo.camelize %>#collection
9
+ <%- end -%>
10
+ def each
11
+ offset = 0
12
+ while (rows = find_all(offset))
13
+ break if rows.none?
14
+ offset += 1
15
+ yield(rows)
16
+ # You may also preload associations here or add metadata useful for the document
17
+ # yield(rows, **preload_associations(rows))
18
+ end
19
+ end
20
+
21
+ protected
22
+
23
+ # @param offset [Number] Offset to start from
24
+ def find_all(offset)
25
+ # @TODO load data from persistent storage
26
+ end
27
+ end
28
+ end
29
+ end
@@ -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
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ class <%= @index_name %> < <%= @base_class %>
4
+ module Documents
5
+ class <%= @repo.camelize if @repo %>Document < Esse::Document
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 @repo && defined?(Elasticsearch::VERSION) && Elasticsearch::VERSION > '5' -%>
18
+ type: "<%= @repo %>",
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 @repo && defined?(Elasticsearch::VERSION) && Elasticsearch::VERSION <= '5' -%>
27
+
28
+ def type
29
+ '<%= @repo %>'
30
+ end
31
+ <%- end -%>
32
+ end
33
+ end
34
+ end
@@ -1,124 +1,73 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- <%- @types.each do |type| -%>
3
+ <%- @repos.each do |type| -%>
4
4
  require_relative '<%= @index_name.demodulize.underscore.to_s %>/collections/<%= type.underscore %>_collection'
5
- <%- end -%>
6
- <%- @types.each do |type| -%>
7
- require_relative '<%= @index_name.demodulize.underscore.to_s %>/serializers/<%= type.underscore %>_serializer'
8
- <%- end -%>
9
-
5
+ <%- end if @cli_options[:collections] && !@cli_options[:active_record] -%>
6
+ <%- @repos.each do |type| -%>
7
+ require_relative '<%= @index_name.demodulize.underscore.to_s %>/documents/<%= type.underscore %>_document'
8
+ <%- end if @cli_options[:documents] -%>
10
9
  class <%= @index_name %> < <%= @base_class %>
11
- # plugin :active_record
12
- # plugin :sequel
10
+ <%-if @index_cluster_id -%>
11
+ self.cluster_id = :<%= @index_cluster_id %>
12
+ <%- end -%>
13
+ <%- if @cli_options[:active_record] -%>
14
+ plugin :active_record
13
15
 
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
16
+ <%- end -%>
17
+ <%- if @repos.empty? -%>
18
+ repository :default do
19
+ <%- if @cli_options[:active_record] -%>
20
+ collection ::<%= @index_name.camelize %>.all
21
+ <%- elsif @cli_options[:collections] -%>
22
+ collection Collections::Collection
23
+ <%- else -%>
24
+ collection do |**context, &block|
25
+ query = <%= @index_name.camelize.sub(/Index$/, '') %>.all
26
+ query = query.where(id: context[:id]) if context[:id]
27
+ query.find_in_batches(batch_size: 1_000) do |batch|
28
+ block.call(batch, **context)
29
+ end
30
+ end
31
+ <%- end -%>
45
32
 
33
+ <%- if @cli_options[:documents] -%>
34
+ document Documents::Document
35
+ <%- else -%>
36
+ document do |object, **_context|
37
+ {
38
+ id: object.id,
39
+ name: object.name,
40
+ }
41
+ end
42
+ <%- end # if @cli_options[:documents] -%>
43
+ end
44
+ <%- end # /@repos.empty?-%>
45
+ <%- @repos.each do |type| -%>
46
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
70
- <%- end -%>
71
- <%- @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
47
+ repository :<%= type.underscore %> do
48
+ <%- if @cli_options[:active_record] -%>
49
+ collection ::<%= type.camelize %>.all
50
+ <%- elsif @cli_options[:collections] -%>
86
51
  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
121
- serializer Serializers::<%= type.camelize %>Serializer
52
+ <%- else -%>
53
+ collection do |**context, &block|
54
+ query = <%= type.camelize %>.all
55
+ query = query.where(id: context[:id]) if context[:id]
56
+ query.find_in_batches(batch_size: 1_000) do |batch|
57
+ block.call(batch, **context)
58
+ end
59
+ end
60
+ <%- end -%>
61
+ <%- if @cli_options[:documents] -%>
62
+ document Documents::<%= type.camelize %>Document
63
+ <%- else -%>
64
+ document do |<%= type.underscore %>, **_context|
65
+ {
66
+ id: <%= type.underscore %>.id,
67
+ name: <%= @index_name.underscore %>.name,
68
+ }
69
+ end
70
+ <%- end -%>
122
71
  end
123
- <%- end -%>
72
+ <%- end #@repos.each do |type| -%>
124
73
  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
+ }