Commit 2cf9d0fa6e1126dcebe4baa57c6eacf032c7be9c

Authored by Josh Schwartzman
Committed by Andrew Kane
1 parent edfe444d

Add time zone to date histogram (#1136)

* Add time_zone as attribute to searchkick date_histogram query

* Test for aggregation with time zone

* Fix test, allow any args to date_histogram.

- Fix test so it doesn't fail based on when it runs.
- Allow any key/value pairs to be passed through to date_histogram.
Showing 2 changed files with 44 additions and 5 deletions   Show diff stats
lib/searchkick/query.rb
... ... @@ -742,12 +742,8 @@ module Searchkick
742 742 }.merge(shared_agg_options)
743 743 }
744 744 elsif (histogram = agg_options[:date_histogram])
745   - interval = histogram[:interval]
746 745 payload[:aggs][field] = {
747   - date_histogram: {
748   - field: histogram[:field],
749   - interval: interval
750   - }
  746 + date_histogram: histogram
751 747 }
752 748 elsif (metric = @@metric_aggs.find { |k| agg_options.has_key?(k) })
753 749 payload[:aggs][field] = {
... ...
test/aggs_test.rb
... ... @@ -116,6 +116,32 @@ class AggsTest < Minitest::Test
116 116 assert_equal 4, products.aggs["products_per_year"]["buckets"].size
117 117 end
118 118  
  119 + def test_aggs_with_time_zone
  120 + start_time = Time.at(1529366400)
  121 +
  122 + store [
  123 + {name: "Opera House Pass", created_at: start_time},
  124 + {name: "London Eye Pass", created_at: start_time + 16.hours},
  125 + {name: "London Tube Pass", created_at: start_time + 16.hours}
  126 + ]
  127 +
  128 + sydney_search = search_aggregate_by_day_with_time_zone('Pass', '+10:00') # Sydney
  129 + london_search = search_aggregate_by_day_with_time_zone('Pass', '+01:00') # London
  130 +
  131 + # London search will return all 3 in one bucket because of time zone offset
  132 + expected_london_buckets = [
  133 + {"key_as_string" => "2018-06-19T00:00:00.000+01:00", "key" => 1529362800000, "doc_count" => 3}
  134 + ]
  135 + assert_equal expected_london_buckets, london_search.aggs["products_per_day"]["buckets"]
  136 +
  137 + # Sydney search will return them in separate buckets due to time zone offset
  138 + expected_sydney_buckets = [
  139 + {"key_as_string" => "2018-06-19T00:00:00.000+10:00", "key" => 1529330400000, "doc_count" => 1},
  140 + {"key_as_string" => "2018-06-20T00:00:00.000+10:00", "key" => 1529416800000, "doc_count" => 2}
  141 + ]
  142 + assert_equal expected_sydney_buckets, sydney_search.aggs["products_per_day"]["buckets"]
  143 + end
  144 +
119 145 def test_aggs_avg
120 146 products =
121 147 Product.search("*", {
... ... @@ -200,6 +226,23 @@ class AggsTest < Minitest::Test
200 226  
201 227 protected
202 228  
  229 + def search_aggregate_by_day_with_time_zone(query, time_zone = '-8:00')
  230 + Product.search(query, {
  231 + where: {
  232 + created_at: {lt: Time.now}
  233 + },
  234 + aggs: {
  235 + products_per_day: {
  236 + date_histogram: {
  237 + field: :created_at,
  238 + interval: :day,
  239 + time_zone: time_zone
  240 + }
  241 + }
  242 + }
  243 + })
  244 + end
  245 +
203 246 def buckets_as_hash(agg)
204 247 Hash[agg["buckets"].map { |v| [v["key"], v["doc_count"]] }]
205 248 end
... ...