Commit 7f66ff26ee60316ba01209948d8806662d7be498

Authored by Andrew Kane
1 parent 7f8b301c

Added range and date_range aggregations

@@ -578,9 +578,16 @@ Limit @@ -578,9 +578,16 @@ Limit
578 Product.search "apples", aggs: {store_id: {limit: 10}} 578 Product.search "apples", aggs: {store_id: {limit: 10}}
579 ``` 579 ```
580 580
  581 +Ranges
  582 +
  583 +```ruby
  584 +price_ranges = [{to: 20}, {from: 20, to: 50}, {from: 50}]
  585 +Product.search "*", aggs: {price: {ranges: price_ranges}}
  586 +```
  587 +
581 #### Moving From Facets 588 #### Moving From Facets
582 589
583 -1. Replace `facets` with `aggs` in searches. **Note:** Range and stats facets are not supported at this time. 590 +1. Replace `facets` with `aggs` in searches. **Note:** Stats facets are not supported at this time.
584 591
585 ```ruby 592 ```ruby
586 products = Product.search "chuck taylor", facets: [:brand] 593 products = Product.search "chuck taylor", facets: [:brand]
@@ -627,6 +634,14 @@ Product.search "apples", aggs: {store_id: {limit: 10}} @@ -627,6 +634,14 @@ Product.search "apples", aggs: {store_id: {limit: 10}}
627 634
628 3. By default, `where` conditions apply to aggregations. This is equivalent to `smart_facets: true`. If you have `smart_facets: true`, you can remove it. If this is not desired, set `smart_aggs: false`. 635 3. By default, `where` conditions apply to aggregations. This is equivalent to `smart_facets: true`. If you have `smart_facets: true`, you can remove it. If this is not desired, set `smart_aggs: false`.
629 636
  637 +4. If you have any range facets with dates, change the key from `ranges` to `date_ranges`.
  638 +
  639 + ```ruby
  640 + facets: {date_field: {ranges: date_ranges}}
  641 + # to
  642 + aggs: {date_field: {date_ranges: date_ranges}}
  643 + ```
  644 +
630 ### Facets [deprecated] 645 ### Facets [deprecated]
631 646
632 Facets have been deprecated in favor of aggregations as of Searchkick 0.9.2. See [how to upgrade](#moving-from-facets). 647 Facets have been deprecated in favor of aggregations as of Searchkick 0.9.2. See [how to upgrade](#moving-from-facets).
lib/searchkick/query.rb
@@ -344,12 +344,28 @@ module Searchkick @@ -344,12 +344,28 @@ module Searchkick
344 aggs.each do |field, agg_options| 344 aggs.each do |field, agg_options|
345 size = agg_options[:limit] ? agg_options[:limit] : 100_000 345 size = agg_options[:limit] ? agg_options[:limit] : 100_000
346 346
347 - payload[:aggs][field] = {  
348 - terms: {  
349 - field: agg_options[:field] || field,  
350 - size: size 347 + if agg_options[:ranges]
  348 + payload[:aggs][field] = {
  349 + range: {
  350 + field: agg_options[:field] || field,
  351 + ranges: agg_options[:ranges]
  352 + }
351 } 353 }
352 - } 354 + elsif agg_options[:date_ranges]
  355 + payload[:aggs][field] = {
  356 + date_range: {
  357 + field: agg_options[:field] || field,
  358 + ranges: agg_options[:date_ranges]
  359 + }
  360 + }
  361 + else
  362 + payload[:aggs][field] = {
  363 + terms: {
  364 + field: agg_options[:field] || field,
  365 + size: size
  366 + }
  367 + }
  368 + end
353 369
354 where = {} 370 where = {}
355 where = (options[:where] || {}).reject { |k| k == field } unless options[:smart_aggs] == false 371 where = (options[:where] || {}).reject { |k| k == field } unless options[:smart_aggs] == false
test/aggs_test.rb
@@ -32,6 +32,27 @@ class AggsTest < Minitest::Test @@ -32,6 +32,27 @@ class AggsTest < Minitest::Test
32 assert_equal(1, agg["sum_other_doc_count"]) if Gem::Version.new(Searchkick.server_version) >= Gem::Version.new("1.4.0") 32 assert_equal(1, agg["sum_other_doc_count"]) if Gem::Version.new(Searchkick.server_version) >= Gem::Version.new("1.4.0")
33 end 33 end
34 34
  35 + def test_ranges
  36 + price_ranges = [{to: 10}, {from: 10, to: 20}, {from: 20}]
  37 + agg = Product.search("Product", aggs: {price: {ranges: price_ranges}}).aggs["price"]
  38 +
  39 + assert_equal 3, agg["buckets"].size
  40 + assert_equal 10.0, agg["buckets"][0]["to"]
  41 + assert_equal 20.0, agg["buckets"][2]["from"]
  42 + assert_equal 1, agg["buckets"][0]["doc_count"]
  43 + assert_equal 0, agg["buckets"][1]["doc_count"]
  44 + assert_equal 2, agg["buckets"][2]["doc_count"]
  45 + end
  46 +
  47 + def test_date_ranges
  48 + ranges = [{to: 1.day.ago}, {from: 1.day.ago, to: 1.day.from_now}, {from: 1.day.from_now}]
  49 + agg = Product.search("Product", aggs: {created_at: {date_ranges: ranges}}).aggs["created_at"]
  50 +
  51 + assert_equal 1, agg["buckets"][0]["doc_count"]
  52 + assert_equal 1, agg["buckets"][1]["doc_count"]
  53 + assert_equal 1, agg["buckets"][2]["doc_count"]
  54 + end
  55 +
35 def test_query_where 56 def test_query_where
36 assert_equal ({1 => 1}), store_agg(where: {in_stock: true}, aggs: [:store_id]) 57 assert_equal ({1 => 1}), store_agg(where: {in_stock: true}, aggs: [:store_id])
37 end 58 end