Commit 587c225e951b693ac8687f1145f2d425d5e62a66

Authored by Andrew
1 parent f957289e

Simplified queries

Showing 1 changed file with 59 additions and 70 deletions   Show diff stats
lib/searchkick/query.rb
... ... @@ -232,8 +232,11 @@ module Searchkick
232 232 warn "The body option replaces the entire body, so the following options are ignored: #{ignored_options.join(", ")}" if ignored_options.any?
233 233 payload = @json
234 234 else
  235 + must_not = []
  236 + should = []
  237 +
235 238 if options[:similar]
236   - payload = {
  239 + query = {
237 240 more_like_this: {
238 241 like: term,
239 242 min_doc_freq: 1,
... ... @@ -245,10 +248,10 @@ module Searchkick
245 248 raise ArgumentError, "Must specify fields to search"
246 249 end
247 250 if fields != ["_all"]
248   - payload[:more_like_this][:fields] = fields
  251 + query[:more_like_this][:fields] = fields
249 252 end
250 253 elsif all
251   - payload = {
  254 + query = {
252 255 match_all: {}
253 256 }
254 257 else
... ... @@ -360,9 +363,11 @@ module Searchkick
360 363 queries_to_add.concat(q2)
361 364 end
362 365  
  366 + queries.concat(queries_to_add)
  367 +
363 368 if options[:exclude]
364   - must_not =
365   - Array(options[:exclude]).map do |phrase|
  369 + Array(options[:exclude]).map do |phrase|
  370 + must_not <<
366 371 if field.start_with?("*.")
367 372 {
368 373 multi_match: {
... ... @@ -382,17 +387,8 @@ module Searchkick
382 387 }
383 388 }
384 389 end
385   - end
386   -
387   - queries_to_add = [{
388   - bool: {
389   - should: queries_to_add,
390   - must_not: must_not
391   - }
392   - }]
  390 + end
393 391 end
394   -
395   - queries.concat(queries_to_add)
396 392 end
397 393  
398 394 payload = {
... ... @@ -402,12 +398,8 @@ module Searchkick
402 398 }
403 399  
404 400 if conversions_fields.present? && options[:conversions] != false
405   - shoulds = []
406 401 conversions_fields.each do |conversions_field|
407   - # wrap payload in a bool query
408   - script_score = {field_value_factor: {field: "#{conversions_field}.count"}}
409   -
410   - shoulds << {
  402 + should << {
411 403 nested: {
412 404 path: conversions_field,
413 405 score_mode: "sum",
... ... @@ -418,19 +410,48 @@ module Searchkick
418 410 match: {
419 411 "#{conversions_field}.query" => options[:conversions_term] || term
420 412 }
  413 + },
  414 + field_value_factor: {
  415 + field: "#{conversions_field}.count"
421 416 }
422   - }.merge(script_score)
  417 + }
423 418 }
424 419 }
425 420 }
426 421 end
427   - payload = {
428   - bool: {
429   - must: payload,
430   - should: shoulds
431   - }
432   - }
433 422 end
  423 +
  424 + query = payload
  425 + end
  426 +
  427 + payload = {
  428 + size: per_page,
  429 + from: offset
  430 + }
  431 +
  432 + # type when inheritance
  433 + where = (options[:where] || {}).dup
  434 + if searchkick_options[:inheritance] && (options[:type] || (klass != searchkick_klass && searchkick_index))
  435 + where[:type] = [options[:type] || klass].flatten.map { |v| searchkick_index.klass_document_type(v, true) }
  436 + end
  437 +
  438 + # start everything as efficient filters
  439 + # move to post_filters as aggs demand
  440 + filters = where_filters(where)
  441 + post_filters = []
  442 +
  443 + # aggregations
  444 + set_aggregations(payload, filters, post_filters) if options[:aggs]
  445 +
  446 + # post filters
  447 + set_post_filters(payload, post_filters) if post_filters.any?
  448 +
  449 + if filters.any? || must_not.any? || should.any?
  450 + bool = {must: query}
  451 + bool[:filter] = filters if filters.any?
  452 + bool[:must_not] = must_not if must_not.any?
  453 + bool[:should] = should if should.any?
  454 + query = {bool: bool}
434 455 end
435 456  
436 457 custom_filters = []
... ... @@ -441,30 +462,27 @@ module Searchkick
441 462 set_boost_by_distance(custom_filters) if options[:boost_by_distance]
442 463  
443 464 if custom_filters.any?
444   - payload = {
  465 + query = {
445 466 function_score: {
446 467 functions: custom_filters,
447   - query: payload,
  468 + query: query,
448 469 score_mode: "sum"
449 470 }
450 471 }
451 472 end
452 473  
453 474 if multiply_filters.any?
454   - payload = {
  475 + query = {
455 476 function_score: {
456 477 functions: multiply_filters,
457   - query: payload,
  478 + query: query,
458 479 score_mode: "multiply"
459 480 }
460 481 }
461 482 end
462 483  
463   - payload = {
464   - query: payload,
465   - size: per_page,
466   - from: offset
467   - }
  484 + payload[:query] = query
  485 +
468 486 payload[:explain] = options[:explain] if options[:explain]
469 487 payload[:profile] = options[:profile] if options[:profile]
470 488  
... ... @@ -474,23 +492,6 @@ module Searchkick
474 492 # indices_boost
475 493 set_boost_by_indices(payload)
476 494  
477   - # type when inheritance
478   - where = (options[:where] || {}).dup
479   - if searchkick_options[:inheritance] && (options[:type] || (klass != searchkick_klass && searchkick_index))
480   - where[:type] = [options[:type] || klass].flatten.map { |v| searchkick_index.klass_document_type(v, true) }
481   - end
482   -
483   - # start everything as efficient filters
484   - # move to post_filters as aggs demand
485   - filters = where_filters(where)
486   - post_filters = []
487   -
488   - # aggregations
489   - set_aggregations(payload, filters, post_filters) if options[:aggs]
490   -
491   - # filters
492   - set_filters(payload, filters, post_filters)
493   -
494 495 # suggestions
495 496 set_suggestions(payload, options[:suggest]) if options[:suggest]
496 497  
... ... @@ -760,24 +761,12 @@ module Searchkick
760 761 end
761 762 end
762 763  
763   - def set_filters(payload, filters, post_filters)
764   - if post_filters.any?
765   - payload[:post_filter] = {
766   - bool: {
767   - filter: post_filters
768   - }
769   - }
770   - end
771   -
772   - if filters.any?
773   - # more efficient query if no aggs
774   - payload[:query] = {
775   - bool: {
776   - must: payload[:query],
777   - filter: filters
778   - }
  764 + def set_post_filters(payload, post_filters)
  765 + payload[:post_filter] = {
  766 + bool: {
  767 + filter: post_filters
779 768 }
780   - end
  769 + }
781 770 end
782 771  
783 772 # TODO id transformation for arrays
... ...