forked from karmi/retire
/
search.rb
128 lines (104 loc) · 3.44 KB
/
search.rb
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
123
124
125
126
127
128
module Tire
module Search
class Search
attr_reader :indices, :url, :results, :response, :json, :query, :facets, :filters, :options
def initialize(indices=nil, options = {}, &block)
@indices = Array(indices)
@options = options
@type = @options[:type]
@url = Configuration.url+['/', @indices.join(','), @type, '_search'].compact.join('/').squeeze('/')
# TODO: Do not allow changing the wrapper here or set it back after yield
Configuration.wrapper @options[:wrapper] if @options[:wrapper]
block.arity < 1 ? instance_eval(&block) : block.call(self) if block_given?
end
def query(&block)
@query = Query.new
block.arity < 1 ? @query.instance_eval(&block) : block.call(@query)
self
end
def sort(&block)
@sort = Sort.new(&block).to_ary
self
end
def facet(name, options={}, &block)
@facets ||= {}
@facets.update Facet.new(name, options, &block).to_hash
self
end
def filter(type, *options)
@filters ||= []
@filters << Filter.new(type, *options).to_hash
self
end
def highlight(*args)
unless args.empty?
@highlight = Highlight.new(*args)
self
else
@highlight
end
end
def from(value)
@from = value
@options[:from] = value
self
end
def size(value)
@size = value
@options[:size] = value
self
end
def fields(*fields)
@fields = Array(fields.flatten)
self
end
def perform
@response = Configuration.client.get(@url, self.to_json)
@json = MultiJson.decode(@response.body)
@results = Results::Collection.new(@json, @options)
self
rescue Exception => error
STDERR.puts "[REQUEST FAILED] #{self.to_curl}\n"
raise
ensure
logged(error)
end
def to_curl
%Q|curl -X GET "#{@url}?pretty=true" -d '#{self.to_json}'|
end
def to_hash
request = {}
request.update( { :query => @query.to_hash } ) if @query
request.update( { :sort => @sort.to_ary } ) if @sort
request.update( { :facets => @facets.to_hash } ) if @facets
@filters.each { |filter| request.update( { :filter => filter.to_hash } ) } if @filters
request.update( { :highlight => @highlight.to_hash } ) if @highlight
request.update( { :size => @size } ) if @size
request.update( { :from => @from } ) if @from
request.update( { :fields => @fields } ) if @fields
request
end
def to_json
to_hash.to_json
end
def logged(error=nil)
if Configuration.logger
Configuration.logger.log_request '_search', indices, to_curl
code = @response ? @response.code : error.message
took = @json['took'] rescue nil
if Configuration.logger.level.to_s == 'debug'
# FIXME: Depends on RestClient implementation
body = if @response
defined?(Yajl) ? Yajl::Encoder.encode(@json, :pretty => true) : MultiJson.encode(@json)
else
error.http_body rescue ''
end
else
body = ''
end
Configuration.logger.log_response code, took, body
end
end
end
end
end