elastic_adapter 0.0.3 → 0.0.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.
- checksums.yaml +4 -4
- data/lib/elastic_adapter.rb +11 -9
- data/lib/elastic_adapter/index.rb +6 -4
- data/lib/elastic_adapter/{decoration → responses}/aggregation_response.rb +7 -13
- data/lib/elastic_adapter/responses/base_response.rb +28 -0
- data/lib/elastic_adapter/responses/count_response.rb +13 -0
- data/lib/elastic_adapter/responses/get_response.rb +13 -0
- data/lib/elastic_adapter/{decoration → responses}/response_decorator_factory.rb +5 -23
- data/lib/elastic_adapter/responses/sanitized_response.rb +46 -0
- data/lib/elastic_adapter/responses/search_response.rb +21 -0
- data/lib/elastic_adapter/responses/suggestion_response.rb +46 -0
- data/lib/elastic_adapter/responses/validation_response.rb +18 -0
- data/lib/elastic_adapter/version.rb +1 -1
- data/spec/cassettes/ElasticAdapter_Index/_count/empty_index/is_a_fixnum.yml +30 -0
- data/spec/cassettes/ElasticAdapter_Index/_count/empty_index/number.yml +57 -0
- data/spec/cassettes/ElasticAdapter_Index/_count/not_empty_index/is_a_fixnum.yml +30 -0
- data/spec/cassettes/ElasticAdapter_Index/_get/document_exists.yml +3 -3
- data/spec/cassettes/ElasticAdapter_Index/_get/document_exists/response/{contains_the_document.yml → document/returns_the_document.yml} +1 -1
- data/spec/cassettes/ElasticAdapter_Index/_search.yml +16 -16
- data/spec/cassettes/ElasticAdapter_Index/_search/match_all/returns_all_documents.yml +2 -2
- data/spec/cassettes/ElasticAdapter_Index/_search/zoo/returns_one_document.yml +1 -1
- data/spec/cassettes/ElasticAdapter_Index/_search/zoo/returns_the_wanted_document.yml +2 -2
- data/spec/cassettes/ElasticAdapter_Index/_validate.yml +2 -2
- data/spec/cassettes/ElasticAdapter_Index/_validate/invalid_query/is_a_response.yml +1 -1
- data/spec/cassettes/ElasticAdapter_Index/_validate/invalid_query/{is_false.yml → valid_/is_false.yml} +1 -1
- data/spec/cassettes/ElasticAdapter_Index/_validate/valid_query/is_a_response.yml +1 -1
- data/spec/cassettes/ElasticAdapter_Index/_validate/valid_query/is_true.yml +1 -1
- data/spec/index/aggregation_spec.rb +1 -1
- data/spec/index/count_spec.rb +4 -4
- data/spec/index/get_spec.rb +4 -2
- data/spec/index/index_spec.rb +1 -1
- data/spec/index/search_spec.rb +4 -4
- data/spec/index/shared_examples.rb +2 -2
- data/spec/index/suggest_spec.rb +2 -3
- data/spec/index/validate_spec.rb +7 -5
- data/spec/{decoration → responses}/aggregation_response_spec.rb +1 -2
- data/spec/responses/base_response_spec.rb +19 -0
- data/spec/responses/count_response_spec.rb +24 -0
- data/spec/responses/get_response_spec.rb +29 -0
- data/spec/{decoration → responses}/response_decorator_factory_spec.rb +54 -6
- data/spec/responses/sanitized_response_spec.rb +36 -0
- data/spec/responses/search_response_spec.rb +43 -0
- data/spec/responses/suggestion_response_spec.rb +63 -0
- data/spec/responses/validation_response_spec.rb +45 -0
- metadata +38 -20
- data/lib/elastic_adapter/decoration/count_response.rb +0 -16
- data/lib/elastic_adapter/decoration/decorator.rb +0 -37
- data/lib/elastic_adapter/decoration/hit_decorator.rb +0 -25
- data/lib/elastic_adapter/decoration/search_response.rb +0 -27
- data/lib/elastic_adapter/decoration/suggestion_response.rb +0 -24
- data/lib/elastic_adapter/decoration/validation_response.rb +0 -15
- data/lib/elastic_adapter/response.rb +0 -51
- data/spec/response_spec.rb +0 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b73e1ccef696aa67e9fdb445fdad0233735e09f
|
4
|
+
data.tar.gz: 7798c15828d65100a7586084d0b04596fa27e8f5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 136c4240dfdc3cf631706b802960e42d4b73500c248635f7330791a744fc831dd6c6e27681f55f9a2869468fe0757dc18ebe499f0b4a0a384d5a4ae6a06e577b
|
7
|
+
data.tar.gz: c65ce37d0765ccee7222c746e9b7ffbbfa5817426bb427f1bc41a8de307c26ccfccef0b2f08b61f27815d6df165558a567048ef2e16c958eb2a4559d9f64fdca
|
data/lib/elastic_adapter.rb
CHANGED
@@ -2,15 +2,17 @@ require "elasticsearch"
|
|
2
2
|
|
3
3
|
require "elastic_adapter/version"
|
4
4
|
require "elastic_adapter/document_type"
|
5
|
-
|
6
|
-
require "elastic_adapter/
|
7
|
-
require "elastic_adapter/
|
8
|
-
require "elastic_adapter/
|
9
|
-
require "elastic_adapter/
|
10
|
-
require "elastic_adapter/
|
11
|
-
require "elastic_adapter/
|
12
|
-
require "elastic_adapter/
|
13
|
-
require "elastic_adapter/
|
5
|
+
|
6
|
+
require "elastic_adapter/responses/base_response"
|
7
|
+
require "elastic_adapter/responses/sanitized_response"
|
8
|
+
require "elastic_adapter/responses/aggregation_response"
|
9
|
+
require "elastic_adapter/responses/count_response"
|
10
|
+
require "elastic_adapter/responses/get_response"
|
11
|
+
require "elastic_adapter/responses/search_response"
|
12
|
+
require "elastic_adapter/responses/suggestion_response"
|
13
|
+
require "elastic_adapter/responses/validation_response"
|
14
|
+
require "elastic_adapter/responses/response_decorator_factory"
|
15
|
+
|
14
16
|
require "elastic_adapter/index"
|
15
17
|
|
16
18
|
begin
|
@@ -85,9 +85,11 @@ module ElasticAdapter
|
|
85
85
|
# @param [Hash] query a query to count the documents for a given query. Defaults to match all
|
86
86
|
# @return [Decoration::CountResponse] the count
|
87
87
|
def count(query = { query: { match_all: {} } })
|
88
|
-
handle_api_call :count do
|
88
|
+
response = handle_api_call :count do
|
89
89
|
client.count index: name, body: query
|
90
90
|
end
|
91
|
+
|
92
|
+
response.count || response
|
91
93
|
end
|
92
94
|
|
93
95
|
# Indexes a Hash or anything that responds to to_hash as a document
|
@@ -125,7 +127,7 @@ module ElasticAdapter
|
|
125
127
|
# @param [Integer] id
|
126
128
|
# @return [ElasticAdapter::HitDecorator]
|
127
129
|
def get(id)
|
128
|
-
handle_api_call :
|
130
|
+
handle_api_call :get do
|
129
131
|
client.get(
|
130
132
|
index: name,
|
131
133
|
type: document_type.name,
|
@@ -204,9 +206,9 @@ module ElasticAdapter
|
|
204
206
|
private
|
205
207
|
|
206
208
|
def handle_api_call(*args)
|
207
|
-
|
209
|
+
Responses::ResponseDecoratorFactory.decorate(yield, *args)
|
208
210
|
rescue Elasticsearch::Transport::Transport::Error => e
|
209
|
-
|
211
|
+
Responses::SanitizedResponse.new(
|
210
212
|
exception: e
|
211
213
|
)
|
212
214
|
end
|
@@ -1,20 +1,16 @@
|
|
1
1
|
module ElasticAdapter
|
2
|
-
module
|
3
|
-
|
4
|
-
#
|
5
|
-
# @attr_reader [Hash] aggregations
|
6
|
-
class AggregationResponse < Decorator
|
2
|
+
module Responses
|
3
|
+
class AggregationResponse < BaseResponse
|
7
4
|
attr_reader :aggregations
|
8
5
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
# @return [Hash]
|
13
|
-
def alter_object(hash)
|
6
|
+
private
|
7
|
+
|
8
|
+
def set_instance_variables
|
14
9
|
new_hash = {}
|
10
|
+
|
15
11
|
new_hash[:aggregations] = {}
|
16
12
|
|
17
|
-
|
13
|
+
object[:aggregations].each do |key, value|
|
18
14
|
new_hash[:aggregations][key] = []
|
19
15
|
|
20
16
|
value[:buckets].each do |agg|
|
@@ -26,8 +22,6 @@ module ElasticAdapter
|
|
26
22
|
end
|
27
23
|
|
28
24
|
@aggregations = new_hash[:aggregations]
|
29
|
-
|
30
|
-
new_hash
|
31
25
|
end
|
32
26
|
end
|
33
27
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "delegate"
|
2
|
+
|
3
|
+
module ElasticAdapter
|
4
|
+
module Responses
|
5
|
+
class BaseResponse < SimpleDelegator
|
6
|
+
def initialize(object)
|
7
|
+
__setobj__(object)
|
8
|
+
set_instance_variables
|
9
|
+
end
|
10
|
+
|
11
|
+
# Returns the underlaying object
|
12
|
+
#
|
13
|
+
# @return [Object] The underlaying object
|
14
|
+
def object
|
15
|
+
__getobj__
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
# This method is intended to set instance variables that provide
|
21
|
+
# access to values from the original object
|
22
|
+
#
|
23
|
+
# @param [Object] object
|
24
|
+
def set_instance_variables
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -1,22 +1,20 @@
|
|
1
1
|
module ElasticAdapter
|
2
|
-
module
|
3
|
-
# This class is used
|
4
|
-
# the decorator for responses returned by elasticsearch
|
2
|
+
module Responses
|
3
|
+
# This class is used to decorate responses
|
5
4
|
#
|
6
|
-
# @see Response#decorate
|
7
5
|
class ResponseDecoratorFactory
|
8
6
|
class << self
|
9
|
-
# Takes a response and multiple symbols and
|
7
|
+
# Takes a response and multiple symbols and decorates the response.
|
10
8
|
#
|
11
9
|
# @param [Hash] response a response returned by elasticsearch
|
12
10
|
# @param [Array<Symbol>] args the decorators the response should be decorated with.
|
13
11
|
# Currently valid args are :count, :hit, :search, :validation, :suggestion
|
14
12
|
# @return [Docorator] a decorated response
|
15
13
|
def decorate(plain_response, *args)
|
16
|
-
response =
|
14
|
+
response = SanitizedResponse.new(plain_response)
|
17
15
|
|
18
16
|
response = CountResponse.new(response) if args.include? :count
|
19
|
-
response =
|
17
|
+
response = GetResponse.new(response) if args.include? :get
|
20
18
|
response = SearchResponse.new(response) if args.include? :search
|
21
19
|
response = ValidationResponse.new(response) if args.include? :validation
|
22
20
|
response = SuggestionResponse.new(response) if args.include? :suggestion
|
@@ -24,22 +22,6 @@ module ElasticAdapter
|
|
24
22
|
|
25
23
|
response
|
26
24
|
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
# Checks if the passed response is a response
|
31
|
-
# from the elasticsearch suggest api
|
32
|
-
#
|
33
|
-
# @param [Hash] response
|
34
|
-
# @return [Boolean]
|
35
|
-
def suggestion?(response)
|
36
|
-
second_key = response[response.keys[1]]
|
37
|
-
return false unless second_key.is_a? Array
|
38
|
-
return false if second_key.empty?
|
39
|
-
return false unless second_key.first.is_a? Hash
|
40
|
-
return false unless second_key.first.key? :options
|
41
|
-
true
|
42
|
-
end
|
43
25
|
end
|
44
26
|
end
|
45
27
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module ElasticAdapter
|
2
|
+
module Responses
|
3
|
+
class SanitizedResponse < BaseResponse
|
4
|
+
def initialize(object)
|
5
|
+
super(deep_sanitize_object(object))
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def deep_sanitize_object(object)
|
11
|
+
if object.is_a? Hash
|
12
|
+
return sanitize_hash(object)
|
13
|
+
elsif object.is_a? Array
|
14
|
+
return sanitize_array(object)
|
15
|
+
else
|
16
|
+
return object
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def sanitize_hash(hash)
|
21
|
+
result = {}
|
22
|
+
|
23
|
+
hash.each do |key, value|
|
24
|
+
new_key = remove_leading_underscore(key).to_sym
|
25
|
+
|
26
|
+
if value.is_a?(Hash)
|
27
|
+
result[new_key] = sanitize_hash(value)
|
28
|
+
else
|
29
|
+
result[new_key] = deep_sanitize_object(value)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
result
|
34
|
+
end
|
35
|
+
|
36
|
+
def sanitize_array(array)
|
37
|
+
array.map { |element| deep_sanitize_object(element) }
|
38
|
+
end
|
39
|
+
|
40
|
+
def remove_leading_underscore(string)
|
41
|
+
/^_?(.*)$/.match(string)[1]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ElasticAdapter
|
2
|
+
module Responses
|
3
|
+
class SearchResponse < BaseResponse
|
4
|
+
attr_reader :hits
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def set_instance_variables
|
9
|
+
hits = []
|
10
|
+
object[:hits][:hits].each do |hit|
|
11
|
+
hits << {
|
12
|
+
id: hit[:id]
|
13
|
+
}.merge(hit[:source])
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
@hits = hits
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module ElasticAdapter
|
2
|
+
module Responses
|
3
|
+
class SuggestionResponse < BaseResponse
|
4
|
+
# This class represents a search term and it's
|
5
|
+
# suggested options
|
6
|
+
class TermSuggestion
|
7
|
+
attr_reader :text, :options
|
8
|
+
|
9
|
+
def initialize(params)
|
10
|
+
@text = params[:text]
|
11
|
+
@options = params[:options]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# This class represents a single named suggestion
|
16
|
+
# returned by elaticsearch
|
17
|
+
class Suggestion
|
18
|
+
attr_reader :name, :terms
|
19
|
+
|
20
|
+
def initialize(name, suggestions)
|
21
|
+
@name = name
|
22
|
+
@terms = []
|
23
|
+
|
24
|
+
suggestions.each do |suggestion_per_term|
|
25
|
+
@terms << TermSuggestion.new(suggestion_per_term)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_reader :suggestions
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def set_instance_variables
|
35
|
+
@suggestions = []
|
36
|
+
|
37
|
+
object_without_shards = object.reject { |key, value| key == :shards}
|
38
|
+
object_without_shards.each do |key, value|
|
39
|
+
# In this context key is the named suggestion
|
40
|
+
# returned by elasticsearch
|
41
|
+
@suggestions << Suggestion.new(key, value)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module ElasticAdapter
|
2
|
+
module Responses
|
3
|
+
class ValidationResponse < BaseResponse
|
4
|
+
attr_reader :explanations, :valid
|
5
|
+
|
6
|
+
def valid?
|
7
|
+
valid
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def set_instance_variables
|
13
|
+
@valid = object[:valid]
|
14
|
+
@explanations = object[:explanations]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://localhost:9200/test_index/_count
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: '{"query":{"match_all":{}}}'
|
9
|
+
headers:
|
10
|
+
User-Agent:
|
11
|
+
- Faraday v0.9.1
|
12
|
+
Accept-Encoding:
|
13
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
14
|
+
Accept:
|
15
|
+
- "*/*"
|
16
|
+
response:
|
17
|
+
status:
|
18
|
+
code: 404
|
19
|
+
message: Not Found
|
20
|
+
headers:
|
21
|
+
Content-Type:
|
22
|
+
- application/json; charset=UTF-8
|
23
|
+
Content-Length:
|
24
|
+
- '68'
|
25
|
+
body:
|
26
|
+
encoding: UTF-8
|
27
|
+
string: '{"error":"IndexMissingException[[test_index] missing]","status":404}'
|
28
|
+
http_version:
|
29
|
+
recorded_at: Mon, 09 Mar 2015 18:08:20 GMT
|
30
|
+
recorded_with: VCR 2.9.3
|
@@ -0,0 +1,57 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://localhost:9200/test_index/_count
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: '{"query":{"match_all":{}}}'
|
9
|
+
headers:
|
10
|
+
User-Agent:
|
11
|
+
- Faraday v0.9.1
|
12
|
+
Accept-Encoding:
|
13
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
14
|
+
Accept:
|
15
|
+
- "*/*"
|
16
|
+
response:
|
17
|
+
status:
|
18
|
+
code: 404
|
19
|
+
message: Not Found
|
20
|
+
headers:
|
21
|
+
Content-Type:
|
22
|
+
- application/json; charset=UTF-8
|
23
|
+
Content-Length:
|
24
|
+
- '68'
|
25
|
+
body:
|
26
|
+
encoding: UTF-8
|
27
|
+
string: '{"error":"IndexMissingException[[test_index] missing]","status":404}'
|
28
|
+
http_version:
|
29
|
+
recorded_at: Mon, 09 Mar 2015 18:08:00 GMT
|
30
|
+
- request:
|
31
|
+
method: get
|
32
|
+
uri: http://localhost:9200/test_index/_count
|
33
|
+
body:
|
34
|
+
encoding: UTF-8
|
35
|
+
string: '{"query":{"match_all":{}}}'
|
36
|
+
headers:
|
37
|
+
User-Agent:
|
38
|
+
- Faraday v0.9.1
|
39
|
+
Accept-Encoding:
|
40
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
41
|
+
Accept:
|
42
|
+
- "*/*"
|
43
|
+
response:
|
44
|
+
status:
|
45
|
+
code: 404
|
46
|
+
message: Not Found
|
47
|
+
headers:
|
48
|
+
Content-Type:
|
49
|
+
- application/json; charset=UTF-8
|
50
|
+
Content-Length:
|
51
|
+
- '68'
|
52
|
+
body:
|
53
|
+
encoding: UTF-8
|
54
|
+
string: '{"error":"IndexMissingException[[test_index] missing]","status":404}'
|
55
|
+
http_version:
|
56
|
+
recorded_at: Mon, 09 Mar 2015 18:08:02 GMT
|
57
|
+
recorded_with: VCR 2.9.3
|