stretcher 1.3.3 → 1.4.0

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.
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