Commit 57fe8ebed3f841bdf18bd46f2ec384ad0577fc00

Authored by Andrew Kane
1 parent 8a4e6c43

Added experimental support for the ability to modify the generated query

README.md
... ... @@ -579,6 +579,16 @@ class Product < ActiveRecord::Base
579 579 end
580 580 ```
581 581  
  582 +## Experimental [master]
  583 +
  584 +Modify the query generated by Searchkick.
  585 +
  586 +```ruby
  587 +query = Product.search "2% Milk", execute: false
  588 +query.body[:query] = {match_all: {}}
  589 +products = query.execute
  590 +```
  591 +
582 592 ## Reference
583 593  
584 594 Searchkick requires Elasticsearch `0.90.0` or higher.
... ...
lib/searchkick/query.rb
1 1 module Searchkick
2 2 class Query
3 3 attr_reader :klass, :term, :options
  4 + attr_accessor :body
4 5  
5 6 def initialize(klass, term, options = {})
6 7 if term.is_a?(Hash)
... ... @@ -13,25 +14,7 @@ module Searchkick
13 14 @klass = klass
14 15 @term = term
15 16 @options = options
16   - end
17   -
18   - def searchkick_index
19   - klass.searchkick_index
20   - end
21   -
22   - def searchkick_options
23   - klass.searchkick_options
24   - end
25 17  
26   - def searchkick_klass
27   - klass.searchkick_klass
28   - end
29   -
30   - def document_type
31   - klass.document_type
32   - end
33   -
34   - def results
35 18 fields =
36 19 if options[:fields]
37 20 if options[:autocomplete]
... ... @@ -299,13 +282,36 @@ module Searchkick
299 282 # http://www.elasticsearch.org/guide/reference/api/search/fields/
300 283 payload[:fields] = [] if load
301 284  
302   - tire_options = {load: load, payload: payload, size: per_page, from: offset}
  285 + tire_options = {load: load, size: per_page, from: offset}
303 286 if options[:type] or klass != searchkick_klass
304 287 tire_options[:type] = [options[:type] || klass].flatten.map(&:document_type)
305 288 end
306   - search = Tire::Search::Search.new(index_name, tire_options)
  289 +
  290 + @search = Tire::Search::Search.new(index_name, tire_options)
  291 + @body = payload
  292 + @facet_limits = facet_limits
  293 + end
  294 +
  295 + def searchkick_index
  296 + klass.searchkick_index
  297 + end
  298 +
  299 + def searchkick_options
  300 + klass.searchkick_options
  301 + end
  302 +
  303 + def searchkick_klass
  304 + klass.searchkick_klass
  305 + end
  306 +
  307 + def document_type
  308 + klass.document_type
  309 + end
  310 +
  311 + def execute
  312 + @search.options[:payload] = body
307 313 begin
308   - response = search.json
  314 + response = @search.json
309 315 rescue Tire::Search::SearchRequestFailed => e
310 316 status_code = e.message[0..3].to_i
311 317 if status_code == 404
... ... @@ -319,14 +325,14 @@ module Searchkick
319 325  
320 326 # apply facet limit in client due to
321 327 # https://github.com/elasticsearch/elasticsearch/issues/1305
322   - facet_limits.each do |field, limit|
  328 + @facet_limits.each do |field, limit|
323 329 field = field.to_s
324 330 facet = response["facets"][field]
325 331 response["facets"][field]["terms"] = facet["terms"].first(limit)
326 332 response["facets"][field]["other"] = facet["total"] - facet["terms"].sum{|term| term["count"] }
327 333 end
328 334  
329   - Searchkick::Results.new(response, search.options.merge(term: term, model_name: searchkick_klass.model_name))
  335 + Searchkick::Results.new(response, @search.options.merge(term: term, model_name: searchkick_klass.model_name))
330 336 end
331 337  
332 338 private
... ...
lib/searchkick/search.rb
... ... @@ -2,7 +2,12 @@ module Searchkick
2 2 module Search
3 3  
4 4 def search(term, options = {})
5   - Searchkick::Query.new(self, term, options).results
  5 + query = Searchkick::Query.new(self, term, options)
  6 + if options[:execute] == false
  7 + query
  8 + else
  9 + query.execute
  10 + end
6 11 end
7 12  
8 13 end
... ...
test/query_test.rb 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +require_relative "test_helper"
  2 +
  3 +class TestQuery < Minitest::Unit::TestCase
  4 +
  5 + def test_basic
  6 + store_names ["Milk", "Apple"]
  7 + query = Product.search("milk", execute: false)
  8 + # query.body = {query: {match_all: {}}}
  9 + # query.body = {query: {match: {name: "Apple"}}}
  10 + query.body[:query] = {match_all: {}}
  11 + assert_equal ["Apple", "Milk"], query.execute.map(&:name).sort
  12 + end
  13 +
  14 +end
... ...