elasticated 2.5.5 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +35 -2
- data/Rakefile +52 -1
- data/elasticated.gemspec +3 -1
- data/lib/elasticated.rb +20 -24
- data/lib/elasticated/aggregation.rb +3 -6
- data/lib/elasticated/aggregations/date_histogram_aggregation.rb +6 -1
- data/lib/elasticated/aggregations/filter_aggregation.rb +8 -12
- data/lib/elasticated/aggregations/filter_aggregation_evaluator.rb +1 -1
- data/lib/elasticated/aggregations/group_aggregation.rb +14 -11
- data/lib/elasticated/aggregations/range_aggregation.rb +10 -11
- data/lib/elasticated/aggregations/range_aggregation_evaluator.rb +1 -1
- data/lib/elasticated/aggregations/ranges_builder.rb +2 -2
- data/lib/elasticated/aggregations/safe_date_histogram_aggregation.rb +7 -2
- data/lib/elasticated/aggregations/subaggregated.rb +1 -1
- data/lib/elasticated/boolean_clause.rb +4 -3
- data/lib/elasticated/bulk_actions/create_action.rb +14 -0
- data/lib/elasticated/bulk_actions/delete_action.rb +30 -0
- data/lib/elasticated/bulk_actions/index_action.rb +35 -0
- data/lib/elasticated/bulk_actions/standard_action.rb +22 -0
- data/lib/elasticated/bulk_actions/update_action.rb +44 -0
- data/lib/elasticated/bulk_actions/upsert_action.rb +14 -0
- data/lib/elasticated/bulk_request.rb +58 -0
- data/lib/elasticated/bulk_request/response.rb +32 -0
- data/lib/elasticated/bulk_request/response_item.rb +39 -0
- data/lib/elasticated/client.rb +27 -3
- data/lib/elasticated/conditions/custom_condition.rb +3 -3
- data/lib/elasticated/conditions/range_condition.rb +5 -2
- data/lib/elasticated/conditions/script_condition.rb +3 -3
- data/lib/elasticated/conditions/standard_condition.rb +4 -5
- data/lib/elasticated/conditions/term_condition.rb +22 -0
- data/lib/elasticated/conditions/terms_condition.rb +2 -2
- data/lib/elasticated/conditions_builder.rb +19 -4
- data/lib/elasticated/delimiters/date_field_delimiter.rb +21 -12
- data/lib/elasticated/delimiters/standard_field_delimiter.rb +18 -2
- data/lib/elasticated/delimiters/term_field_delimiter.rb +6 -5
- data/lib/elasticated/document.rb +20 -1
- data/lib/elasticated/enum.rb +17 -0
- data/lib/elasticated/index_selector.rb +26 -25
- data/lib/elasticated/mapping.rb +2 -4
- data/lib/elasticated/mapping/builder.rb +3 -2
- data/lib/elasticated/mapping/fields_builder.rb +13 -9
- data/lib/elasticated/mapping/object_builder.rb +38 -4
- data/lib/elasticated/mapping/type_builder.rb +3 -5
- data/lib/elasticated/mixins/block_evaluation.rb +17 -0
- data/lib/elasticated/mixins/clonable.rb +60 -0
- data/lib/elasticated/mixins/configurable.rb +22 -0
- data/lib/elasticated/mixins/inspectionable.rb +16 -0
- data/lib/elasticated/partitioned_repository.rb +24 -18
- data/lib/elasticated/query.rb +27 -21
- data/lib/elasticated/query_aggregations.rb +5 -7
- data/lib/elasticated/query_conditions.rb +6 -3
- data/lib/elasticated/quick.rb +7 -0
- data/lib/elasticated/repository.rb +184 -40
- data/lib/elasticated/repository/intelligent_search.rb +3 -3
- data/lib/elasticated/repository/normal_search.rb +2 -2
- data/lib/elasticated/repository/resumable_search.rb +5 -5
- data/lib/elasticated/repository/scan_scroll_search.rb +4 -4
- data/lib/elasticated/repository/scroll_search.rb +3 -3
- data/lib/elasticated/repository/search.rb +7 -0
- data/lib/elasticated/repository/single_page_search.rb +1 -1
- data/lib/elasticated/results.rb +14 -0
- data/lib/version.rb +18 -25
- data/spec/aggregation_spec.rb +95 -16
- data/spec/bulk_request_spec.rb +158 -0
- data/spec/date_field_delimiter_spec.rb +50 -6
- data/spec/document_spec.rb +1 -5
- data/spec/integration_spec.rb +7 -7
- data/spec/mapping_spec.rb +128 -8
- data/spec/partitioned_repository_spec.rb +218 -0
- data/spec/query_conditions_spec.rb +98 -45
- data/spec/query_spec.rb +21 -28
- data/spec/repository_spec.rb +245 -0
- data/spec/results_spec.rb +0 -4
- data/spec/sample_responses/elasticsearch_bulk_response_1.json +35 -0
- data/spec/sample_responses/elasticsearch_bulk_response_2.json +20 -0
- data/spec/sample_responses/elasticsearch_count_1.json +8 -0
- data/spec/sample_responses/elasticsearch_count_2.json +8 -0
- data/spec/sample_responses/elasticsearch_get_response_1.json +10 -0
- data/spec/sample_responses/elasticsearch_get_response_2.json +6 -0
- data/spec/{elasticsearch_hit_1.json → sample_responses/elasticsearch_hit_1.json} +0 -0
- data/spec/sample_responses/elasticsearch_mget_response_1.json +25 -0
- data/spec/{elasticsearch_response_1.json → sample_responses/elasticsearch_response_1.json} +0 -0
- data/spec/{elasticsearch_response_2.json → sample_responses/elasticsearch_response_2.json} +0 -0
- data/spec/{elasticsearch_top_hits_response.json → sample_responses/elasticsearch_top_hits_response.json} +0 -0
- data/spec/spec_helper.rb +47 -0
- data/spec/spec_helper/fake_index_selector.rb +27 -0
- data/spec/term_field_delimiter_spec.rb +8 -8
- metadata +80 -26
- data/lib/elasticated/block_evaluation.rb +0 -15
- data/lib/elasticated/clonable.rb +0 -58
- data/lib/elasticated/configurable.rb +0 -20
- data/lib/elasticated/date_delimiter_factory.rb +0 -123
- data/lib/elasticated/delimiter_visitor.rb +0 -53
- data/lib/elasticated/inspectionable.rb +0 -9
- data/lib/elasticated/strategy_params_for_query_service.rb +0 -14
- data/lib/elasticated/term_delimiter_factory.rb +0 -73
- data/spec/delimiter_factory_spec.rb +0 -399
- data/spec/strategy_params_for_query_service_spec.rb +0 -387
@@ -20,7 +20,7 @@ module Elasticated
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def parse_subaggregations(response)
|
23
|
-
if compact and _subaggregations.
|
23
|
+
if compact and _subaggregations.count == 1
|
24
24
|
single_subaggregation = _subaggregations.first
|
25
25
|
single_subaggregation.parse(response[single_subaggregation.name.to_s])
|
26
26
|
else
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module Elasticated
|
2
2
|
class BooleanClause
|
3
3
|
|
4
|
-
include Clonable
|
4
|
+
include Mixins::Clonable
|
5
|
+
include Mixins::Inspectionable
|
5
6
|
|
6
7
|
attr_accessor :conditions
|
7
8
|
|
@@ -11,8 +12,8 @@ module Elasticated
|
|
11
12
|
|
12
13
|
# delimiters
|
13
14
|
|
14
|
-
def
|
15
|
-
|
15
|
+
def fill_delimiter(field_delimiter)
|
16
|
+
conditions.each{ |condition| condition.fill_delimiter field_delimiter }
|
16
17
|
end
|
17
18
|
|
18
19
|
# conditions
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Elasticated
|
2
|
+
module BulkActions
|
3
|
+
class DeleteAction < StandardAction
|
4
|
+
|
5
|
+
attr_accessor :document_id, :params
|
6
|
+
|
7
|
+
def initialize(repository, document_id, params={})
|
8
|
+
super repository
|
9
|
+
self.document_id = document_id
|
10
|
+
self.params = params
|
11
|
+
end
|
12
|
+
|
13
|
+
def build
|
14
|
+
original_params = Helpers.hash_deep_dup params
|
15
|
+
# preparations
|
16
|
+
prepared_params = repository.params_for_ids [document_id], original_params
|
17
|
+
# verifications
|
18
|
+
prepared_params[:index] || raise("A target index should be specified in a delete")
|
19
|
+
prepared_params[:type] || raise("A target type should be specified in a delete")
|
20
|
+
# the final command
|
21
|
+
prepared_params[:_index] = prepared_params.delete :index
|
22
|
+
prepared_params[:_type] = prepared_params.delete :type
|
23
|
+
prepared_params[:_id] = document_id
|
24
|
+
command = { delete: prepared_params }
|
25
|
+
[command]
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Elasticated
|
2
|
+
module BulkActions
|
3
|
+
class IndexAction < StandardAction
|
4
|
+
|
5
|
+
attr_accessor :document, :params
|
6
|
+
|
7
|
+
def initialize(repository, document, params={})
|
8
|
+
super repository
|
9
|
+
self.document = document
|
10
|
+
self.params = params
|
11
|
+
end
|
12
|
+
|
13
|
+
def build
|
14
|
+
original_params = Helpers.hash_deep_dup params
|
15
|
+
# preparations
|
16
|
+
prepared_document = repository.prepare_document document
|
17
|
+
prepared_params = repository.params_for_document document, original_params
|
18
|
+
# the final command
|
19
|
+
prepared_params[:_index] = prepared_params.delete(:index) || prepared_document.index || raise("An index name is required for a document indexation")
|
20
|
+
prepared_params[:_type] = prepared_params.delete(:type) || prepared_document.type || raise("A type name is required for a document indexation")
|
21
|
+
prepared_params[:_id] = prepared_params.delete(:id) || prepared_document.id
|
22
|
+
command = { command_name => prepared_params }
|
23
|
+
prepared_source = prepared_document.source
|
24
|
+
[command, prepared_source]
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
def command_name
|
30
|
+
:index
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Elasticated
|
2
|
+
module BulkActions
|
3
|
+
class StandardAction
|
4
|
+
|
5
|
+
# abstract class
|
6
|
+
# child must implement 'build()' => Hash
|
7
|
+
|
8
|
+
attr_accessor :repository
|
9
|
+
|
10
|
+
def initialize(repository)
|
11
|
+
self.repository = repository
|
12
|
+
end
|
13
|
+
|
14
|
+
# def build
|
15
|
+
# command = build_command
|
16
|
+
# body = build_body
|
17
|
+
# [command, body]
|
18
|
+
# end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Elasticated
|
2
|
+
module BulkActions
|
3
|
+
class UpdateAction < StandardAction
|
4
|
+
|
5
|
+
attr_accessor :document_id, :params
|
6
|
+
|
7
|
+
def initialize(repository, document_id, params={})
|
8
|
+
super repository
|
9
|
+
self.document_id = document_id
|
10
|
+
self.params = params
|
11
|
+
end
|
12
|
+
|
13
|
+
def build
|
14
|
+
original_params = Helpers.hash_deep_dup params
|
15
|
+
# verifications
|
16
|
+
source = original_params.delete(:source) || raise("No body specified for partial update")
|
17
|
+
# preparations
|
18
|
+
prepared_source = repository.prepare_source Helpers.hash_deep_dup source
|
19
|
+
prepared_params = repository.params_for_source source, original_params
|
20
|
+
# more verifications
|
21
|
+
prepared_params[:index] || raise("A target index should be specified in a partial update")
|
22
|
+
prepared_params[:type] || raise("A target type should be specified in a partial update")
|
23
|
+
# the final command
|
24
|
+
prepared_params[:_index] = prepared_params.delete :index
|
25
|
+
prepared_params[:_type] = prepared_params.delete :type
|
26
|
+
prepared_params[:_id] = document_id
|
27
|
+
command = { command_name => prepared_params }
|
28
|
+
body = build_body_from prepared_source
|
29
|
+
[command, body]
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
|
34
|
+
def command_name
|
35
|
+
:update
|
36
|
+
end
|
37
|
+
|
38
|
+
def build_body_from(prepared_source)
|
39
|
+
{ doc: prepared_source }
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Elasticated
|
2
|
+
class BulkRequest
|
3
|
+
|
4
|
+
def self.build_over(repository, &block)
|
5
|
+
request = new repository
|
6
|
+
request.evaluate block
|
7
|
+
request
|
8
|
+
end
|
9
|
+
|
10
|
+
include Mixins::Inspectionable
|
11
|
+
include Mixins::BlockEvaluation
|
12
|
+
|
13
|
+
attr_accessor :repository, :actions
|
14
|
+
attr_accessor :errors, :items
|
15
|
+
|
16
|
+
def initialize(repository)
|
17
|
+
self.repository = repository
|
18
|
+
self.actions = Array.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def add(action)
|
22
|
+
actions << action
|
23
|
+
end
|
24
|
+
|
25
|
+
def build
|
26
|
+
actions.map(&:build).flatten
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_text
|
30
|
+
build.map(&:to_json)*"\n"
|
31
|
+
end
|
32
|
+
|
33
|
+
def get_action_class(action_name)
|
34
|
+
return nil unless action_name.to_s.end_with? '_document'
|
35
|
+
camel_case_name = Helpers.string_to_camel_case action_name.to_s.gsub /\_document$/, ''
|
36
|
+
self.class.const_get("::Elasticated::BulkActions::#{camel_case_name}Action") rescue nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def method_missing(method_name, *args, &block)
|
40
|
+
action_class = get_action_class method_name
|
41
|
+
if action_class
|
42
|
+
action = action_class.new(repository, *args, &block)
|
43
|
+
add action
|
44
|
+
else
|
45
|
+
super
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def respond_to_missing?(name, include_private=false)
|
50
|
+
get_action_class(name) || super
|
51
|
+
end
|
52
|
+
|
53
|
+
def parse(result)
|
54
|
+
Response.parse result
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Elasticated
|
2
|
+
class BulkRequest
|
3
|
+
class Response
|
4
|
+
|
5
|
+
include Mixins::Inspectionable
|
6
|
+
|
7
|
+
def self.parse(elasticsearch_response)
|
8
|
+
response = new
|
9
|
+
response.took = elasticsearch_response['took']
|
10
|
+
response.errors = elasticsearch_response['errors']
|
11
|
+
response.items = elasticsearch_response['items'].map do |elasticsearch_item|
|
12
|
+
ResponseItem.parse elasticsearch_item
|
13
|
+
end
|
14
|
+
response
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_accessor :took, :errors, :items
|
18
|
+
|
19
|
+
def errors?
|
20
|
+
!!errors
|
21
|
+
end
|
22
|
+
alias_method :error?, :errors?
|
23
|
+
|
24
|
+
def text_for_inspect
|
25
|
+
text = (items.count == 1) ? "#{items.count} item" : "#{items.count} items"
|
26
|
+
text = errors? ? "#{text}, with errors" : "#{text}, no errors"
|
27
|
+
text
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Elasticated
|
2
|
+
class BulkRequest
|
3
|
+
class ResponseItem
|
4
|
+
|
5
|
+
include Mixins::Inspectionable
|
6
|
+
|
7
|
+
def self.parse(partial_response)
|
8
|
+
item = new
|
9
|
+
item.action = partial_response.first.first
|
10
|
+
data = partial_response.first.last
|
11
|
+
item.index = data['_index']
|
12
|
+
item.type = data['_type']
|
13
|
+
item.id = data['_id']
|
14
|
+
item.version = data['_version']
|
15
|
+
item.status = data['status']
|
16
|
+
item.found = data['found']
|
17
|
+
item.error = data['error']
|
18
|
+
item
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_accessor :action, :index, :type, :id, :version, :status, :found, :error
|
22
|
+
|
23
|
+
def error?
|
24
|
+
!!error
|
25
|
+
end
|
26
|
+
|
27
|
+
def completed?
|
28
|
+
!error?
|
29
|
+
end
|
30
|
+
|
31
|
+
def text_for_inspect
|
32
|
+
text = "#{action} #{index}/#{type}/#{id} (status #{status})"
|
33
|
+
text = "#{text}, with error" if error?
|
34
|
+
text
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/elasticated/client.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Elasticated
|
2
2
|
class Client
|
3
|
-
include Configurable
|
3
|
+
include Mixins::Configurable
|
4
4
|
|
5
5
|
attr_accessor :transport
|
6
6
|
|
@@ -41,7 +41,7 @@ module Elasticated
|
|
41
41
|
mapping = opts[:mapping]
|
42
42
|
body = Hash.new
|
43
43
|
body.merge!(settings: { number_of_shards: shards }) if shards
|
44
|
-
body.merge!(mappings: mapping) if mapping
|
44
|
+
body.merge!(mappings: mapping.to_h) if mapping # both Hash and Mapping::Builder responds to 'to_h'
|
45
45
|
args.merge! body: body unless body.empty?
|
46
46
|
log.info "Creating index '#{index_name}'"
|
47
47
|
transport.indices.create args
|
@@ -65,6 +65,10 @@ module Elasticated
|
|
65
65
|
log.info "Alias '#{index_alias}' removed from index '#{index_name}'"
|
66
66
|
end
|
67
67
|
|
68
|
+
def update_mapping(index_name, type_name, mapping, opts={})
|
69
|
+
transport.indices.put_mapping opts.merge(index: index_name, type: type_name, body: mapping)
|
70
|
+
end
|
71
|
+
|
68
72
|
def refresh_index(index_name)
|
69
73
|
transport.indices.refresh index: index_name
|
70
74
|
log.debug "Index '#{index_name}' refreshed"
|
@@ -95,11 +99,31 @@ module Elasticated
|
|
95
99
|
transport.scroll opts.merge scroll_id: scroll_id
|
96
100
|
end
|
97
101
|
|
98
|
-
def
|
102
|
+
def delete_by_query(body, opts={})
|
99
103
|
log_query :delete, body.to_json, opts
|
100
104
|
transport.delete_by_query opts.merge body: body
|
101
105
|
end
|
102
106
|
|
107
|
+
def get_document(document_id, opts={})
|
108
|
+
log_query :get, document_id, opts
|
109
|
+
transport.get opts.merge id: document_id
|
110
|
+
end
|
111
|
+
|
112
|
+
def get_documents(documents_ids, opts={})
|
113
|
+
log_query :mget, documents_ids, opts
|
114
|
+
transport.mget opts.merge body: { ids: documents_ids }
|
115
|
+
end
|
116
|
+
|
117
|
+
def delete_document(document_id, opts={})
|
118
|
+
log_query :delete, document_id, opts
|
119
|
+
transport.delete opts.merge id: document_id
|
120
|
+
end
|
121
|
+
|
122
|
+
def bulk(bulk_body, opts={})
|
123
|
+
log_query :bulk, bulk_body, opts
|
124
|
+
transport.bulk opts.merge body: bulk_body
|
125
|
+
end
|
126
|
+
|
103
127
|
protected
|
104
128
|
|
105
129
|
def log_query(query_type, message_body, query_opts={})
|
@@ -2,7 +2,7 @@ module Elasticated
|
|
2
2
|
module Conditions
|
3
3
|
class CustomCondition
|
4
4
|
|
5
|
-
include Inspectionable
|
5
|
+
include Mixins::Inspectionable
|
6
6
|
|
7
7
|
attr_accessor :body
|
8
8
|
|
@@ -14,8 +14,8 @@ module Elasticated
|
|
14
14
|
body
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
18
|
-
|
17
|
+
def fill_delimiter(field_delimiter)
|
18
|
+
# nothing to do
|
19
19
|
end
|
20
20
|
|
21
21
|
end
|
@@ -15,8 +15,11 @@ module Elasticated
|
|
15
15
|
{ range: { field => body }.merge(opts) }
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
19
|
-
|
18
|
+
def fill_delimiter(field_delimiter)
|
19
|
+
minimum_value = body[:gt] || body[:gte]
|
20
|
+
field_delimiter.set_minimum field, minimum_value
|
21
|
+
maximum_value = body[:lt] || body[:lte]
|
22
|
+
field_delimiter.set_maximum field, maximum_value
|
20
23
|
end
|
21
24
|
|
22
25
|
end
|
@@ -2,7 +2,7 @@ module Elasticated
|
|
2
2
|
module Conditions
|
3
3
|
class ScriptCondition
|
4
4
|
|
5
|
-
include Inspectionable
|
5
|
+
include Mixins::Inspectionable
|
6
6
|
|
7
7
|
attr_accessor :script, :params
|
8
8
|
|
@@ -17,8 +17,8 @@ module Elasticated
|
|
17
17
|
{ script: body }
|
18
18
|
end
|
19
19
|
|
20
|
-
def
|
21
|
-
|
20
|
+
def fill_delimiter(field_delimiter)
|
21
|
+
# nothing to do
|
22
22
|
end
|
23
23
|
|
24
24
|
end
|