elasticated 2.5.5 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +35 -2
  3. data/Rakefile +52 -1
  4. data/elasticated.gemspec +3 -1
  5. data/lib/elasticated.rb +20 -24
  6. data/lib/elasticated/aggregation.rb +3 -6
  7. data/lib/elasticated/aggregations/date_histogram_aggregation.rb +6 -1
  8. data/lib/elasticated/aggregations/filter_aggregation.rb +8 -12
  9. data/lib/elasticated/aggregations/filter_aggregation_evaluator.rb +1 -1
  10. data/lib/elasticated/aggregations/group_aggregation.rb +14 -11
  11. data/lib/elasticated/aggregations/range_aggregation.rb +10 -11
  12. data/lib/elasticated/aggregations/range_aggregation_evaluator.rb +1 -1
  13. data/lib/elasticated/aggregations/ranges_builder.rb +2 -2
  14. data/lib/elasticated/aggregations/safe_date_histogram_aggregation.rb +7 -2
  15. data/lib/elasticated/aggregations/subaggregated.rb +1 -1
  16. data/lib/elasticated/boolean_clause.rb +4 -3
  17. data/lib/elasticated/bulk_actions/create_action.rb +14 -0
  18. data/lib/elasticated/bulk_actions/delete_action.rb +30 -0
  19. data/lib/elasticated/bulk_actions/index_action.rb +35 -0
  20. data/lib/elasticated/bulk_actions/standard_action.rb +22 -0
  21. data/lib/elasticated/bulk_actions/update_action.rb +44 -0
  22. data/lib/elasticated/bulk_actions/upsert_action.rb +14 -0
  23. data/lib/elasticated/bulk_request.rb +58 -0
  24. data/lib/elasticated/bulk_request/response.rb +32 -0
  25. data/lib/elasticated/bulk_request/response_item.rb +39 -0
  26. data/lib/elasticated/client.rb +27 -3
  27. data/lib/elasticated/conditions/custom_condition.rb +3 -3
  28. data/lib/elasticated/conditions/range_condition.rb +5 -2
  29. data/lib/elasticated/conditions/script_condition.rb +3 -3
  30. data/lib/elasticated/conditions/standard_condition.rb +4 -5
  31. data/lib/elasticated/conditions/term_condition.rb +22 -0
  32. data/lib/elasticated/conditions/terms_condition.rb +2 -2
  33. data/lib/elasticated/conditions_builder.rb +19 -4
  34. data/lib/elasticated/delimiters/date_field_delimiter.rb +21 -12
  35. data/lib/elasticated/delimiters/standard_field_delimiter.rb +18 -2
  36. data/lib/elasticated/delimiters/term_field_delimiter.rb +6 -5
  37. data/lib/elasticated/document.rb +20 -1
  38. data/lib/elasticated/enum.rb +17 -0
  39. data/lib/elasticated/index_selector.rb +26 -25
  40. data/lib/elasticated/mapping.rb +2 -4
  41. data/lib/elasticated/mapping/builder.rb +3 -2
  42. data/lib/elasticated/mapping/fields_builder.rb +13 -9
  43. data/lib/elasticated/mapping/object_builder.rb +38 -4
  44. data/lib/elasticated/mapping/type_builder.rb +3 -5
  45. data/lib/elasticated/mixins/block_evaluation.rb +17 -0
  46. data/lib/elasticated/mixins/clonable.rb +60 -0
  47. data/lib/elasticated/mixins/configurable.rb +22 -0
  48. data/lib/elasticated/mixins/inspectionable.rb +16 -0
  49. data/lib/elasticated/partitioned_repository.rb +24 -18
  50. data/lib/elasticated/query.rb +27 -21
  51. data/lib/elasticated/query_aggregations.rb +5 -7
  52. data/lib/elasticated/query_conditions.rb +6 -3
  53. data/lib/elasticated/quick.rb +7 -0
  54. data/lib/elasticated/repository.rb +184 -40
  55. data/lib/elasticated/repository/intelligent_search.rb +3 -3
  56. data/lib/elasticated/repository/normal_search.rb +2 -2
  57. data/lib/elasticated/repository/resumable_search.rb +5 -5
  58. data/lib/elasticated/repository/scan_scroll_search.rb +4 -4
  59. data/lib/elasticated/repository/scroll_search.rb +3 -3
  60. data/lib/elasticated/repository/search.rb +7 -0
  61. data/lib/elasticated/repository/single_page_search.rb +1 -1
  62. data/lib/elasticated/results.rb +14 -0
  63. data/lib/version.rb +18 -25
  64. data/spec/aggregation_spec.rb +95 -16
  65. data/spec/bulk_request_spec.rb +158 -0
  66. data/spec/date_field_delimiter_spec.rb +50 -6
  67. data/spec/document_spec.rb +1 -5
  68. data/spec/integration_spec.rb +7 -7
  69. data/spec/mapping_spec.rb +128 -8
  70. data/spec/partitioned_repository_spec.rb +218 -0
  71. data/spec/query_conditions_spec.rb +98 -45
  72. data/spec/query_spec.rb +21 -28
  73. data/spec/repository_spec.rb +245 -0
  74. data/spec/results_spec.rb +0 -4
  75. data/spec/sample_responses/elasticsearch_bulk_response_1.json +35 -0
  76. data/spec/sample_responses/elasticsearch_bulk_response_2.json +20 -0
  77. data/spec/sample_responses/elasticsearch_count_1.json +8 -0
  78. data/spec/sample_responses/elasticsearch_count_2.json +8 -0
  79. data/spec/sample_responses/elasticsearch_get_response_1.json +10 -0
  80. data/spec/sample_responses/elasticsearch_get_response_2.json +6 -0
  81. data/spec/{elasticsearch_hit_1.json → sample_responses/elasticsearch_hit_1.json} +0 -0
  82. data/spec/sample_responses/elasticsearch_mget_response_1.json +25 -0
  83. data/spec/{elasticsearch_response_1.json → sample_responses/elasticsearch_response_1.json} +0 -0
  84. data/spec/{elasticsearch_response_2.json → sample_responses/elasticsearch_response_2.json} +0 -0
  85. data/spec/{elasticsearch_top_hits_response.json → sample_responses/elasticsearch_top_hits_response.json} +0 -0
  86. data/spec/spec_helper.rb +47 -0
  87. data/spec/spec_helper/fake_index_selector.rb +27 -0
  88. data/spec/term_field_delimiter_spec.rb +8 -8
  89. metadata +80 -26
  90. data/lib/elasticated/block_evaluation.rb +0 -15
  91. data/lib/elasticated/clonable.rb +0 -58
  92. data/lib/elasticated/configurable.rb +0 -20
  93. data/lib/elasticated/date_delimiter_factory.rb +0 -123
  94. data/lib/elasticated/delimiter_visitor.rb +0 -53
  95. data/lib/elasticated/inspectionable.rb +0 -9
  96. data/lib/elasticated/strategy_params_for_query_service.rb +0 -14
  97. data/lib/elasticated/term_delimiter_factory.rb +0 -73
  98. data/spec/delimiter_factory_spec.rb +0 -399
  99. data/spec/strategy_params_for_query_service_spec.rb +0 -387
@@ -2,9 +2,8 @@ module Elasticated
2
2
  module Conditions
3
3
  class StandardCondition
4
4
 
5
- include Inspectionable
6
-
7
- include Clonable
5
+ include Mixins::Inspectionable
6
+ include Mixins::Clonable
8
7
 
9
8
  attr_accessor :field, :opts
10
9
 
@@ -13,8 +12,8 @@ module Elasticated
13
12
  self.opts = opts
14
13
  end
15
14
 
16
- def accept_visitor(visitor)
17
- visitor.visit_condition(self)
15
+ def fill_delimiter(field_delimiter)
16
+ # nothing to do, by default
18
17
  end
19
18
 
20
19
  end
@@ -0,0 +1,22 @@
1
+ module Elasticated
2
+ module Conditions
3
+ class TermCondition < StandardCondition
4
+
5
+ attr_accessor :value
6
+
7
+ def initialize(field, value, opts={})
8
+ super(field, opts)
9
+ self.value = value
10
+ end
11
+
12
+ def build
13
+ { term: { field => value }.merge(opts) }
14
+ end
15
+
16
+ def fill_delimiter(field_delimiter)
17
+ field_delimiter.add_term field, value
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -13,8 +13,8 @@ module Elasticated
13
13
  { terms: { field => values }.merge(opts) }
14
14
  end
15
15
 
16
- def accept_visitor(visitor)
17
- visitor.visit_terms(self)
16
+ def fill_delimiter(field_delimiter)
17
+ values.each{ |value| field_delimiter.add_term field, value }
18
18
  end
19
19
 
20
20
  end
@@ -1,16 +1,20 @@
1
1
  module Elasticated
2
2
  module ConditionsBuilder
3
3
 
4
- include BlockEvaluation
4
+ include Mixins::BlockEvaluation
5
5
 
6
6
  def custom(body)
7
7
  add Conditions::CustomCondition.new body
8
8
  end
9
9
 
10
- def equal(field, values, opts={})
10
+ def term(field, value, opts={})
11
+ add Conditions::TermCondition.new field, value, opts
12
+ end
13
+
14
+ def terms(field, values, opts={})
11
15
  add Conditions::TermsCondition.new field, [*values], opts
12
16
  end
13
- alias_method :terms, :equal
17
+ alias_method :equal, :terms
14
18
 
15
19
  def wildcard(field, value, opts={})
16
20
  add Conditions::WildcardCondition.new field, value, opts
@@ -28,9 +32,10 @@ module Elasticated
28
32
  add Conditions::MissingCondition.new field, opts
29
33
  end
30
34
 
31
- def between(field, min_value, max_value, opts={})
35
+ def range(field, min_value, max_value, opts={})
32
36
  add Conditions::RangeCondition.new field, { lte: max_value, gte: min_value }, opts
33
37
  end
38
+ alias_method :between, :range
34
39
 
35
40
  def greater_than(field, value, opts={})
36
41
  add Conditions::RangeCondition.new field, { gt: value }, opts
@@ -71,5 +76,15 @@ module Elasticated
71
76
  end
72
77
  alias_method :bool, :boolean
73
78
 
79
+ # helper methods
80
+
81
+ def equal(field, value_or_values, opts={})
82
+ value_or_values.is_a?(Array) ? terms(field, value_or_values, opts) : term(field, value_or_values, opts)
83
+ end
84
+
85
+ def now
86
+ Elasticated::Enum::NOW
87
+ end
88
+
74
89
  end
75
90
  end
@@ -1,30 +1,39 @@
1
1
  module Elasticated
2
2
  module Delimiters
3
- class DateFieldDelimiter < StandardFieldDelimiter
3
+ class DateFieldDelimiter < TermFieldDelimiter
4
4
 
5
5
  attr_accessor :date_since, :date_until
6
6
 
7
- def initialize(opts={})
8
- super
9
- self.date_since = opts[:date_since]
10
- self.date_until = opts[:date_until]
7
+ def set_minimum(field, date)
8
+ return unless applies_to? field
9
+ raise("The date 'now' is not valid as minimum value of a range condition") if is_now?(date)
10
+ self.date_since = date unless date_since && date < date_since
11
+ end
12
+
13
+ def set_maximum(field, date)
14
+ return unless applies_to? field
15
+ return if is_now?(date)
16
+ self.date_until = date unless date_until && date > date_until
11
17
  end
12
18
 
13
19
  def build_strategy_params
14
20
  params = Hash.new
15
- raise "date_since is higher than date_until (#{date_since} - #{date_until})" \
16
- if date_since && date_until && date_since > date_until
17
- if date_since == date_until and not date_since.nil?
18
- params.merge! date: date_since
19
- else
21
+ if values.empty?
22
+ raise "date_since is higher than date_until (#{date_since} - #{date_until})" \
23
+ if date_since && date_until && date_since > date_until
20
24
  params.merge! date_since: date_since if date_since
21
25
  params.merge! date_until: date_until if date_until
26
+ else
27
+ raise "Only one 'term' filter is allowed over the '#{field_name}' field" if values.count > 1
28
+ params.merge! date: values.first
22
29
  end
23
30
  params
24
31
  end
25
32
 
26
- def completed_with(delimiters, opts={})
27
- Elasticated.date_delimiter_factory.create(self, delimiters, opts)
33
+ protected
34
+
35
+ def is_now?(date)
36
+ date.to_s == Elasticated::Enum::NOW
28
37
  end
29
38
 
30
39
  end
@@ -8,8 +8,24 @@ module Elasticated
8
8
  attr_accessor :field_name, :filter_name
9
9
 
10
10
  def initialize(opts={})
11
- self.field_name = opts.fetch(:field)
12
- self.filter_name = opts.fetch(:as, field_name)
11
+ self.field_name = opts.fetch :field
12
+ self.filter_name = opts.fetch :as, field_name
13
+ end
14
+
15
+ def applies_to?(condition_field)
16
+ field_name.to_s == condition_field.to_s
17
+ end
18
+
19
+ def add_term(field, value)
20
+ # nothing to do, by default
21
+ end
22
+
23
+ def set_minimum(field, value)
24
+ # nothing to do, by default
25
+ end
26
+
27
+ def set_maximum(field, value)
28
+ # nothing to do, by default
13
29
  end
14
30
 
15
31
  end
@@ -6,7 +6,12 @@ module Elasticated
6
6
 
7
7
  def initialize(opts={})
8
8
  super
9
- self.values = opts[:values] || []
9
+ self.values = Array.new
10
+ end
11
+
12
+ def add_term(field, value)
13
+ return unless applies_to? field
14
+ values << value
10
15
  end
11
16
 
12
17
  def build_strategy_params
@@ -14,10 +19,6 @@ module Elasticated
14
19
  { filter_name => values.uniq }
15
20
  end
16
21
 
17
- def completed_with(delimiters, opts={})
18
- Elasticated.term_delimiter_factory.create(self, delimiters, opts)
19
- end
20
-
21
22
  end
22
23
  end
23
24
  end
@@ -27,7 +27,8 @@ module Elasticated
27
27
 
28
28
  end
29
29
 
30
- include BlockEvaluation
30
+ include Mixins::Inspectionable
31
+ include Mixins::BlockEvaluation
31
32
 
32
33
  attr_accessor :id, :type, :index, :score, :version, :document_source
33
34
 
@@ -43,5 +44,23 @@ module Elasticated
43
44
  self.document_source ||= Hash::Accessible.new
44
45
  end
45
46
 
47
+ def text_for_inspect
48
+ text = "#{index}/#{type}/#{id}"
49
+ text = "#{text} v#{version}" if version
50
+ text = "#{text} scoring #{score}" if score
51
+ text
52
+ end
53
+
54
+ def to_h
55
+ {
56
+ _id: id,
57
+ _type: type,
58
+ _index: index,
59
+ _score: score,
60
+ _version: version,
61
+ _source: source.to_h
62
+ }
63
+ end
64
+
46
65
  end
47
66
  end
@@ -0,0 +1,17 @@
1
+ module Elasticated
2
+ module Enum
3
+
4
+ NOW = 'now'.freeze
5
+
6
+ module Mapping
7
+ module Dynamic
8
+
9
+ ACCEPT_NEW_FIELDS = true
10
+ IGNORE_NEW_FIELDS = false
11
+ STRICT = 'strict'.freeze
12
+
13
+ end
14
+ end
15
+
16
+ end
17
+ end
@@ -1,39 +1,38 @@
1
1
  module Elasticated
2
2
  class IndexSelector
3
3
 
4
+ # abstract class
5
+ # child must implement 'delimiters()'
6
+ # child must implement 'strategy()'
4
7
  # child can override 'strategy_params_for(document)'
5
8
 
6
- include BlockEvaluation
9
+ include Mixins::BlockEvaluation
7
10
 
8
- attr_reader :strategy, :delimiters
9
-
10
- # params will not be optionals in the next version
11
- def initialize(strategy=nil, delimiters=nil)
12
- @strategy = strategy
13
- @delimiters = delimiters
11
+ def index_for_params(params)
12
+ indices = indices_for_params params
13
+ raise "Only one index can be affected" if indices.count > 1
14
+ indices.first
14
15
  end
15
16
 
16
- def indices_for_query(query, opts={})
17
- params = strategy_params_for_query(query, opts)
17
+ def indices_for_params(params)
18
18
  indices = strategy.call params
19
- raise "At least one index should be affected for a search" if indices.count < 1
19
+ raise "At least one index should be affected" if indices.count < 1
20
20
  indices
21
21
  end
22
22
 
23
+ def indices_for_query(query)
24
+ params = strategy_params_for_query query
25
+ indices_for_params params
26
+ end
27
+
23
28
  def index_for_document(document)
24
29
  params = strategy_params_for_document document
25
- indices = strategy.call params
26
- raise "Only one index can be affected for a document indexation" if indices.count > 1
27
- raise "At least one index should be affected for a document indexation" if indices.count < 1
28
- indices.first
30
+ index_for_params params
29
31
  end
30
32
 
31
- def index_for_percolator(query)
32
- params = strategy_params_for_percolator query
33
- indices = strategy.call params
34
- raise "Only one index can be affected for a percolator indexation" if indices.count > 1
35
- raise "At least one index should be affected for a percolator indexation" if indices.count < 1
36
- indices.first
33
+ def index_for_percolator
34
+ params = strategy_params_for_percolator
35
+ index_for_params params
37
36
  end
38
37
 
39
38
  protected
@@ -46,13 +45,15 @@ module Elasticated
46
45
  end
47
46
  end
48
47
 
49
- def strategy_params_for_percolator(query)
50
- { date: DateTime.now.iso8601 }
48
+ def strategy_params_for_query(query)
49
+ delimiters.inject Hash.new do |params, delimiter|
50
+ query.fill_delimiter delimiter
51
+ params.merge delimiter.build_strategy_params
52
+ end
51
53
  end
52
54
 
53
- def strategy_params_for_query(query, opts={})
54
- service = Elasticated.strategy_params_for_query_service
55
- service.strategy_params_for_query(delimiters, query, opts)
55
+ def strategy_params_for_percolator
56
+ { date: DateTime.now.iso8601 }
56
57
  end
57
58
 
58
59
  end
@@ -4,13 +4,11 @@ module Elasticated
4
4
  class << self
5
5
 
6
6
  def partial(&block)
7
- Partial.new &block
7
+ Partial.new(&block)
8
8
  end
9
9
 
10
10
  def build(&block)
11
- instance = Builder.new
12
- instance.evaluate block
13
- instance.build
11
+ Builder.build(&block)
14
12
  end
15
13
 
16
14
  end
@@ -6,11 +6,11 @@ module Elasticated
6
6
  def build(&block)
7
7
  instance = new
8
8
  instance.evaluate block
9
- instance.build
9
+ instance
10
10
  end
11
11
  end
12
12
 
13
- include BlockEvaluation
13
+ include Mixins::BlockEvaluation
14
14
 
15
15
  attr_accessor :mapping_types
16
16
 
@@ -30,6 +30,7 @@ module Elasticated
30
30
  hash.merge mapping_type.build
31
31
  end
32
32
  end
33
+ alias_method :to_h, :build
33
34
 
34
35
  end
35
36
  end
@@ -2,7 +2,7 @@ module Elasticated
2
2
  module Mapping
3
3
  class FieldsBuilder
4
4
 
5
- include BlockEvaluation
5
+ include Mixins::BlockEvaluation
6
6
 
7
7
  attr_accessor :hash, :name, :sub_objects, :nesteds
8
8
 
@@ -13,36 +13,40 @@ module Elasticated
13
13
  self.name = name
14
14
  end
15
15
 
16
+ def add_property(name, value)
17
+ hash[name] = value
18
+ end
19
+
16
20
  def date(field_name)
17
- hash[field_name] = build_date_field
21
+ add_property field_name, build_date_field
18
22
  end
19
23
 
20
24
  def string(field_name)
21
- hash[field_name] = build_string_field
25
+ add_property field_name, build_string_field
22
26
  end
23
27
 
24
28
  def float(field_name)
25
- hash[field_name] = build_float_field
29
+ add_property field_name, build_float_field
26
30
  end
27
31
 
28
32
  def double(field_name)
29
- hash[field_name] = build_double_field
33
+ add_property field_name, build_double_field
30
34
  end
31
35
 
32
36
  def integer(field_name)
33
- hash[field_name] = build_integer_field
37
+ add_property field_name, build_integer_field
34
38
  end
35
39
 
36
40
  def long(field_name)
37
- hash[field_name] = build_long_field
41
+ add_property field_name, build_long_field
38
42
  end
39
43
 
40
44
  def analyzed_string(field_name)
41
- hash[field_name] = build_analyzed_string_field field_name
45
+ add_property field_name, build_analyzed_string_field(field_name)
42
46
  end
43
47
 
44
48
  def bool(field_name)
45
- hash[field_name] = build_bool_field
49
+ add_property field_name, build_bool_field
46
50
  end
47
51
 
48
52
  def object(object_name, &block)