Class: Tire::Search::Multi::Search

Inherits:
Object
  • Object
show all
Defined in:
lib/tire/multi_search.rb

Overview

Build and perform a multi-search request.

s = Tire::Search::Multi::Search.new 'my-index' do
      search :names do
        query { match :name, 'john' }
      end
      search :counts, search_type: 'count' do
        query { match :_all, 'john' }
      end
      search :other, index: 'other-index' do
        query { string "first_name:john" }
      end
    end

You can optionally pass an index and type to the constructor, using them as defaults for searches which don't define them.

Use the #search method to add a search definition to the request, passing it search options as a Hash and the search definition itself using Tire's DSL.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(indices = nil, options = {}, &block) ⇒ Search

Returns a new instance of Search.



107
108
109
110
111
112
113
114
115
# File 'lib/tire/multi_search.rb', line 107

def initialize(indices=nil, options={}, &block)
  @indices  = Array(indices)
  @types    = Array(options.delete(:type)).map { |type| Utils.escape(type) }
  @options  = options
  @path     = ['/', @indices.join(','), @types.join(','), '_msearch'].compact.join('/').squeeze('/')
  @searches = Tire::Search::Multi::SearchDefinitions.new

  block.arity < 1 ? instance_eval(&block) : block.call(self) if block_given?
end

Instance Attribute Details

#indicesObject (readonly)

Returns the value of attribute indices.



105
106
107
# File 'lib/tire/multi_search.rb', line 105

def indices
  @indices
end

#pathObject (readonly)

Returns the value of attribute path.



105
106
107
# File 'lib/tire/multi_search.rb', line 105

def path
  @path
end

#typesObject (readonly)

Returns the value of attribute types.



105
106
107
# File 'lib/tire/multi_search.rb', line 105

def types
  @types
end

Instance Method Details

#jsonObject

Returns the raw JSON as a Hash



216
217
218
# File 'lib/tire/multi_search.rb', line 216

def json
  @json     || perform and @json
end

#logged(endpoint = '_msearch') ⇒ Object



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/tire/multi_search.rb', line 237

def logged(endpoint='_msearch')
  if Configuration.logger

    Configuration.logger.log_request endpoint, indices, to_curl

    took = @json['took']  rescue nil
    code = @response.code rescue nil

    if Configuration.logger.level.to_s == 'debug'
      body = if @json
        MultiJson.encode( @json, :pretty => Configuration.pretty)
      else
        MultiJson.encode( MultiJson.load(@response.body), :pretty => Configuration.pretty) rescue ''
      end
    else
      body = ''
    end

    Configuration.logger.log_response code || 'N/A', took || 'N/A', body || 'N/A'
  end
end

#namesObject

Returns and array of search definition names



148
149
150
# File 'lib/tire/multi_search.rb', line 148

def names
  @searches.names
end

#paramsObject

Serializes the request URL parameters



181
182
183
184
# File 'lib/tire/multi_search.rb', line 181

def params
  options = @options.dup
  options.empty? ? '' : '?' + options.to_param
end

#performObject



220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/tire/multi_search.rb', line 220

def perform
  @responses = Configuration.client.get(url + params, to_payload)
  if @responses.failure?
    STDERR.puts "[REQUEST FAILED] #{to_curl}\n"
    raise SearchRequestFailed, @responses.to_s
  end
  @json     = MultiJson.decode(@responses.body)
  @results  = Tire::Search::Multi::Results.new @searches, @json['responses']
  return self
ensure
  logged
end

#responseObject

Returns the HTTP response



210
211
212
# File 'lib/tire/multi_search.rb', line 210

def response
  @response || perform and @response
end

#resultsObject

Returns an enumerable collection of result sets.

You can simply iterate over them:

search.results.each do |results|
  puts results.each.map(&:name)
end

To iterate over named result sets, use the each_pair method:

search.results.each_pair do |name,results|
  puts "Search #{name} got #{results.size} results"
end

To get a specific result set:

search.results[:myname]


204
205
206
# File 'lib/tire/multi_search.rb', line 204

def results
  @results  || perform and @results
end

#search(*args, &block) ⇒ Object

Add a search definition to the multi-search request.

The usual search options such as search_type, routing, etc. can be passed as a Hash, and the search definition itself should be passed as a block using the Tire DSL.



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/tire/multi_search.rb', line 122

def search(*args, &block)
  name_or_options = args.pop

  if name_or_options.is_a?(Hash)
    options = name_or_options
    name    = args.pop
  else
    name    = name_or_options
  end

  name    ||= @searches.size
  options ||= {}
  indices   = options.delete(:index) || options.delete(:indices)

  @searches << { :name => name, :search => Tire::Search::Search.new(indices, options, &block) }
end

#searches(name = nil) ⇒ Object

Without argument, returns the collection of search definitions. With argument, returns a search definition by name or order.



142
143
144
# File 'lib/tire/multi_search.rb', line 142

def searches(name=nil)
  name ? @searches[ name ] : @searches
end

#to_arrayObject

Serializes the search definitions as an array of JSON definitions



154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/tire/multi_search.rb', line 154

def to_array
  @searches.map do |search|
    header = {}
    header.update(:index => search.indices.join(',')) unless search.indices.empty?
    header.update(:type  => search.types.join(','))   unless search.types.empty?
    header.update(:search_type => search.options[:search_type]) if search.options[:search_type]
    header.update(:routing     => search.options[:routing])     if search.options[:routing]
    header.update(:preference  => search.options[:preference])  if search.options[:preference]
    body   = search.to_hash
    [ header, body ]
  end.flatten
end

#to_curlObject



233
234
235
# File 'lib/tire/multi_search.rb', line 233

def to_curl
  %Q|curl -X GET '#{url}#{params.empty? ? '?' : params.to_s + '&'}pretty' -d '\n#{to_payload}'|
end

#to_payloadObject

Serializes the search definitions as a multi-line string payload



169
170
171
# File 'lib/tire/multi_search.rb', line 169

def to_payload
  to_array.map { |line| MultiJson.encode(line) }.join("\n") + "\n"
end

#urlObject

Returns the request URL



175
176
177
# File 'lib/tire/multi_search.rb', line 175

def url
  [ Configuration.url, @path ].join
end