stretcher 1.3.2 → 1.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/stretcher.rb +2 -0
- data/lib/stretcher/es_component.rb +24 -0
- data/lib/stretcher/index.rb +16 -28
- data/lib/stretcher/index_type.rb +11 -10
- data/lib/stretcher/search_results.rb +5 -5
- data/lib/stretcher/server.rb +19 -19
- data/lib/stretcher/version.rb +1 -1
- data/spec/lib/stretcher_index_spec.rb +10 -10
- data/spec/lib/stretcher_index_type_spec.rb +13 -8
- data/spec/lib/stretcher_server_spec.rb +3 -3
- metadata +3 -2
data/lib/stretcher.rb
CHANGED
@@ -5,6 +5,8 @@ require 'faraday'
|
|
5
5
|
require 'faraday_middleware'
|
6
6
|
require "stretcher/version"
|
7
7
|
require 'stretcher/request_error'
|
8
|
+
require 'stretcher/search_results'
|
9
|
+
require 'stretcher/es_component'
|
8
10
|
require 'stretcher/server'
|
9
11
|
require 'stretcher/index'
|
10
12
|
require 'stretcher/index_type'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Stretcher
|
2
|
+
# Elasticsearch has symmetry across API endpoints for Server, Index, and Type, lets try and provide some common ground
|
3
|
+
class EsComponent
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
def do_search(generic_opts={}, explicit_body=nil)
|
8
|
+
uri_str = '/_search'
|
9
|
+
body = nil
|
10
|
+
if explicit_body
|
11
|
+
uri_str << '?' + Util.querify(generic_opts)
|
12
|
+
body = explicit_body
|
13
|
+
else
|
14
|
+
body = generic_opts
|
15
|
+
end
|
16
|
+
|
17
|
+
logger.info { "Stretcher Search: curl -XGET '#{uri_str}' -d '#{body.to_json}'" }
|
18
|
+
response = @server.request(:get, path_uri(uri_str)) do |req|
|
19
|
+
req.body = body
|
20
|
+
end
|
21
|
+
SearchResults.new(:raw => response)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/stretcher/index.rb
CHANGED
@@ -2,9 +2,9 @@ require 'stretcher/search_results'
|
|
2
2
|
module Stretcher
|
3
3
|
# Represents an Index context in elastic search.
|
4
4
|
# Generally should be instantiated via Server#index(name).
|
5
|
-
class Index
|
5
|
+
class Index < EsComponent
|
6
6
|
attr_reader :server, :name, :logger
|
7
|
-
|
7
|
+
|
8
8
|
def initialize(server, name, options={})
|
9
9
|
@server = server
|
10
10
|
@name = name
|
@@ -14,14 +14,14 @@ module Stretcher
|
|
14
14
|
# Returns a Stretcher::IndexType object for the type +name+.
|
15
15
|
# Optionally takes a block, which will be passed a single arg with the Index obj
|
16
16
|
# The block syntax returns the evaluated value of the block
|
17
|
-
#
|
17
|
+
#
|
18
18
|
# my_index.index(:foo) # => #<Stretcher::Index ...>
|
19
19
|
# my_index.index(:foo) {|idx| 1+1} # => 2
|
20
20
|
def type(name, &block)
|
21
21
|
t = IndexType.new(self, name)
|
22
22
|
block ? block.call(t) : t
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
# Given a hash of documents, will bulk index
|
26
26
|
#
|
27
27
|
# docs = [{"_type" => "tweet", "_id" => 91011, "text" => "Bulked"}]
|
@@ -42,7 +42,7 @@ module Stretcher
|
|
42
42
|
req.body = options
|
43
43
|
end
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
# Deletes the index
|
47
47
|
def delete
|
48
48
|
@server.request :delete, path_uri
|
@@ -52,27 +52,27 @@ module Stretcher
|
|
52
52
|
def stats
|
53
53
|
@server.request :get, path_uri("/_stats")
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
# Retrieves status for this index
|
57
57
|
def status
|
58
|
-
@server.request :get, path_uri("/_status")
|
58
|
+
@server.request :get, path_uri("/_status")
|
59
59
|
end
|
60
|
-
|
60
|
+
|
61
61
|
# Retrieve the mapping for this index
|
62
62
|
def get_mapping
|
63
63
|
@server.request :get, path_uri("/_mapping")
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
# Retrieve settings for this index
|
67
67
|
def get_settings
|
68
68
|
@server.request :get, path_uri("/_settings")
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
# Check if the index has been created on the remote server
|
72
72
|
def exists?
|
73
73
|
@server.http.head(path_uri).status != 404
|
74
74
|
end
|
75
|
-
|
75
|
+
|
76
76
|
# Issues a search with the given query opts and body, both should be hashes
|
77
77
|
#
|
78
78
|
# res = server.index('foo').search(size: 12, {query: {match_all: {}}})
|
@@ -82,22 +82,10 @@ module Stretcher
|
|
82
82
|
# res.results # => [#<Hashie::Mash _id="123" text="Hello">]
|
83
83
|
# res.raw # => #<Hashie::Mash ...> Raw JSON from the search
|
84
84
|
def search(generic_opts={}, explicit_body=nil)
|
85
|
-
|
86
|
-
|
87
|
-
if explicit_body
|
88
|
-
uri_str << '?' + Util.querify(generic_opts)
|
89
|
-
body = explicit_body
|
90
|
-
else
|
91
|
-
body = generic_opts
|
92
|
-
end
|
93
|
-
|
94
|
-
logger.info { "Stretcher Search: curl -XGET '#{uri_str}' -d '#{body.to_json}'" }
|
95
|
-
response = @server.request(:get, path_uri(uri_str)) do |req|
|
96
|
-
req.body = body
|
97
|
-
end
|
98
|
-
SearchResults.new(raw: response)
|
85
|
+
# Written this way to be more RDoc friendly
|
86
|
+
do_search(generic_opts, explicit_body)
|
99
87
|
end
|
100
|
-
|
88
|
+
|
101
89
|
# Searches a list of queries against only this index
|
102
90
|
# This deviates slightly from the official API in that *ONLY*
|
103
91
|
# queries are requried, the empty {} preceding them are not
|
@@ -108,7 +96,7 @@ module Stretcher
|
|
108
96
|
def msearch(queries=[])
|
109
97
|
raise ArgumentError, "msearch takes an array!" unless queries.is_a?(Array)
|
110
98
|
req_body = queries.reduce([]) {|acc,q|
|
111
|
-
acc << {index
|
99
|
+
acc << {:index => name}
|
112
100
|
acc << q
|
113
101
|
acc
|
114
102
|
}
|
@@ -116,7 +104,7 @@ module Stretcher
|
|
116
104
|
end
|
117
105
|
|
118
106
|
# Implements the Analyze API
|
119
|
-
# EX:
|
107
|
+
# EX:
|
120
108
|
# index.analyze("Candles", analyzer: :snowball)
|
121
109
|
# # => #<Hashie::Mash tokens=[#<Hashie::Mash end_offset=7 position=1 start_offset=0 token="candl" type="<ALPHANUM>">]>
|
122
110
|
def analyze(text, analysis_params)
|
data/lib/stretcher/index_type.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
module Stretcher
|
2
2
|
# Represents an index scoped to a specific type.
|
3
3
|
# Generally should be instantiated via Index#type(name).
|
4
|
-
class IndexType
|
4
|
+
class IndexType < EsComponent
|
5
5
|
attr_reader :server, :index, :name, :logger
|
6
|
-
|
6
|
+
|
7
7
|
def initialize(index, name, options={})
|
8
8
|
@index = index
|
9
9
|
@server = index.server
|
@@ -17,12 +17,12 @@ module Stretcher
|
|
17
17
|
res = server.request(:get, path_uri("/#{id}"))
|
18
18
|
raw ? res : res["_source"]
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
# Index an item with a specific ID
|
22
22
|
def put(id, source)
|
23
23
|
server.request(:put, path_uri("/#{id}"), source)
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
# Uses the update api to modify a document with a script
|
27
27
|
# To update a doc with ID 987 for example:
|
28
28
|
# type.update(987, script: "ctx._source.message = 'Updated!'")
|
@@ -30,11 +30,11 @@ module Stretcher
|
|
30
30
|
def update(id, body)
|
31
31
|
server.request(:post, path_uri("/#{id}/_update"), body)
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
# Deletes the document with the given ID
|
35
35
|
def delete(id)
|
36
36
|
res = server.http.delete path_uri("/#{id}")
|
37
|
-
|
37
|
+
|
38
38
|
# Since 404s are just not a problem here, let's simply return false
|
39
39
|
if res.status == 404
|
40
40
|
false
|
@@ -49,7 +49,7 @@ module Stretcher
|
|
49
49
|
def get_mapping
|
50
50
|
@server.request :get, path_uri("/_mapping")
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
# Delete the mapping for this type. Note this will delete
|
54
54
|
# All documents of this type as well
|
55
55
|
# http://www.elasticsearch.org/guide/reference/api/admin-indices-delete-mapping.html
|
@@ -63,7 +63,7 @@ module Stretcher
|
|
63
63
|
req.body = body
|
64
64
|
}
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
# Check if this index type is defined, if passed an id
|
68
68
|
# this will check if the given document exists
|
69
69
|
def exists?(id=nil)
|
@@ -72,8 +72,9 @@ module Stretcher
|
|
72
72
|
|
73
73
|
# Issues an Index#search scoped to this type
|
74
74
|
# See Index#search for more details
|
75
|
-
def search(generic_opts={},
|
76
|
-
|
75
|
+
def search(generic_opts={}, explicit_body=nil)
|
76
|
+
# Written this way to be more RDoc friendly
|
77
|
+
do_search(generic_opts, explicit_body)
|
77
78
|
end
|
78
79
|
|
79
80
|
# Full path to this index type
|
@@ -1,25 +1,25 @@
|
|
1
1
|
require 'hashie/dash'
|
2
2
|
module Stretcher
|
3
3
|
# Conveniently represents elastic search results in a more compact fashion
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# Available properties:
|
6
|
-
#
|
6
|
+
#
|
7
7
|
# * raw : The raw response from elastic search
|
8
8
|
# * total : The total number of matched docs
|
9
9
|
# * facets : the facets hash
|
10
10
|
# * results : The hit results with _id merged in to _source
|
11
11
|
class SearchResults < Hashie::Dash
|
12
|
-
property :raw, required
|
12
|
+
property :raw, :required => true
|
13
13
|
property :total
|
14
14
|
property :facets
|
15
15
|
property :results
|
16
|
-
|
16
|
+
|
17
17
|
def initialize(*args)
|
18
18
|
super
|
19
19
|
self.total = raw.hits.total
|
20
20
|
self.facets = raw.facets
|
21
21
|
self.results = raw.hits.hits.collect {|r|
|
22
|
-
r['_source'].merge({"_id" => r['_id']})
|
22
|
+
(r.has_key?('_source') ? r['_source'] : r['fields']).merge({"_id" => r['_id']})
|
23
23
|
}
|
24
24
|
end
|
25
25
|
end
|
data/lib/stretcher/server.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Stretcher
|
2
|
-
class Server
|
2
|
+
class Server < EsComponent
|
3
3
|
attr_reader :uri, :http, :logger
|
4
4
|
|
5
5
|
# Instantiate a new instance in a manner convenient for using the block syntax.
|
@@ -9,7 +9,7 @@ module Stretcher
|
|
9
9
|
s = self.new(*args)
|
10
10
|
yield s
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
# Represents a Server context in elastic search.
|
14
14
|
# Use +with_server+ when you want to use the block syntax.
|
15
15
|
# The options hash takes an optional instance of Logger under :logger.
|
@@ -18,25 +18,25 @@ module Stretcher
|
|
18
18
|
def initialize(uri='http://localhost:9200', options={})
|
19
19
|
@uri = uri
|
20
20
|
|
21
|
-
@http = Faraday.new(:url => @uri) do |builder|
|
21
|
+
@http = Faraday.new(:url => @uri) do |builder|
|
22
22
|
builder.response :mashify
|
23
23
|
builder.response :json, :content_type => /\bjson$/
|
24
|
-
|
24
|
+
|
25
25
|
builder.request :json
|
26
|
-
|
26
|
+
|
27
27
|
builder.adapter :net_http_persistent
|
28
|
-
|
28
|
+
|
29
29
|
builder.options[:read_timeout] = 4
|
30
30
|
builder.options[:open_timeout] = 2
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
if options[:logger]
|
34
34
|
@logger = options[:logger]
|
35
35
|
else
|
36
36
|
@logger = Logger.new(STDOUT)
|
37
37
|
@logger.level = Logger::WARN
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
@logger.formatter = proc do |severity, datetime, progname, msg|
|
41
41
|
"[Stretcher][#{severity}]: #{msg}\n"
|
42
42
|
end
|
@@ -45,11 +45,11 @@ module Stretcher
|
|
45
45
|
# Returns a Stretcher::Index object for the index +name+.
|
46
46
|
# Optionally takes a block, which will be passed a single arg with the Index obj
|
47
47
|
# The block syntax returns the evaluated value of the block
|
48
|
-
#
|
48
|
+
#
|
49
49
|
# my_server.index(:foo) # => #<Stretcher::Index ...>
|
50
50
|
# my_server.index(:foo) {|idx| 1+1} # => 2
|
51
51
|
def index(name, &block)
|
52
|
-
idx = Index.new(self, name, logger
|
52
|
+
idx = Index.new(self, name, :logger => logger)
|
53
53
|
block ? block.call(idx) : idx
|
54
54
|
end
|
55
55
|
|
@@ -68,13 +68,13 @@ module Stretcher
|
|
68
68
|
def status
|
69
69
|
request :get, path_uri("/_status")
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
# Returns true if the server is currently reachable, raises an error otherwise
|
73
73
|
def up?
|
74
74
|
request(:get, path_uri)
|
75
75
|
true
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
# Takes an array of msearch data as per
|
79
79
|
# http://www.elasticsearch.org/guide/reference/api/multi-search.html
|
80
80
|
# Should look something like:
|
@@ -92,13 +92,13 @@ module Stretcher
|
|
92
92
|
res = request(:get, path_uri("/_msearch")) {|req|
|
93
93
|
req.body = fmt_body
|
94
94
|
}
|
95
|
-
|
95
|
+
|
96
96
|
errors = res.responses.select {|r| r[:error]}.map(&:error)
|
97
97
|
if !errors.empty?
|
98
|
-
raise RequestError.new(res), "Could not msearch #{errors.inspect}"
|
98
|
+
raise RequestError.new(res), "Could not msearch #{errors.inspect}"
|
99
99
|
end
|
100
|
-
|
101
|
-
res['responses'].map {|r| SearchResults.new(raw
|
100
|
+
|
101
|
+
res['responses'].map {|r| SearchResults.new(:raw => r)}
|
102
102
|
end
|
103
103
|
|
104
104
|
# Retrieves multiple documents, possibly from multiple indexes
|
@@ -108,9 +108,9 @@ module Stretcher
|
|
108
108
|
req.body = body
|
109
109
|
}
|
110
110
|
end
|
111
|
-
|
111
|
+
|
112
112
|
# Implements the Analyze API
|
113
|
-
# EX:
|
113
|
+
# EX:
|
114
114
|
# server.analyze("Candles", analyzer: :snowball)
|
115
115
|
# # => #<Hashie::Mash tokens=[#<Hashie::Mash end_offset=7 position=1 start_offset=0 token="candl" type="<ALPHANUM>">]>
|
116
116
|
# as per: http://www.elasticsearch.org/guide/reference/api/admin-indices-analyze.html
|
@@ -128,7 +128,7 @@ module Stretcher
|
|
128
128
|
# Handy way to query the server, returning *only* the body
|
129
129
|
# Will raise an exception when the status is not in the 2xx range
|
130
130
|
def request(method, *args, &block)
|
131
|
-
logger.info { "Stretcher: Issuing Request #{method.upcase}, #{args}" }
|
131
|
+
logger.info { "Stretcher: Issuing Request #{method.to_s.upcase}, #{args}" }
|
132
132
|
res = if block
|
133
133
|
http.send(method, *args) do |req|
|
134
134
|
# Elastic search does mostly deal with JSON
|
data/lib/stretcher/version.rb
CHANGED
@@ -2,19 +2,19 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Stretcher::Index do
|
4
4
|
let(:server) {
|
5
|
-
Stretcher::Server.new(ES_URL, logger
|
5
|
+
Stretcher::Server.new(ES_URL, :logger => DEBUG_LOGGER)
|
6
6
|
}
|
7
7
|
let(:index) { server.index('foo') }
|
8
8
|
let(:corpus) {
|
9
9
|
[
|
10
|
-
{text
|
11
|
-
{text
|
12
|
-
{text
|
10
|
+
{:text => "Foo", "_type" => 'tweet', "_id" => 'fooid'},
|
11
|
+
{:text => "Bar", "_type" => 'tweet', "_id" => 'barid'},
|
12
|
+
{:text => "Baz", "_type" => 'tweet', "id" => 'bazid'} # Note we support both _id and id
|
13
13
|
]
|
14
14
|
}
|
15
15
|
|
16
16
|
def create_tweet_mapping
|
17
|
-
mdata = {tweet:
|
17
|
+
mdata = {:tweet => {:properties => {:text => {:type => :string}}}}
|
18
18
|
index.type('tweet').put_mapping(mdata)
|
19
19
|
end
|
20
20
|
|
@@ -22,7 +22,7 @@ describe Stretcher::Index do
|
|
22
22
|
create_tweet_mapping
|
23
23
|
index.bulk_index(corpus)
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
it "should work on an existential level" do
|
27
27
|
index.delete rescue nil
|
28
28
|
index.exists?.should be_false
|
@@ -67,26 +67,26 @@ describe Stretcher::Index do
|
|
67
67
|
seed_corpus
|
68
68
|
match_text = corpus.first[:text]
|
69
69
|
sleep 1 # ES needs time to update!
|
70
|
-
res = index.search({}, {query
|
70
|
+
res = index.search({}, {:query => {:match => {:text => match_text}}})
|
71
71
|
res.results.first.text.should == match_text
|
72
72
|
end
|
73
73
|
|
74
74
|
# TODO: Actually use two indexes
|
75
75
|
it "should msearch across the index returning all docs" do
|
76
76
|
seed_corpus
|
77
|
-
res = index.msearch([{query
|
77
|
+
res = index.msearch([{:query => {:match_all => {}}}])
|
78
78
|
res.length.should == 1
|
79
79
|
res[0].class.should == Stretcher::SearchResults
|
80
80
|
end
|
81
81
|
|
82
82
|
it "execute the analysis API and return an expected result" do
|
83
|
-
analyzed = index.analyze("Candles", analyzer
|
83
|
+
analyzed = index.analyze("Candles", :analyzer => :snowball)
|
84
84
|
analyzed.tokens.first.token.should == 'candl'
|
85
85
|
end
|
86
86
|
|
87
87
|
it "should raise an exception when msearching a non-existant index" do
|
88
88
|
lambda {
|
89
|
-
res = server.index(:does_not_exist).msearch([{query
|
89
|
+
res = server.index(:does_not_exist).msearch([{:query => {:match_all => {}}}])
|
90
90
|
}.should raise_exception(Stretcher::RequestError)
|
91
91
|
end
|
92
92
|
end
|
@@ -16,27 +16,32 @@ describe Stretcher::Index do
|
|
16
16
|
|
17
17
|
describe "searching" do
|
18
18
|
before do
|
19
|
-
@doc = {message
|
19
|
+
@doc = {:message => "hello"}
|
20
20
|
end
|
21
21
|
|
22
22
|
it "should search and find the right doc" do
|
23
23
|
match_text = 'hello'
|
24
24
|
type.put(123123, @doc)
|
25
25
|
sleep 1
|
26
|
-
res = type.search({}, {query
|
26
|
+
res = type.search({}, {:query => {:match => {:message => match_text}}})
|
27
|
+
res.results.first.message.should == @doc[:message]
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should build results when _source is not included in loaded fields" do
|
31
|
+
res = type.search({}, {query: {match_all: {}}, fields: ['message']})
|
27
32
|
res.results.first.message.should == @doc[:message]
|
28
33
|
end
|
29
34
|
end
|
30
35
|
|
31
36
|
describe "put/get" do
|
32
37
|
before do
|
33
|
-
@doc = {message
|
38
|
+
@doc = {:message => "hello!"}
|
34
39
|
end
|
35
|
-
|
40
|
+
|
36
41
|
it "should put correctly" do
|
37
42
|
type.put(987, @doc).should_not be_nil
|
38
43
|
end
|
39
|
-
|
44
|
+
|
40
45
|
it "should get individual documents correctly" do
|
41
46
|
type.get(987).message.should == @doc[:message]
|
42
47
|
end
|
@@ -48,14 +53,14 @@ describe Stretcher::Index do
|
|
48
53
|
end
|
49
54
|
|
50
55
|
it "should update individual docs correctly" do
|
51
|
-
type.update(987, script
|
56
|
+
type.update(987, :script => "ctx._source.message = 'Updated!'")
|
52
57
|
type.get(987).message.should == 'Updated!'
|
53
58
|
end
|
54
|
-
|
59
|
+
|
55
60
|
it "should delete individual docs correctly" do
|
56
61
|
type.exists?(987).should be_true
|
57
62
|
type.delete(987)
|
58
|
-
type.exists?(987).should be_false
|
63
|
+
type.exists?(987).should be_false
|
59
64
|
end
|
60
65
|
end
|
61
66
|
end
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Stretcher::Server do
|
4
4
|
let(:server) { Stretcher::Server.new(ES_URL) }
|
5
|
-
|
5
|
+
|
6
6
|
it "should initialize cleanly" do
|
7
7
|
server.class.should == Stretcher::Server
|
8
8
|
end
|
@@ -28,7 +28,7 @@ describe Stretcher::Server do
|
|
28
28
|
it "should check the status w/o error" do
|
29
29
|
server.status.ok.should be_true
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
it "should beget an index object cleanly" do
|
33
33
|
server.index('foo').class.should == Stretcher::Index
|
34
34
|
end
|
@@ -44,7 +44,7 @@ describe Stretcher::Server do
|
|
44
44
|
end
|
45
45
|
|
46
46
|
it "execute the analysis API and return an expected result" do
|
47
|
-
analyzed = server.analyze("Candles", analyzer
|
47
|
+
analyzed = server.analyze("Candles", :analyzer => :snowball)
|
48
48
|
analyzed.tokens.first.token.should == 'candl'
|
49
49
|
end
|
50
50
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stretcher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-03-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: faraday
|
@@ -152,6 +152,7 @@ files:
|
|
152
152
|
- README.md
|
153
153
|
- Rakefile
|
154
154
|
- lib/stretcher.rb
|
155
|
+
- lib/stretcher/es_component.rb
|
155
156
|
- lib/stretcher/index.rb
|
156
157
|
- lib/stretcher/index_type.rb
|
157
158
|
- lib/stretcher/request_error.rb
|