stretcher 1.3.3 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -91,6 +91,13 @@ The test suite is not to be trusted, don't count on your indexes staying around!
91
91
 
92
92
  Specs may be run with `rake spec`
93
93
 
94
+ ## Contributors
95
+
96
+ * @andrewvc
97
+ * @psynix
98
+ * @fmardini
99
+ * @chatgris
100
+
94
101
  ## Contributing
95
102
 
96
103
  1. Fork it
@@ -2,23 +2,36 @@ module Stretcher
2
2
  # Elasticsearch has symmetry across API endpoints for Server, Index, and Type, lets try and provide some common ground
3
3
  class EsComponent
4
4
 
5
+ # Many of the methods marked protected are called by one line shims in subclasses. This is mostly to facilitate
6
+ # better looking rdocs
7
+
5
8
  private
6
9
 
7
10
  def do_search(generic_opts={}, explicit_body=nil)
8
- uri_str = '/_search'
11
+ query_opts = {}
9
12
  body = nil
10
13
  if explicit_body
11
- uri_str << '?' + Util.querify(generic_opts)
14
+ query_opts = generic_opts
12
15
  body = explicit_body
13
16
  else
14
17
  body = generic_opts
15
18
  end
16
19
 
17
- logger.info { "Stretcher Search: curl -XGET '#{uri_str}' -d '#{body.to_json}'" }
18
- response = @server.request(:get, path_uri(uri_str)) do |req|
20
+ logger.info { "Stretcher Search: curl -XGET '#{Util.qurl(path_uri('_search'), query_opts)}' -d '#{body.to_json}'" }
21
+ response = request(:get, "_search", query_opts) do |req|
19
22
  req.body = body
20
23
  end
21
24
  SearchResults.new(:raw => response)
22
25
  end
26
+
27
+ def do_refresh
28
+ request(:post, "_refresh")
29
+ end
30
+
31
+ def request(method, path=nil, query_opts=nil, *args, &block)
32
+ prefixed_path = path_uri(path)
33
+ raise "Cannot issue request, no server specified!" unless @server
34
+ @server.request(method, prefixed_path, query_opts, *args, &block)
35
+ end
23
36
  end
24
37
  end
@@ -38,39 +38,44 @@ module Stretcher
38
38
 
39
39
  # Creates the index, with the supplied hash as the optinos body (usually mappings: and settings:))
40
40
  def create(options={})
41
- @server.request(:put, path_uri) do |req|
41
+ request(:put) do |req|
42
42
  req.body = options
43
43
  end
44
44
  end
45
45
 
46
46
  # Deletes the index
47
47
  def delete
48
- @server.request :delete, path_uri
48
+ request :delete
49
49
  end
50
50
 
51
51
  # Retrieves stats for this index
52
52
  def stats
53
- @server.request :get, path_uri("/_stats")
53
+ request :get, "_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
+ request :get, "_status"
59
59
  end
60
60
 
61
61
  # Retrieve the mapping for this index
62
62
  def get_mapping
63
- @server.request :get, path_uri("/_mapping")
63
+ request :get, "_mapping"
64
64
  end
65
65
 
66
66
  # Retrieve settings for this index
67
67
  def get_settings
68
- @server.request :get, path_uri("/_settings")
68
+ request :get, "_settings"
69
69
  end
70
70
 
71
71
  # Check if the index has been created on the remote server
72
72
  def exists?
73
- @server.http.head(path_uri).status != 404
73
+ # Unless the exception is hit we know its a 2xx response
74
+ request(:head)
75
+ true
76
+ rescue Stretcher::RequestError => e
77
+ raise e if e.http_response.status != 404
78
+ false
74
79
  end
75
80
 
76
81
  # Issues a search with the given query opts and body, both should be hashes
@@ -108,14 +113,20 @@ module Stretcher
108
113
  # index.analyze("Candles", analyzer: :snowball)
109
114
  # # => #<Hashie::Mash tokens=[#<Hashie::Mash end_offset=7 position=1 start_offset=0 token="candl" type="<ALPHANUM>">]>
110
115
  def analyze(text, analysis_params)
111
- @server.request(:get, path_uri("/_analyze"), analysis_params) do |req|
116
+ request(:get, "_analyze", analysis_params) do |req|
112
117
  req.body = text
113
118
  end
114
119
  end
120
+
121
+ # Perform a refresh making all items in this index available instantly
122
+ def refresh
123
+ do_refresh
124
+ end
115
125
 
116
126
  # Full path to this index
117
127
  def path_uri(path="/")
118
- @server.path_uri("/#{name}") + path.to_s
128
+ p = @server.path_uri("/#{name}")
129
+ path ? p << "/#{path}" : p
119
130
  end
120
131
  end
121
132
  end
@@ -14,13 +14,13 @@ module Stretcher
14
14
  # Retrieves the document by ID
15
15
  # Normally this returns the contents of _source, however, the 'raw' flag is passed in, it will return the full response hash
16
16
  def get(id, raw=false)
17
- res = server.request(:get, path_uri("/#{id}"))
17
+ res = request(:get, 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
- server.request(:put, path_uri("/#{id}"), source)
23
+ request(:put, id, source)
24
24
  end
25
25
 
26
26
  # Uses the update api to modify a document with a script
@@ -28,38 +28,32 @@ module Stretcher
28
28
  # type.update(987, script: "ctx._source.message = 'Updated!'")
29
29
  # See http://www.elasticsearch.org/guide/reference/api/update.html
30
30
  def update(id, body)
31
- server.request(:post, path_uri("/#{id}/_update"), body)
31
+ request(:post, "#{id}/_update", body)
32
32
  end
33
33
 
34
34
  # Deletes the document with the given ID
35
35
  def delete(id)
36
- res = server.http.delete path_uri("/#{id}")
37
-
38
- # Since 404s are just not a problem here, let's simply return false
39
- if res.status == 404
40
- false
41
- elsif res.status >= 200 && res.status <= 299
42
- res.body
43
- else
44
- raise RequestError.new(res), "Error processing delete request! Status: #{res.status}\n Body: #{res.body}"
45
- end
36
+ request :delete, id
37
+ rescue Stretcher::RequestError => e
38
+ raise e if e.http_response.status != 404
39
+ false
46
40
  end
47
41
 
48
42
  # Retrieve the mapping for this type
49
43
  def get_mapping
50
- @server.request :get, path_uri("/_mapping")
44
+ request :get, "_mapping"
51
45
  end
52
46
 
53
47
  # Delete the mapping for this type. Note this will delete
54
48
  # All documents of this type as well
55
49
  # http://www.elasticsearch.org/guide/reference/api/admin-indices-delete-mapping.html
56
50
  def delete_mapping
57
- @server.request :delete, path_uri("/_mapping")
51
+ request :delete, "_mapping"
58
52
  end
59
53
 
60
54
  # Alter the mapping for this type
61
55
  def put_mapping(body)
62
- @server.request(:put, path_uri("/_mapping")) {|req|
56
+ request(:put, "_mapping") {|req|
63
57
  req.body = body
64
58
  }
65
59
  end
@@ -67,7 +61,11 @@ module Stretcher
67
61
  # Check if this index type is defined, if passed an id
68
62
  # this will check if the given document exists
69
63
  def exists?(id=nil)
70
- server.http.head(path_uri("/#{id}")).status != 404
64
+ request :head, id
65
+ true
66
+ rescue Stretcher::RequestError => e
67
+ raise e if e.http_response.status != 404
68
+ false
71
69
  end
72
70
 
73
71
  # Issues an Index#search scoped to this type
@@ -78,8 +76,9 @@ module Stretcher
78
76
  end
79
77
 
80
78
  # Full path to this index type
81
- def path_uri(path="/")
82
- index.path_uri("/#{name}") + path.to_s
79
+ def path_uri(path=nil)
80
+ p = index.path_uri(name)
81
+ path ? p << "/#{path}" : p
83
82
  end
84
83
  end
85
84
  end
@@ -119,24 +119,29 @@ module Stretcher
119
119
  req.body = text
120
120
  end
121
121
  end
122
+
123
+ # Perform a refresh, making all indexed documents available
124
+ def refresh
125
+ do_refresh
126
+ end
122
127
 
123
128
  # Full path to the server root dir
124
- def path_uri(path="/")
129
+ def path_uri(path=nil)
125
130
  @uri.to_s + path.to_s
126
131
  end
127
132
 
128
133
  # Handy way to query the server, returning *only* the body
129
134
  # Will raise an exception when the status is not in the 2xx range
130
- def request(method, *args, &block)
131
- logger.info { "Stretcher: Issuing Request #{method.to_s.upcase}, #{args}" }
135
+ def request(method, url=nil, query_opts=nil, *args, &block)
136
+ logger.info { "Stretcher: Issuing Request #{method.to_s.upcase}, #{Util.qurl(url,query_opts)}" }
132
137
  res = if block
133
- http.send(method, *args) do |req|
138
+ http.send(method, url, query_opts, *args) do |req|
134
139
  # Elastic search does mostly deal with JSON
135
140
  req.headers["Content-Type"] = 'application/json'
136
141
  block.call(req)
137
142
  end
138
143
  else
139
- http.send(method, *args)
144
+ http.send(method, url, query_opts, *args)
140
145
  end
141
146
 
142
147
  if res.status >= 200 && res.status <= 299
@@ -1,5 +1,9 @@
1
1
  module Stretcher
2
2
  module Util
3
+ def self.qurl(url, query_opts=nil)
4
+ query_opts && !query_opts.empty? ? "#{url}?#{querify(query_opts)}" : url
5
+ end
6
+
3
7
  def self.querify(hash)
4
8
  hash.map {|k,v| "#{k}=#{v}"}.join('&')
5
9
  end
@@ -1,3 +1,3 @@
1
1
  module Stretcher
2
- VERSION = "1.3.3"
2
+ VERSION = "1.4.0"
3
3
  end
@@ -15,7 +15,7 @@ describe Stretcher::Index do
15
15
 
16
16
  def create_tweet_mapping
17
17
  mdata = {:tweet => {:properties => {:text => {:type => :string}}}}
18
- index.type('tweet').put_mapping(mdata)
18
+ index.type(:tweet).put_mapping(mdata)
19
19
  end
20
20
 
21
21
  def seed_corpus
@@ -66,7 +66,7 @@ describe Stretcher::Index do
66
66
  it "should search without error" do
67
67
  seed_corpus
68
68
  match_text = corpus.first[:text]
69
- sleep 1 # ES needs time to update!
69
+ index.refresh
70
70
  res = index.search({}, {:query => {:match => {:text => match_text}}})
71
71
  res.results.first.text.should == match_text
72
72
  end
@@ -22,7 +22,7 @@ describe Stretcher::Index do
22
22
  it "should search and find the right doc" do
23
23
  match_text = 'hello'
24
24
  type.put(123123, @doc)
25
- sleep 1
25
+ index.refresh
26
26
  res = type.search({}, {:query => {:match => {:message => match_text}}})
27
27
  res.results.first.message.should == @doc[:message]
28
28
  end
@@ -29,6 +29,10 @@ describe Stretcher::Server do
29
29
  server.status.ok.should be_true
30
30
  end
31
31
 
32
+ it "should refresh w/o error" do
33
+ server.refresh.ok.should be_true
34
+ end
35
+
32
36
  it "should beget an index object cleanly" do
33
37
  server.index('foo').class.should == Stretcher::Index
34
38
  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.3
4
+ version: 1.4.0
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-03-03 00:00:00.000000000 Z
12
+ date: 2013-03-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday