esse 0.2.2 → 0.2.4

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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/exec/esse +2 -0
  3. data/lib/esse/cli/event_listener.rb +4 -5
  4. data/lib/esse/cli/extensions_loader.rb +22 -0
  5. data/lib/esse/cli/generate.rb +14 -16
  6. data/lib/esse/cli/index/close.rb +1 -1
  7. data/lib/esse/cli/index/create.rb +1 -1
  8. data/lib/esse/cli/index/delete.rb +1 -1
  9. data/lib/esse/cli/index/import.rb +2 -2
  10. data/lib/esse/cli/index/open.rb +1 -1
  11. data/lib/esse/cli/index/reset.rb +1 -1
  12. data/lib/esse/cli/index/update_aliases.rb +2 -2
  13. data/lib/esse/cli/index/update_mapping.rb +8 -3
  14. data/lib/esse/cli/index/update_settings.rb +1 -1
  15. data/lib/esse/cli/index.rb +9 -4
  16. data/lib/esse/cli/templates/collection.rb.erb +6 -6
  17. data/lib/esse/cli/templates/{serializer.rb.erb → document.rb.erb} +6 -6
  18. data/lib/esse/cli/templates/index.rb.erb +39 -34
  19. data/lib/esse/cli.rb +6 -0
  20. data/lib/esse/cluster.rb +44 -12
  21. data/lib/esse/core.rb +7 -3
  22. data/lib/esse/deprecations/cluster.rb +5 -5
  23. data/lib/esse/deprecations/deprecate.rb +29 -0
  24. data/lib/esse/deprecations/index.rb +21 -3
  25. data/lib/esse/deprecations/index_backend_delegator.rb +217 -0
  26. data/lib/esse/deprecations/repository.rb +19 -4
  27. data/lib/esse/deprecations/repository_backend_delegator.rb +110 -0
  28. data/lib/esse/deprecations/serializer.rb +14 -0
  29. data/lib/esse/deprecations.rb +4 -0
  30. data/lib/esse/{serializer.rb → document.rb} +17 -2
  31. data/lib/esse/dynamic_template.rb +4 -0
  32. data/lib/esse/errors.rb +8 -1
  33. data/lib/esse/events.rb +13 -5
  34. data/lib/esse/hash_document.rb +1 -1
  35. data/lib/esse/import/bulk.rb +21 -11
  36. data/lib/esse/index/aliases.rb +50 -0
  37. data/lib/esse/index/attributes.rb +14 -5
  38. data/lib/esse/index/base.rb +17 -53
  39. data/lib/esse/index/documents.rb +236 -0
  40. data/lib/esse/index/indices.rb +171 -0
  41. data/lib/esse/index/object_document_mapper.rb +0 -59
  42. data/lib/esse/index/search.rb +8 -1
  43. data/lib/esse/index/type.rb +2 -3
  44. data/lib/esse/index.rb +4 -3
  45. data/lib/esse/null_document.rb +1 -1
  46. data/lib/esse/primitives/hash_utils.rb +11 -0
  47. data/lib/esse/repository/{backend.rb → documents.rb} +2 -3
  48. data/lib/esse/repository/object_document_mapper.rb +20 -20
  49. data/lib/esse/repository.rb +1 -2
  50. data/lib/esse/search/query/dsl.rb +61 -0
  51. data/lib/esse/search/query.rb +15 -17
  52. data/lib/esse/template_loader.rb +1 -1
  53. data/lib/esse/transport/aliases.rb +36 -0
  54. data/lib/esse/transport/documents.rb +199 -0
  55. data/lib/esse/transport/health.rb +30 -0
  56. data/lib/esse/transport/indices.rb +192 -0
  57. data/lib/esse/{client_proxy → transport}/search.rb +9 -5
  58. data/lib/esse/transport.rb +44 -0
  59. data/lib/esse/version.rb +1 -1
  60. metadata +30 -28
  61. data/lib/esse/backend/index/aliases.rb +0 -73
  62. data/lib/esse/backend/index/close.rb +0 -54
  63. data/lib/esse/backend/index/create.rb +0 -67
  64. data/lib/esse/backend/index/delete.rb +0 -39
  65. data/lib/esse/backend/index/documents.rb +0 -270
  66. data/lib/esse/backend/index/existance.rb +0 -22
  67. data/lib/esse/backend/index/open.rb +0 -54
  68. data/lib/esse/backend/index/refresh.rb +0 -45
  69. data/lib/esse/backend/index/reset.rb +0 -33
  70. data/lib/esse/backend/index/update.rb +0 -143
  71. data/lib/esse/backend/index.rb +0 -56
  72. data/lib/esse/backend/repository_backend.rb +0 -105
  73. data/lib/esse/client_proxy.rb +0 -32
  74. data/lib/esse/index/backend.rb +0 -14
@@ -6,6 +6,13 @@ module Esse
6
6
  # @param query_or_payload [String,Hash] The search request definition or query in the Lucene query string syntax
7
7
  # @param kwargs [Hash] The options to pass to the search.
8
8
  def search(*args, &block)
9
+ kwargs = extract_search_options!(args)
10
+ cluster.search(self, **kwargs, &block)
11
+ end
12
+
13
+ private
14
+
15
+ def extract_search_options!(args)
9
16
  query_or_payload = args.shift
10
17
  kwargs = args.last.is_a?(Hash) ? args.pop : {}
11
18
 
@@ -18,7 +25,7 @@ module Esse
18
25
  elsif query_or_payload.is_a?(String)
19
26
  kwargs[:q] = query_or_payload
20
27
  end
21
- cluster.search(self, **kwargs, &block)
28
+ kwargs
22
29
  end
23
30
  end
24
31
 
@@ -24,7 +24,7 @@ module Esse
24
24
 
25
25
  repository :#{name} do
26
26
  # collection ...
27
- # serializer ...
27
+ # document ...
28
28
  end
29
29
  MSG
30
30
  end
@@ -37,7 +37,7 @@ module Esse
37
37
 
38
38
  def repository(repo_name, *_args, **kwargs, &block)
39
39
  repo_class = Class.new(Esse::Repository)
40
- kwargs[:const] ||= true # TODO Change this to false to avoid collisions with application classes
40
+ kwargs[:const] = true unless kwargs.key?(:const) # TODO Change this to false to avoid collisions with application classes
41
41
  kwargs[:lazy_evaluate] ||= false
42
42
 
43
43
  if kwargs[:const]
@@ -48,7 +48,6 @@ module Esse
48
48
 
49
49
  repo_class.send(:define_singleton_method, :index) { index }
50
50
  repo_class.send(:define_singleton_method, :repo_name) { repo_name.to_s }
51
- repo_class.document_type = (kwargs[:document_type] || repo_name).to_s
52
51
 
53
52
  plugins.each do |mod|
54
53
  next unless mod.const_defined?(:RepositoryClassMethods, false)
data/lib/esse/index.rb CHANGED
@@ -17,10 +17,11 @@ module Esse
17
17
  require_relative 'index/settings'
18
18
  require_relative 'index/mappings'
19
19
  require_relative 'index/descendants'
20
- require_relative 'index/backend'
21
20
  require_relative 'index/object_document_mapper'
21
+ # Methods that use the cluster API
22
+ require_relative 'index/aliases'
23
+ require_relative 'index/indices'
22
24
  require_relative 'index/search'
23
-
24
- def_Index(::Esse)
25
+ require_relative 'index/documents'
25
26
  end
26
27
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Esse
4
- class NullDocument < Esse::Serializer
4
+ class NullDocument < Esse::Document
5
5
  def initialize
6
6
  @object = nil
7
7
  @options = {}
@@ -6,6 +6,17 @@ module Esse
6
6
  module HashUtils
7
7
  module_function
8
8
 
9
+ def deep_dup(hash)
10
+ hash.each_with_object({}) do |(key, value), result|
11
+ result[key] = \
12
+ if value.is_a?(Hash)
13
+ deep_dup(value)
14
+ else
15
+ value
16
+ end
17
+ end
18
+ end
19
+
9
20
  def deep_transform_keys(hash, &block)
10
21
  hash.each_with_object({}) do |(key, value), result|
11
22
  result[yield(key)] = \
@@ -3,10 +3,9 @@
3
3
  module Esse
4
4
  class Repository
5
5
  module ClassMethods
6
- def elasticsearch
7
- Esse::Backend::RepositoryBackend.new(self)
6
+ def import(**kwargs)
7
+ index.import(repo_name, **kwargs)
8
8
  end
9
- alias_method :backend, :elasticsearch
10
9
  end
11
10
 
12
11
  extend ClassMethods
@@ -9,63 +9,63 @@ module Esse
9
9
  # Convert ruby object to json. Arguments will be same of passed through the
10
10
  # collection. It's allowed a block or a class with the `to_h` instance method.
11
11
  # Example with block
12
- # serializer do |model, **context|
12
+ # document do |model, **context|
13
13
  # {
14
14
  # id: model.id,
15
15
  # admin: context[:is_admin],
16
16
  # }
17
17
  # end
18
- # Example with serializer class
19
- # serializer UserSerializer
20
- def serializer(klass = nil, &block)
21
- if @serializer_proc
22
- raise ArgumentError, format('Serializer for %p already defined', repo_name)
18
+ # Example with document class
19
+ # document UserDocument
20
+ def document(klass = nil, &block)
21
+ if @document_proc
22
+ raise ArgumentError, format('Document for %p already defined', repo_name)
23
23
  end
24
24
 
25
25
  if block
26
- @serializer_proc = ->(model, **kwargs) { coerce_to_document(block.call(model, **kwargs)) }
27
- elsif klass.is_a?(Class) && klass <= Esse::Serializer
28
- @serializer_proc = ->(model, **kwargs) { klass.new(model, **kwargs) }
26
+ @document_proc = ->(model, **kwargs) { coerce_to_document(block.call(model, **kwargs)) }
27
+ elsif klass.is_a?(Class) && klass <= Esse::Document
28
+ @document_proc = ->(model, **kwargs) { klass.new(model, **kwargs) }
29
29
  elsif klass.is_a?(Class) && klass.instance_methods.include?(:to_h)
30
- @serializer_proc = ->(model, **kwargs) { coerce_to_document(klass.new(model, **kwargs).to_h) }
30
+ @document_proc = ->(model, **kwargs) { coerce_to_document(klass.new(model, **kwargs).to_h) }
31
31
  elsif klass.is_a?(Class) && klass.instance_methods.include?(:as_json) # backward compatibility
32
- @serializer_proc = ->(model, **kwargs) { coerce_to_document(klass.new(model, **kwargs).as_json) }
32
+ @document_proc = ->(model, **kwargs) { coerce_to_document(klass.new(model, **kwargs).as_json) }
33
33
  elsif klass.is_a?(Class) && klass.instance_methods.include?(:call)
34
- @serializer_proc = ->(model, **kwargs) { coerce_to_document(klass.new(model, **kwargs).call) }
34
+ @document_proc = ->(model, **kwargs) { coerce_to_document(klass.new(model, **kwargs).call) }
35
35
  else
36
- msg = format("%<arg>p is not a valid serializer. The serializer should inherit from Esse::Serializer or respond to `to_h'", arg: klass)
36
+ msg = format("%<arg>p is not a valid document. The document should inherit from Esse::Document or respond to `to_h'", arg: klass)
37
37
  raise ArgumentError, msg
38
38
  end
39
39
  end
40
40
 
41
41
  def coerce_to_document(value)
42
42
  case value
43
- when Esse::Serializer
43
+ when Esse::Document
44
44
  value
45
45
  when Hash
46
46
  Esse::HashDocument.new(value)
47
47
  when NilClass, FalseClass
48
48
  Esse::NullDocument.new
49
49
  else
50
- raise ArgumentError, format('%<arg>p is not a valid document. The document should be a hash or an instance of Esse::Serializer', arg: value)
50
+ raise ArgumentError, format('%<arg>p is not a valid document. The document should be a hash or an instance of Esse::Document', arg: value)
51
51
  end
52
52
  end
53
53
 
54
- # Convert ruby object to json by using the serializer of the given document type.
54
+ # Convert ruby object to json by using the document of the given document type.
55
55
  # @param [Object] model The ruby object
56
56
  # @param [Hash] kwargs The context
57
57
  # @return [Esse::Document] The serialized document
58
58
  def serialize(model, **kwargs)
59
- if @serializer_proc.nil?
60
- raise NotImplementedError, format('there is no %<t>p serializer defined for the %<k>p index', t: repo_name, k: index.to_s)
59
+ if @document_proc.nil?
60
+ raise NotImplementedError, format('there is no %<t>p document defined for the %<k>p index', t: repo_name, k: index.to_s)
61
61
  end
62
62
 
63
- @serializer_proc.call(model, **kwargs)
63
+ @document_proc.call(model, **kwargs)
64
64
  end
65
65
 
66
66
  # Used to define the source of data. A block is required. And its
67
67
  # content should yield an array of each object that should be serialized.
68
- # The list of arguments will be passed throught the serializer method.
68
+ # The list of arguments will be passed throught the document method.
69
69
  #
70
70
  # Example:
71
71
  # collection AdminStore
@@ -9,10 +9,9 @@ module Esse
9
9
  # This methods will be defined using meta programming in the index respository definition
10
10
  # @see Esse::Index::Type.repository
11
11
  attr_reader :index
12
- attr_accessor :document_type
13
12
  end
14
13
  require_relative 'repository/actions'
15
- require_relative 'repository/backend'
14
+ require_relative 'repository/documents'
16
15
  require_relative 'repository/object_document_mapper'
17
16
  end
18
17
  end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Esse
4
+ module Search
5
+ class Query
6
+ module DSL
7
+ def limit(value)
8
+ return self if value.to_i <= 0
9
+
10
+ mutate do |defn|
11
+ defn.delete(:size)
12
+ if (body = defn[:body]).is_a?(Hash)
13
+ body[body.key?('size') ? 'size' : :size] = value.to_i
14
+ else
15
+ defn.update(size: value.to_i)
16
+ end
17
+ end
18
+ end
19
+
20
+ def offset(value)
21
+ return self if value.to_i < 0
22
+
23
+ mutate do |defn|
24
+ defn.delete(:from)
25
+ if (body = defn[:body]).is_a?(Hash)
26
+ body[body.key?('from') ? 'from' : :from] = value.to_i
27
+ else
28
+ defn.update(from: value.to_i)
29
+ end
30
+ end
31
+ end
32
+
33
+ def limit_value
34
+ raw_limit_value || 10
35
+ end
36
+
37
+ def offset_value
38
+ raw_offset_value || 0
39
+ end
40
+
41
+ private
42
+
43
+ def mutate(&block)
44
+ relation = clone
45
+ relation.send(:reset!)
46
+ relation.instance_variable_set(:@definition, HashUtils.deep_dup(definition))
47
+ relation.instance_exec(relation.definition, &block) if block
48
+ relation
49
+ end
50
+
51
+ def raw_limit_value
52
+ definition.dig(:body, :size) || definition.dig(:body, 'size') || definition.dig(:size) || definition.dig('size')
53
+ end
54
+
55
+ def raw_offset_value
56
+ definition.dig(:body, :from) || definition.dig(:body, 'from') || definition.dig(:from) || definition.dig('from')
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -1,17 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'query/dsl'
3
4
  module Esse
4
5
  module Search
5
6
  class Query
6
- attr_reader :client_proxy, :definition
7
+ include DSL
8
+ attr_reader :transport, :definition
7
9
 
8
- # @param client_proxy [Esse::ClientProxy] The client proxy to use for the query
10
+ # @param transport [Esse::Transport] The client proxy to use for the query
9
11
  # @param indices [<Array<Esse::Index, String>] The class of the index to search or the index name
10
12
  # @param definition [Hash] The options to pass to the search.
11
- def initialize(client_proxy, *indices, suffix: nil, **definition, &_block)
12
- @client_proxy = client_proxy
13
+ def initialize(transport, *indices, suffix: nil, **definition, &_block)
14
+ @transport = transport
13
15
  @definition = definition
14
- @definition[:index] = indices.map do |index|
16
+ @definition[:index] = self.class.normalize_indices(*indices, suffix: suffix) if indices.size > 0
17
+ end
18
+
19
+ def self.normalize_indices(*indices, suffix: nil)
20
+ indices.map do |index|
15
21
  if index.is_a?(Class) && index < Esse::Index
16
22
  index.index_name(suffix: suffix)
17
23
  elsif index.is_a?(String) || index.is_a?(Symbol)
@@ -48,8 +54,8 @@ module Esse
48
54
  end
49
55
  ensure
50
56
  begin
51
- client_proxy.clear_scroll(body: {scroll_id: scroll_id}) if scroll_id
52
- rescue Esse::Backend::NotFoundError
57
+ transport.clear_scroll(body: {scroll_id: scroll_id}) if scroll_id
58
+ rescue Esse::Transport::NotFoundError
53
59
  end
54
60
  end
55
61
 
@@ -60,7 +66,7 @@ module Esse
60
66
  Esse::Events.instrument('elasticsearch.execute_search_query') do |payload|
61
67
  payload[:query] = self
62
68
  begin
63
- resp = Response.new(self, client_proxy.search(**definition, **execution_options))
69
+ resp = Response.new(self, transport.search(**definition, **execution_options))
64
70
  rescue => e
65
71
  err = e
66
72
  end
@@ -77,7 +83,7 @@ module Esse
77
83
  Esse::Events.instrument('elasticsearch.execute_search_query') do |payload|
78
84
  payload[:query] = self
79
85
  begin
80
- resp = Response.new(self, client_proxy.scroll(scroll: scroll, body: { scroll_id: scroll_id }))
86
+ resp = Response.new(self, transport.scroll(scroll: scroll, body: { scroll_id: scroll_id }))
81
87
  rescue => e
82
88
  err = e
83
89
  end
@@ -92,14 +98,6 @@ module Esse
92
98
  def reset!
93
99
  @response = nil
94
100
  end
95
-
96
- def raw_limit_value
97
- definition.dig(:body, :size) || definition.dig(:body, 'size') || definition.dig(:size) || definition.dig('size')
98
- end
99
-
100
- def raw_offset_value
101
- definition.dig(:body, :from) || definition.dig(:body, 'from') || definition.dig(:from) || definition.dig('from')
102
- end
103
101
  end
104
102
  end
105
103
  end
@@ -24,7 +24,7 @@ module Esse
24
24
  path = nil
25
25
  @directories.each do |dir|
26
26
  patterns.find do |pattern|
27
- path = Dir[dir.join("#{pattern}.{#{@extensions.join(",")}}")].first
27
+ path = Dir[dir.join("#{pattern}.{#{@extensions.join(',')}}")].first
28
28
  break if path
29
29
  end
30
30
  break if path
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Esse
4
+ class Transport
5
+ module InstanceMethods
6
+ # Return a list of index aliases.
7
+ #
8
+ # @param options [Hash] Hash of paramenters that will be passed along to elasticsearch request
9
+ # @option [String] :index A comma-separated list of index names to filter aliases
10
+ # @option [String] :name A comma-separated list of alias names to return
11
+ # @raise [Esse::Transport::ServerError] in case of failure
12
+ #
13
+ # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.5/indices-get-alias.html
14
+ def aliases(**options)
15
+ coerce_exception { client.indices.get_alias(**options) }
16
+ end
17
+
18
+ # Updates index aliases.
19
+ #
20
+ # @param options [Hash] Hash of paramenters that will be passed along to elasticsearch request
21
+ # @option [Hash] :body The definition of `actions` to perform
22
+ #
23
+ # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html
24
+ def update_aliases(body:, **options)
25
+ throw_error_when_readonly!
26
+
27
+ Esse::Events.instrument('elasticsearch.update_aliases') do |payload|
28
+ payload[:request] = options
29
+ payload[:response] = coerce_exception { client.indices.update_aliases(**options, body: body) }
30
+ end
31
+ end
32
+ end
33
+
34
+ include InstanceMethods
35
+ end
36
+ end
@@ -0,0 +1,199 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Esse
4
+ class Transport
5
+ module InstanceMethods
6
+ # Returns a document.
7
+ #
8
+ # @option [String] :id The document ID
9
+ # @option [String] :index The name of the index
10
+ # @option [Boolean] :force_synthetic_source Should this request force synthetic _source? Use this to test if the mapping supports synthetic _source and to get a sense of the worst case performance. Fetches with this enabled will be slower the enabling synthetic source natively in the index.
11
+ # @option [List] :stored_fields A comma-separated list of stored fields to return in the response
12
+ # @option [String] :preference Specify the node or shard the operation should be performed on (default: random)
13
+ # @option [Boolean] :realtime Specify whether to perform the operation in realtime or search mode
14
+ # @option [Boolean] :refresh Refresh the shard containing the document before performing the operation
15
+ # @option [String] :routing Specific routing value
16
+ # @option [List] :_source True or false to return the _source field or not, or a list of fields to return
17
+ # @option [List] :_source_excludes A list of fields to exclude from the returned _source field
18
+ # @option [List] :_source_includes A list of fields to extract and return from the _source field
19
+ # @option [Number] :version Explicit version number for concurrency control
20
+ # @option [String] :version_type Specific version type (options: internal, external, external_gte)
21
+ # @option [Hash] :headers Custom HTTP headers
22
+ #
23
+ # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-get.html
24
+ #
25
+ def get(id:, index:, **options)
26
+ Esse::Events.instrument('elasticsearch.get') do |payload|
27
+ payload[:request] = opts = options.merge(id: id, index: index)
28
+ payload[:response] = coerce_exception { client.get(**opts) }
29
+ end
30
+ end
31
+
32
+ # Returns information about whether a document exists in an index.
33
+ #
34
+ # @option [String] :id The document ID
35
+ # @option [String] :index The name of the index
36
+ # @option [List] :stored_fields A comma-separated list of stored fields to return in the response
37
+ # @option [String] :preference Specify the node or shard the operation should be performed on (default: random)
38
+ # @option [Boolean] :realtime Specify whether to perform the operation in realtime or search mode
39
+ # @option [Boolean] :refresh Refresh the shard containing the document before performing the operation
40
+ # @option [String] :routing Specific routing value
41
+ # @option [List] :_source True or false to return the _source field or not, or a list of fields to return
42
+ # @option [List] :_source_excludes A list of fields to exclude from the returned _source field
43
+ # @option [List] :_source_includes A list of fields to extract and return from the _source field
44
+ # @option [Number] :version Explicit version number for concurrency control
45
+ # @option [String] :version_type Specific version type (options: internal, external, external_gte)
46
+ # @option [Hash] :headers Custom HTTP headers
47
+ #
48
+ # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-get.html
49
+ #
50
+ def exist?(id:, index:, **options)
51
+ Esse::Events.instrument('elasticsearch.exist') do |payload|
52
+ payload[:request] = opts = options.merge(id: id, index: index)
53
+ payload[:response] = coerce_exception { client.exists(**opts) }
54
+ end
55
+ end
56
+
57
+ # Returns number of documents matching a query.
58
+ #
59
+ # @option [List] :index A comma-separated list of indices to restrict the results
60
+ # @option [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when unavailable (missing or closed)
61
+ # @option [Boolean] :ignore_throttled Whether specified concrete, expanded or aliased indices should be ignored when throttled
62
+ # @option [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified)
63
+ # @option [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all)
64
+ # @option [Number] :min_score Include only documents with a specific `_score` value in the result
65
+ # @option [String] :preference Specify the node or shard the operation should be performed on (default: random)
66
+ # @option [List] :routing A comma-separated list of specific routing values
67
+ # @option [String] :q Query in the Lucene query string syntax
68
+ # @option [String] :analyzer The analyzer to use for the query string
69
+ # @option [Boolean] :analyze_wildcard Specify whether wildcard and prefix queries should be analyzed (default: false)
70
+ # @option [String] :default_operator The default operator for query string query (AND or OR) (options: AND, OR)
71
+ # @option [String] :df The field to use as default where no field prefix is given in the query string
72
+ # @option [Boolean] :lenient Specify whether format-based query failures (such as providing text to a numeric field) should be ignored
73
+ # @option [Number] :terminate_after The maximum count for each shard, upon reaching which the query execution will terminate early
74
+ # @option [Hash] :headers Custom HTTP headers
75
+ # @option [Hash] :body A query to restrict the results specified with the Query DSL (optional)
76
+ #
77
+ # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-count.html
78
+ def count(index:, **options)
79
+ Esse::Events.instrument('elasticsearch.count') do |payload|
80
+ payload[:request] = opts = options.merge(index: index)
81
+ payload[:response] = coerce_exception { client.count(**opts) }
82
+ end
83
+ end
84
+
85
+ # Removes a document from the index.
86
+ #
87
+ # @option arguments [String] :id The document ID
88
+ # @option arguments [String] :index The name of the index
89
+ # @option arguments [String] :wait_for_active_shards Sets the number of shard copies that must be active before proceeding with the delete operation. Defaults to 1, meaning the primary shard only. Set to `all` for all shard copies, otherwise set to any non-negative value less than or equal to the total number of copies for the shard (number of replicas + 1)
90
+ # @option arguments [String] :refresh If `true` then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` (the default) then do nothing with refreshes. (options: true, false, wait_for)
91
+ # @option arguments [String] :routing Specific routing value
92
+ # @option arguments [Time] :timeout Explicit operation timeout
93
+ # @option arguments [Number] :if_seq_no only perform the delete operation if the last operation that has changed the document has the specified sequence number
94
+ # @option arguments [Number] :if_primary_term only perform the delete operation if the last operation that has changed the document has the specified primary term
95
+ # @option arguments [Number] :version Explicit version number for concurrency control
96
+ # @option arguments [String] :version_type Specific version type (options: internal, external, external_gte)
97
+ # @option arguments [Hash] :headers Custom HTTP headers
98
+ #
99
+ # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-delete.html
100
+ def delete(id:, index:, **options)
101
+ throw_error_when_readonly!
102
+
103
+ Esse::Events.instrument('elasticsearch.delete') do |payload|
104
+ payload[:request] = opts = options.merge(id: id, index: index)
105
+ payload[:response] = coerce_exception { client.delete(**opts) }
106
+ end
107
+ end
108
+
109
+ # Updates a document with a script or partial document.
110
+ #
111
+ # @option [String] :id Document ID
112
+ # @option [String] :index The name of the index
113
+ # @option [String] :wait_for_active_shards Sets the number of shard copies that must be active before proceeding with the update operation. Defaults to 1, meaning the primary shard only. Set to `all` for all shard copies, otherwise set to any non-negative value less than or equal to the total number of copies for the shard (number of replicas + 1)
114
+ # @option [List] :_source True or false to return the _source field or not, or a list of fields to return
115
+ # @option [List] :_source_excludes A list of fields to exclude from the returned _source field
116
+ # @option [List] :_source_includes A list of fields to extract and return from the _source field
117
+ # @option [String] :lang The script language (default: painless)
118
+ # @option [String] :refresh If `true` then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` (the default) then do nothing with refreshes. (options: true, false, wait_for)
119
+ # @option [Number] :retry_on_conflict Specify how many times should the operation be retried when a conflict occurs (default: 0)
120
+ # @option [String] :routing Specific routing value
121
+ # @option [Time] :timeout Explicit operation timeout
122
+ # @option [Number] :if_seq_no only perform the update operation if the last operation that has changed the document has the specified sequence number
123
+ # @option [Number] :if_primary_term only perform the update operation if the last operation that has changed the document has the specified primary term
124
+ # @option [Boolean] :require_alias When true, requires destination is an alias. Default is false
125
+ # @option [Hash] :headers Custom HTTP headers
126
+ # @option [Hash] :body The request definition requires either `script` or partial `doc` (*Required*)
127
+ #
128
+ # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html
129
+ #
130
+ def update(id:, index:, body:, **options)
131
+ throw_error_when_readonly!
132
+
133
+ Esse::Events.instrument('elasticsearch.update') do |payload|
134
+ payload[:request] = opts = options.merge(id: id, index: index, body: body)
135
+ payload[:response] = coerce_exception { client.update(**opts) }
136
+ end
137
+ end
138
+
139
+ # Creates or updates a document in an index.
140
+ #
141
+ # @option [String] :id Document ID
142
+ # @option [String] :index The name of the index
143
+ # @option [String] :wait_for_active_shards Sets the number of shard copies that must be active before proceeding with the index operation. Defaults to 1, meaning the primary shard only. Set to `all` for all shard copies, otherwise set to any non-negative value less than or equal to the total number of copies for the shard (number of replicas + 1)
144
+ # @option [String] :op_type Explicit operation type. Defaults to `index` for requests with an explicit document ID, and to `create`for requests without an explicit document ID (options: index, create)
145
+ # @option [String] :refresh If `true` then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` (the default) then do nothing with refreshes. (options: true, false, wait_for)
146
+ # @option [String] :routing Specific routing value
147
+ # @option [Time] :timeout Explicit operation timeout
148
+ # @option [Number] :version Explicit version number for concurrency control
149
+ # @option [String] :version_type Specific version type (options: internal, external, external_gte)
150
+ # @option [Number] :if_seq_no only perform the index operation if the last operation that has changed the document has the specified sequence number
151
+ # @option [Number] :if_primary_term only perform the index operation if the last operation that has changed the document has the specified primary term
152
+ # @option [String] :pipeline The pipeline id to preprocess incoming documents with
153
+ # @option [Boolean] :require_alias When true, requires destination to be an alias. Default is false
154
+ # @option [Hash] :headers Custom HTTP headers
155
+ # @option [Hash] :body The document (*Required*)
156
+ #
157
+ # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-index_.html
158
+ def index(id:, index:, body:, **options)
159
+ throw_error_when_readonly!
160
+
161
+ Esse::Events.instrument('elasticsearch.index') do |payload|
162
+ payload[:request] = opts = options.merge(id: id, index: index, body: body)
163
+ payload[:response] = coerce_exception { client.index(**opts) }
164
+ end
165
+ end
166
+
167
+ # Allows to perform multiple index/update/delete operations in a single request.
168
+ #
169
+ # @option arguments [String] :index Default index for items which don't provide one
170
+ # @option arguments [String] :wait_for_active_shards Sets the number of shard copies that must be active before proceeding with the bulk operation. Defaults to 1, meaning the primary shard only. Set to `all` for all shard copies, otherwise set to any non-negative value less than or equal to the total number of copies for the shard (number of replicas + 1)
171
+ # @option arguments [String] :refresh If `true` then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` (the default) then do nothing with refreshes. (options: true, false, wait_for)
172
+ # @option arguments [String] :routing Specific routing value
173
+ # @option arguments [Time] :timeout Explicit operation timeout
174
+ # @option arguments [String] :type Default document type for items which don't provide one
175
+ # @option arguments [List] :_source True or false to return the _source field or not, or default list of fields to return, can be overridden on each sub-request
176
+ # @option arguments [List] :_source_excludes Default list of fields to exclude from the returned _source field, can be overridden on each sub-request
177
+ # @option arguments [List] :_source_includes Default list of fields to extract and return from the _source field, can be overridden on each sub-request
178
+ # @option arguments [String] :pipeline The pipeline id to preprocess incoming documents with
179
+ # @option arguments [Boolean] :require_alias Sets require_alias for all incoming documents. Defaults to unset (false)
180
+ # @option arguments [Hash] :headers Custom HTTP headers
181
+ # @option arguments [String|Array] :body The operation definition and data (action-data pairs), separated by newlines. Array of Strings, Header/Data pairs,
182
+ # or the conveniency "combined" format can be passed, refer to Elasticsearch::API::Utils.__bulkify documentation.
183
+ #
184
+ # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html
185
+ def bulk(body:, **options)
186
+ throw_error_when_readonly!
187
+
188
+ Esse::Events.instrument('elasticsearch.bulk') do |payload|
189
+ payload[:request] = opts = options.merge(body: body)
190
+ payload[:response] = response = coerce_exception { client.bulk(**opts) }
191
+ yield(payload) if block_given? # Allow caller to add data to the payload of event
192
+ response
193
+ end
194
+ end
195
+ end
196
+
197
+ include InstanceMethods
198
+ end
199
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Esse
4
+ class Transport
5
+ module InstanceMethods
6
+ # Returns basic information about the health of the cluster.
7
+ #
8
+ # @option [List] :index Limit the information returned to a specific index
9
+ # @option [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are open, closed or both. (options: open, closed, hidden, none, all)
10
+ # @option [String] :level Specify the level of detail for returned information (options: cluster, indices, shards)
11
+ # @option [Boolean] :local Return local information, do not retrieve the state from master node (default: false)
12
+ # @option [Time] :master_timeout Explicit operation timeout for connection to master node
13
+ # @option [Time] :timeout Explicit operation timeout
14
+ # @option [String] :wait_for_active_shards Wait until the specified number of shards is active
15
+ # @option [String] :wait_for_nodes Wait until the specified number of nodes is available
16
+ # @option [String] :wait_for_events Wait until all currently queued events with the given priority are processed (options: immediate, urgent, high, normal, low, languid)
17
+ # @option [Boolean] :wait_for_no_relocating_shards Whether to wait until there are no relocating shards in the cluster
18
+ # @option [Boolean] :wait_for_no_initializing_shards Whether to wait until there are no initializing shards in the cluster
19
+ # @option [String] :wait_for_status Wait until cluster is in a specific state (options: green, yellow, red)
20
+ # @option [Hash] :headers Custom HTTP headers
21
+ #
22
+ # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-health.html
23
+ def health(**options)
24
+ coerce_exception { client.cluster.health(**options) }
25
+ end
26
+ end
27
+
28
+ include InstanceMethods
29
+ end
30
+ end