elastic-rails 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/lib/elastic/commands/build_agg_from_params.rb +37 -20
  3. data/lib/elastic/commands/build_query_from_params.rb +109 -79
  4. data/lib/elastic/commands/build_sort_from_params.rb +41 -0
  5. data/lib/elastic/commands/import_index_documents.rb +1 -1
  6. data/lib/elastic/configuration.rb +14 -11
  7. data/lib/elastic/core/adaptor.rb +0 -1
  8. data/lib/elastic/core/base_middleware.rb +2 -2
  9. data/lib/elastic/core/default_middleware.rb +1 -1
  10. data/lib/elastic/core/definition.rb +53 -34
  11. data/lib/elastic/core/query_assembler.rb +51 -19
  12. data/lib/elastic/core/query_config.rb +4 -5
  13. data/lib/elastic/core/source_formatter.rb +12 -31
  14. data/lib/elastic/datatypes/date.rb +32 -0
  15. data/lib/elastic/datatypes/default.rb +74 -0
  16. data/lib/elastic/datatypes/string.rb +7 -0
  17. data/lib/elastic/datatypes/term.rb +10 -0
  18. data/lib/elastic/datatypes/time.rb +29 -0
  19. data/lib/elastic/dsl/bool_query_builder.rb +4 -0
  20. data/lib/elastic/fields/nested.rb +24 -6
  21. data/lib/elastic/fields/value.rb +69 -25
  22. data/lib/elastic/nested_query.rb +34 -0
  23. data/lib/elastic/nested_type.rb +10 -0
  24. data/lib/elastic/nodes/agg/average.rb +3 -1
  25. data/lib/elastic/nodes/agg/base_metric.rb +6 -5
  26. data/lib/elastic/nodes/agg/date_histogram.rb +4 -4
  27. data/lib/elastic/nodes/agg/maximum.rb +3 -1
  28. data/lib/elastic/nodes/agg/minimum.rb +3 -1
  29. data/lib/elastic/nodes/agg/stats.rb +3 -1
  30. data/lib/elastic/nodes/agg/sum.rb +3 -1
  31. data/lib/elastic/nodes/agg/terms.rb +4 -4
  32. data/lib/elastic/nodes/agg/top_hits.rb +6 -6
  33. data/lib/elastic/nodes/and.rb +2 -2
  34. data/lib/elastic/nodes/base.rb +5 -3
  35. data/lib/elastic/nodes/base_agg.rb +2 -2
  36. data/lib/elastic/nodes/boolean.rb +34 -14
  37. data/lib/elastic/nodes/concerns/aggregable.rb +12 -8
  38. data/lib/elastic/nodes/concerns/bucketed.rb +4 -7
  39. data/lib/elastic/nodes/concerns/field_query.rb +10 -0
  40. data/lib/elastic/nodes/concerns/hit_provider.rb +11 -0
  41. data/lib/elastic/nodes/function_score.rb +8 -7
  42. data/lib/elastic/nodes/match.rb +6 -5
  43. data/lib/elastic/nodes/nested.rb +28 -7
  44. data/lib/elastic/nodes/range.rb +9 -8
  45. data/lib/elastic/nodes/search.rb +11 -10
  46. data/lib/elastic/nodes/sort.rb +82 -0
  47. data/lib/elastic/nodes/term.rb +7 -6
  48. data/lib/elastic/query.rb +24 -12
  49. data/lib/elastic/railtie.rb +7 -0
  50. data/lib/elastic/railties/ar_helpers.rb +2 -1
  51. data/lib/elastic/railties/configuration_extensions.rb +13 -0
  52. data/lib/elastic/railties/indexable_record.rb +1 -2
  53. data/lib/elastic/railties/indexing_job.rb +8 -0
  54. data/lib/elastic/railties/type_extensions.rb +1 -1
  55. data/lib/elastic/results/aggregations.rb +1 -1
  56. data/lib/elastic/results/bucket.rb +3 -2
  57. data/lib/elastic/results/grouped_result.rb +31 -1
  58. data/lib/elastic/results/hit.rb +8 -20
  59. data/lib/elastic/results/hit_collection.rb +2 -33
  60. data/lib/elastic/results/root.rb +3 -2
  61. data/lib/elastic/results/scored_collection.rb +44 -0
  62. data/lib/elastic/results/scored_item.rb +10 -0
  63. data/lib/elastic/shims/base.rb +6 -4
  64. data/lib/elastic/shims/concerns/hit_picker.rb +41 -0
  65. data/lib/elastic/shims/field_picking.rb +20 -0
  66. data/lib/elastic/shims/grouping.rb +17 -8
  67. data/lib/elastic/shims/id_picking.rb +15 -0
  68. data/lib/elastic/shims/populating.rb +4 -11
  69. data/lib/elastic/shims/reducing.rb +3 -7
  70. data/lib/elastic/shims/total_picking.rb +16 -0
  71. data/lib/elastic/type.rb +6 -3
  72. data/lib/elastic/types/base_type.rb +16 -9
  73. data/lib/elastic/types/faceted_type.rb +1 -1
  74. data/lib/elastic/types/nestable_type.rb +2 -2
  75. data/lib/elastic/version.rb +1 -1
  76. data/lib/elastic.rb +15 -0
  77. data/lib/generators/elastic/index_generator.rb +1 -1
  78. data/lib/generators/elastic/init_generator.rb +10 -0
  79. data/lib/generators/elastic/templates/elastic.yml +14 -0
  80. data/lib/generators/elastic/templates/index.rb +0 -1
  81. metadata +21 -2
@@ -6,33 +6,27 @@ module Elastic::Core
6
6
  end
7
7
 
8
8
  def assemble
9
- query = build_base_query
9
+ populated_query build_hit_query
10
+ end
10
11
 
11
- if !grouped?
12
- query.size = (@config.limit || Elastic::Configuration.page_size)
13
- query.offset = @config.offset
14
- else
15
- query.size = 0
16
- last = attach_groups query
17
- last.aggregate(Elastic::Nodes::TopHits.build('default'))
12
+ def assemble_total
13
+ query = build_base_query
14
+ query.size = 0
18
15
 
16
+ if grouped?
17
+ attach_groups(query)
19
18
  query = grouped_query query
20
- query = reduced_query query
21
19
  end
22
20
 
23
- populated_query query
21
+ pick_query_totals query
24
22
  end
25
23
 
26
24
  def assemble_ids
27
- raise NotImplementedError, 'ids retrieval not yet implemented'
28
- end
29
-
30
- def assemble_total
31
- raise NotImplementedError, 'total not yet implemented'
25
+ pick_query_ids build_hit_query
32
26
  end
33
27
 
34
- def assemble_pluck(_field)
35
- raise NotImplementedError, 'pluck not yet implemented'
28
+ def assemble_pick(_field)
29
+ pick_query_fields build_hit_query, _field
36
30
  end
37
31
 
38
32
  def assemble_metric(_node)
@@ -45,7 +39,7 @@ module Elastic::Core
45
39
  query.size = 0
46
40
 
47
41
  last = attach_groups(query)
48
- last.aggs = _aggs
42
+ last.aggregations = _aggs
49
43
 
50
44
  query = grouped_query(query) if grouped?
51
45
  query
@@ -54,7 +48,33 @@ module Elastic::Core
54
48
  private
55
49
 
56
50
  def build_base_query
57
- @config.root.simplify
51
+ Elastic::Nodes::Search.build @config.query.simplify
52
+ end
53
+
54
+ def build_hit_query
55
+ query = build_base_query
56
+
57
+ if !grouped?
58
+ query.size = (@config.limit || Elastic::Configuration.page_size)
59
+ query.offset = @config.offset
60
+ query = sort_node(query)
61
+ else
62
+ query.size = 0
63
+ last = attach_groups query
64
+ last.aggregate sort_node Elastic::Nodes::TopHits.build('default')
65
+
66
+ query = grouped_query query
67
+ query = reduced_query query
68
+ end
69
+
70
+ query
71
+ end
72
+
73
+ def sort_node(_node)
74
+ return _node unless @config.sort
75
+ sort_node = @config.sort.clone
76
+ sort_node.child = _node
77
+ sort_node
58
78
  end
59
79
 
60
80
  def grouped?
@@ -80,5 +100,17 @@ module Elastic::Core
80
100
  def populated_query(_query)
81
101
  Elastic::Shims::Populating.new(@index, @config, _query)
82
102
  end
103
+
104
+ def pick_query_ids(_query)
105
+ Elastic::Shims::IdPicking.new(_query)
106
+ end
107
+
108
+ def pick_query_fields(_query, _field)
109
+ Elastic::Shims::FieldPicking.new(_query, _field.to_s)
110
+ end
111
+
112
+ def pick_query_totals(_query)
113
+ Elastic::Shims::TotalPicking.new(_query)
114
+ end
83
115
  end
84
116
  end
@@ -1,12 +1,10 @@
1
1
  module Elastic::Core
2
2
  class QueryConfig
3
- attr_accessor :root, :groups, :limit, :offset, :middleware_options
3
+ attr_accessor :query, :groups, :limit, :offset, :sort, :middleware_options
4
4
 
5
5
  def self.initial_config
6
6
  new.tap do |config|
7
- config.root = Elastic::Nodes::Search.new
8
- config.root.query = Elastic::Nodes::Boolean.new
9
- config.root.query.disable_coord = true unless Elastic::Configuration.coord_similarity
7
+ config.query = Elastic::Nodes::Boolean.new
10
8
  config.groups = []
11
9
  config.middleware_options = HashWithIndifferentAccess.new
12
10
  end
@@ -14,10 +12,11 @@ module Elastic::Core
14
12
 
15
13
  def clone
16
14
  self.class.new.tap do |clone|
17
- clone.root = @root.clone
15
+ clone.query = @query.clone
18
16
  clone.groups = @groups.dup
19
17
  clone.limit = @limit
20
18
  clone.offset = @offset
19
+ clone.sort = @sort.try(:clone)
21
20
  clone.middleware_options = @middleware_options.dup
22
21
  end
23
22
  end
@@ -1,40 +1,21 @@
1
1
  module Elastic::Core
2
2
  class SourceFormatter
3
- def initialize(_mapping)
4
- @mapping = _mapping
5
- @treatment_cache = {}
3
+ def initialize(_definition)
4
+ @definition = _definition
6
5
  end
7
6
 
8
- def format(_source, _prefix = nil)
9
- _source.each do |field, value|
10
- field_name = _prefix ? "#{_prefix}.#{field}" : field
11
-
12
- treatment = treatment_for field_name
13
- if treatment == :nested
14
- value.each { |v| format(v, field_name) }
15
- else
16
- _source[field] = send(treatment, value) unless treatment == :none
17
- end
18
- end
19
- end
20
-
21
- private
22
-
23
- def treatment_for(_field)
24
- treatment = @treatment_cache[_field]
25
- treatment = @treatment_cache[_field] = get_treatment(_field) if treatment.nil?
26
- treatment
27
- end
28
-
29
- def get_treatment(_field)
30
- field_options = @mapping.get_field_options(_field) || {}
31
- return :nested if field_options['type'] == 'nested'
32
- return :parse_date if field_options['type'] == 'date'
33
- :none
7
+ def format_field(_field, _value)
8
+ field = @definition.get_field _field
9
+ return _value if field.nil?
10
+ field.prepare_value_for_result _value
34
11
  end
35
12
 
36
- def parse_date(_value)
37
- Time.parse _value
13
+ def format(_source)
14
+ _source.each do |key, value|
15
+ field = @definition.get_field key
16
+ next if field.nil?
17
+ _source[key] = field.prepare_value_for_result(value)
18
+ end
38
19
  end
39
20
  end
40
21
  end
@@ -0,0 +1,32 @@
1
+ module Elastic::Datatypes
2
+ class Date < Default
3
+ def prepare_for_index(_value)
4
+ if !_value.nil? && !_value.is_a?(::Date)
5
+ raise ArgumentError, "expected a date for field #{name}"
6
+ end
7
+
8
+ # date is stored as the corresponding utc timestamp in elastic search,
9
+ # no need to convert it here
10
+ _value
11
+ end
12
+
13
+ def prepare_value_for_result(_value)
14
+ case _value
15
+ when ::String
16
+ ::Time.parse(_value).utc.to_date
17
+ when ::Integer
18
+ ::Time.at(_value / 1000).utc.to_date
19
+ else
20
+ _value
21
+ end
22
+ end
23
+
24
+ def supported_aggregations
25
+ [:date_histogram] + super
26
+ end
27
+
28
+ def date_histogram_aggregation_defaults
29
+ { interval: '1w' }
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,74 @@
1
+ module Elastic::Datatypes
2
+ class Default
3
+ MAPPING_OPTIONS = [
4
+ :type, :analyzer, :boost, :coerce, :copy_to, :doc_values, :dynamic,
5
+ :enabled, :fielddata, :geohash, :geohash_precision, :geohash_prefix, :format, :ignore_above,
6
+ :ignore_malformed, :include_in_all, :index_options, :lat_lon, :index, :fields, :norms,
7
+ :null_value, :position_increment_gap, :properties, :search_analyzer, :similarity, :store,
8
+ :term_vector
9
+ ]
10
+
11
+ def initialize(_name, _options)
12
+ @name = _name
13
+ @user_options = _options
14
+ end
15
+
16
+ def mapping_options
17
+ @user_options.slice(*MAPPING_OPTIONS)
18
+ end
19
+
20
+ def prepare_for_query(_value)
21
+ prepare_for_index _value
22
+ end
23
+
24
+ def prepare_for_index(_value)
25
+ _value
26
+ end
27
+
28
+ def prepare_value_for_result(_value)
29
+ _value
30
+ end
31
+
32
+ def supported_aggregations
33
+ [:terms, :histogram, :range]
34
+ end
35
+
36
+ def supported_queries
37
+ [:term, :range]
38
+ end
39
+
40
+ # default configurations
41
+
42
+ def term_query_defaults
43
+ {}
44
+ end
45
+
46
+ def match_query_defaults
47
+ {}
48
+ end
49
+
50
+ def range_query_defaults
51
+ {}
52
+ end
53
+
54
+ def terms_aggregation_defaults
55
+ { size: 0 }
56
+ end
57
+
58
+ def date_histogram_aggregation_defaults
59
+ {}
60
+ end
61
+
62
+ def histogram_aggregation_defaults
63
+ {}
64
+ end
65
+
66
+ def range_aggregation_defaults
67
+ {}
68
+ end
69
+
70
+ private
71
+
72
+ attr_reader :name, :user_options
73
+ end
74
+ end
@@ -0,0 +1,7 @@
1
+ module Elastic::Datatypes
2
+ class String < Default
3
+ def supported_queries
4
+ [:match, :term, :range]
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ module Elastic::Datatypes
2
+ class Term < Default
3
+ def mapping_options
4
+ options = super
5
+ options[:type] = 'string'
6
+ options[:index] = 'not_analyzed'
7
+ options
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,29 @@
1
+ module Elastic::Datatypes
2
+ class Time < Default
3
+ def mapping_options
4
+ options = super
5
+ options[:type] = 'date'
6
+ options
7
+ end
8
+
9
+ def prepare_value_for_result(_value)
10
+ # TODO: set timezone
11
+ case _value
12
+ when ::String
13
+ ::Time.parse(_value)
14
+ when ::Integer
15
+ ::Time.at(_value / 1000)
16
+ else
17
+ _value
18
+ end
19
+ end
20
+
21
+ def supported_aggregations
22
+ [:date_histogram] + super
23
+ end
24
+
25
+ def date_histogram_aggregation_defaults
26
+ { interval: '1h' }
27
+ end
28
+ end
29
+ end
@@ -1,5 +1,9 @@
1
1
  module Elastic::Dsl
2
2
  module BoolQueryBuilder
3
+ def coord_similarity(_enable)
4
+ with_bool_query { |query| query.disable_coord = !_enable }
5
+ end
6
+
3
7
  def must(*_queries)
4
8
  with_bool_query do |query|
5
9
  query.must build_query_from_params(_queries)
@@ -7,19 +7,32 @@ module Elastic::Fields
7
7
  @index = _index
8
8
  end
9
9
 
10
+ def merge!(_options)
11
+ # does nothing
12
+ end
13
+
10
14
  def expanded_names
11
15
  [@name] + @index.definition.expanded_field_names.map { |n| @name + '.' + n }
12
16
  end
13
17
 
14
- def mapping_inference_enabled?
18
+ def validate
19
+ nil
20
+ end
21
+
22
+ def needs_inference?
15
23
  false
16
24
  end
17
25
 
26
+ def nested?
27
+ true
28
+ end
29
+
18
30
  def disable_mapping_inference
31
+ # does nothing, inference is always disabled
19
32
  end
20
33
 
21
34
  def freeze
22
- @index.freeze_index_definition
35
+ @index.freeze_definition
23
36
  super
24
37
  end
25
38
 
@@ -31,12 +44,17 @@ module Elastic::Fields
31
44
  @index.definition.get_field _name
32
45
  end
33
46
 
34
- def prepare_value_for_query(_value)
35
- _value
36
- end
37
-
38
47
  def prepare_value_for_index(_values)
39
48
  _values.map { |v| @index.new(v).as_es_document(only_data: true) }
40
49
  end
50
+
51
+ def prepare_value_for_result(_values)
52
+ formatter = Elastic::Core::SourceFormatter.new @index.definition
53
+ _values.each { |v| formatter.format(v) }
54
+ end
55
+
56
+ def select_aggregation(_from)
57
+ nil
58
+ end
41
59
  end
42
60
  end
@@ -1,60 +1,104 @@
1
1
  module Elastic::Fields
2
2
  class Value
3
- MAPPING_OPTIONS = [
4
- :type, :analyzer, :boost, :coerce, :copy_to, :doc_values, :dynamic,
5
- :enabled, :fielddata, :geohash, :geohash_precision, :geohash_prefix, :format, :ignore_above,
6
- :ignore_malformed, :include_in_all, :index_options, :lat_lon, :index, :fields, :norms,
7
- :null_value, :position_increment_gap, :properties, :search_analyzer, :similarity, :store,
8
- :term_vector
9
- ]
3
+ extend Forwardable
10
4
 
11
5
  attr_reader :name
12
6
 
7
+ def_delegators :@datatype, :mapping_options, :prepare_value_for_result, :supported_queries,
8
+ :supported_aggregations
9
+
10
+ def_delegators :@datatype, :term_query_defaults, :match_query_defaults, :range_query_defaults,
11
+ :terms_aggregation_defaults, :date_histogram_aggregation_defaults,
12
+ :histogram_aggregation_defaults, :range_aggregation_defaults
13
+
13
14
  def initialize(_name, _options)
14
15
  @name = _name.to_s
15
- @options = _options
16
+ @options = _options.symbolize_keys
16
17
  @mapping_inference = true
17
- @transform = Elastic::Support::Transform.new @options[:transform]
18
+ end
19
+
20
+ def nested?
21
+ false
22
+ end
23
+
24
+ def merge!(_options)
25
+ return if _options.nil?
26
+ @options.merge! _options.symbolize_keys
27
+ end
28
+
29
+ def get_field(_name)
30
+ nil
31
+ end
32
+
33
+ def validate
34
+ return "explicit field type for #{@name} required" unless @options.key? :type
35
+ nil
18
36
  end
19
37
 
20
38
  def expanded_names
21
39
  [@name]
22
40
  end
23
41
 
24
- def mapping_inference_enabled?
25
- @mapping_inference && !@options.key?(:transform)
42
+ def needs_inference?
43
+ mapping_inference_enabled? && !@options.key?(:type)
26
44
  end
27
45
 
28
46
  def disable_mapping_inference
29
47
  @mapping_inference = false
30
48
  end
31
49
 
32
- def mapping_options
33
- process_special_types @options.symbolize_keys.slice(*MAPPING_OPTIONS)
34
- end
35
-
36
- def has_field?(_name)
37
- false
50
+ def freeze
51
+ @name.freeze
52
+ @options.freeze
53
+ load_transform_and_datatype
38
54
  end
39
55
 
40
56
  def prepare_value_for_query(_value)
41
- prepare_value_for_index(_value)
57
+ _value = @transform.apply _value if @transform
58
+ @datatype.prepare_for_query _value
42
59
  end
43
60
 
44
61
  def prepare_value_for_index(_value)
45
- @transform.apply _value
62
+ _value = @transform.apply _value if @transform
63
+ @datatype.prepare_for_index _value
46
64
  end
47
65
 
48
66
  private
49
67
 
50
- def process_special_types(_definition)
51
- case _definition[:type].try(:to_sym)
52
- when :term
53
- _definition[:type] = 'string'
54
- _definition[:index] = 'not_analyzed'
68
+ def load_transform_and_datatype
69
+ @datatype = datatype_class.new(@name, @options)
70
+ @transform = Elastic::Support::Transform.new @options[:transform] if @options.key? :transform
71
+ end
72
+
73
+ def mapping_inference_enabled?
74
+ @mapping_inference && !@options.key?(:transform)
75
+ end
76
+
77
+ def datatype_class
78
+ case @options[:type]
79
+ when Symbol, String
80
+ load_registered_datatype @options[:type].to_sym
81
+ when nil
82
+ Elastic::Datatypes::Default
83
+ else
84
+ @options[:type]
55
85
  end
86
+ end
56
87
 
57
- _definition
88
+ def load_registered_datatype(_name)
89
+ # TODO: replace this with a datatype registry
90
+ case _name
91
+ when :term
92
+ Elastic::Datatypes::Term
93
+ when :string
94
+ Elastic::Datatypes::String
95
+ when :date
96
+ Elastic::Datatypes::Date
97
+ when :time
98
+ Elastic::Datatypes::Time
99
+ else
100
+ Elastic::Datatypes::Default
101
+ end
58
102
  end
59
103
  end
60
104
  end
@@ -0,0 +1,34 @@
1
+ module Elastic
2
+ class NestedQuery
3
+ include Elastic::Dsl::BoolQueryBuilder
4
+
5
+ attr_reader :index
6
+
7
+ def initialize(_index, _root = nil)
8
+ @index = _index
9
+ @root = _root || build_root_node
10
+ end
11
+
12
+ def score_mode(_mode)
13
+ with_clone { |root| root.score_mode = _mode }
14
+ end
15
+
16
+ def as_node
17
+ @root.clone
18
+ end
19
+
20
+ private
21
+
22
+ def with_clone(&_block)
23
+ self.class.new @index, @root.clone.tap(&_block)
24
+ end
25
+
26
+ def with_bool_query(&_block)
27
+ with_clone { |root| root.child.tap(&_block) }
28
+ end
29
+
30
+ def build_root_node
31
+ Elastic::Nodes::Nested.build(nil, Elastic::Nodes::Boolean.new)
32
+ end
33
+ end
34
+ end
@@ -1,5 +1,15 @@
1
1
  module Elastic
2
2
  class NestedType < Types::BaseType
3
3
  extend Types::FacetedType
4
+
5
+ class << self
6
+ extend Forwardable
7
+
8
+ def_delegators :query, :must, :should, :segment, :coord_similarity
9
+ end
10
+
11
+ def self.query
12
+ NestedQuery.new self
13
+ end
4
14
  end
5
15
  end
@@ -1,6 +1,8 @@
1
1
  module Elastic::Nodes::Agg
2
2
  class Average < BaseMetric
3
- private def metric
3
+ private
4
+
5
+ def metric
4
6
  'avg'
5
7
  end
6
8
  end
@@ -17,14 +17,15 @@ module Elastic::Nodes::Agg
17
17
  prepare_clone super
18
18
  end
19
19
 
20
- def render
21
- options = { 'field' => @field.to_s }
22
- options['missing'] = @missing if @missing
20
+ def render(_options = {})
21
+ hash = { 'field' => @field.to_s }
22
+ hash['missing'] = @missing if @missing
23
23
 
24
- { metric => options }
24
+ { metric => hash }
25
25
  end
26
26
 
27
- def handle_result(_raw)
27
+ def handle_result(_raw, _formatter)
28
+ # TODO: apply formatter to value
28
29
  Elastic::Results::Metric.new _raw['value']
29
30
  end
30
31
 
@@ -26,11 +26,11 @@ module Elastic::Nodes::Agg
26
26
  prepare_clone(super)
27
27
  end
28
28
 
29
- def render
30
- options = { 'field' => @field.to_s }
31
- options['interval'] = @interval if @interval
29
+ def render(_options = {})
30
+ hash = { 'field' => @field.to_s }
31
+ hash['interval'] = @interval if @interval
32
32
 
33
- render_aggs 'date_histogram' => options
33
+ render_aggs({ 'date_histogram' => hash }, _options)
34
34
  end
35
35
 
36
36
  private
@@ -1,6 +1,8 @@
1
1
  module Elastic::Nodes::Agg
2
2
  class Maximum < BaseMetric
3
- private def metric
3
+ private
4
+
5
+ def metric
4
6
  'max'
5
7
  end
6
8
  end
@@ -1,6 +1,8 @@
1
1
  module Elastic::Nodes::Agg
2
2
  class Minimum < BaseMetric
3
- private def metric
3
+ private
4
+
5
+ def metric
4
6
  'min'
5
7
  end
6
8
  end
@@ -1,6 +1,8 @@
1
1
  module Elastic::Nodes::Agg
2
2
  class Stats < BaseMetric
3
- private def metric
3
+ private
4
+
5
+ def metric
4
6
  'stats'
5
7
  end
6
8
  end
@@ -1,6 +1,8 @@
1
1
  module Elastic::Nodes::Agg
2
2
  class Sum < BaseMetric
3
- private def metric
3
+ private
4
+
5
+ def metric
4
6
  'sum'
5
7
  end
6
8
  end