Commit 57fe8ebed3f841bdf18bd46f2ec384ad0577fc00
1 parent
8a4e6c43
Exists in
master
and in
21 other branches
Added experimental support for the ability to modify the generated query
Showing
4 changed files
with
59 additions
and
24 deletions
Show diff stats
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 | ... | ... |
... | ... | @@ -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 | ... | ... |