public
Created

  • Download Gist
gistfile1.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
module Tire
module Scroll
DEFAULT_SCROLL_DURATION = '1m'
 
class Scroll
attr_reader :search, :total, :remaining, :counter
 
def initialize(indices=nil, options={}, &block)
@search = Tire::Search::Search.new(indices, options, &block)
@options = options
@duration = options[:scroll] || DEFAULT_SCROLL_DURATION
end
 
def url
Configuration.url + "/_search/scroll?scroll=#{@duration}"
end
 
def results
@results || (perform; @results)
end
 
def response
@response || (perform; @response)
end
 
def each
begin
perform
results.each do |item|
pp ['each', item.id]
yield item
end
end while any?
end
 
def in_batches
begin
perform
yield @results
end while any?
end
 
def done?
!any?
end
 
def any?
@remaining > 0
end
 
def perform
if @response.nil?
puts @search.to_curl
puts
@response = @search.response
@json = @search.json
@results = @search.results
reset_stats
else
puts to_curl
puts
begin
@response = Configuration.client.post(url, @scroll_id)
if @response.failure?
STDERR.puts "[REQUEST FAILED] #{self.to_curl}\n"
raise SearchRequestFailed, @response.to_s
end
 
@json = MultiJson.decode(@response.body)
@results = Results::Collection.new(@json, @options)
update_stats
ensure
logged
end
end
 
@scroll_id = @json['_scroll_id']
return self
end
 
def to_curl
%Q|curl -X GET "#{url}?pretty=true" -d '#{@scroll_id}'|
end
 
def logged(error=nil)
if Configuration.logger
 
Configuration.logger.log_request 'scroll', nil, to_curl
 
took = @json['took'] rescue nil
code = @response.code rescue nil
 
if Configuration.logger.level.to_s == 'debug'
# FIXME: Depends on RestClient implementation
body = if @json
defined?(Yajl) ? Yajl::Encoder.encode(@json, :pretty => true) : MultiJson.encode(@json)
else
@response.body rescue nil
end
else
body = ''
end
 
Configuration.logger.log_response code || 'N/A', took || 'N/A', body || 'N/A'
end
end
 
protected
 
def update_stats
@remaining -= @results.count
@counter += @results.count
end
 
def reset_stats
@total = @json['hits']['total']
@counter = @json['hits']['hits'].length
@remaining = @total - @counter
end
end
end
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.