diff --git a/README.md b/README.md index 957fcde..d549d35 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Add this line to your application’s Gemfile: gem 'searchkick' ``` -For Elasticsearch 0.90, use version `0.6.3` and [this readme](https://github.com/ankane/searchkick/blob/v0.6.3/README.md). +For Elasticsearch 2.0, use version `0.9.2` or above. For Elasticsearch 0.90, use version `0.6.3` and [this readme](https://github.com/ankane/searchkick/blob/v0.6.3/README.md). Add searchkick to models you want to search. @@ -547,11 +547,95 @@ products = Product.search "peantu butta", suggest: true products.suggestions # ["peanut butter"] ``` -### Facets +### Aggregations -[Facets](http://www.elasticsearch.org/guide/reference/api/search/facets/) provide aggregated search data. +[Aggregations](http://www.elasticsearch.org/guide/reference/api/search/facets/) provide aggregated search data. -![Facets](http://ankane.github.io/searchkick/facets.png) +![Aggregations](http://ankane.github.io/searchkick/facets.png) + +```ruby +products = Product.search "chuck taylor", aggs: [:product_type, :gender, :brand] +products.aggs +``` + +By default, `where` conditions apply to aggregations. + +```ruby +Product.search "wingtips", where: {color: "brandy"}, aggs: [:size] +# aggregations for brandy wingtips are returned +``` + +Change this with: + +```ruby +Product.search "wingtips", where: {color: "brandy"}, aggs: [:size], smart_aggs: false +# aggregations for all wingtips are returned +``` + +Set `where` conditions for each aggregation separately with: + +```ruby +Product.search "wingtips", aggs: {size: {where: {color: "brandy"}}} +``` + +Limit + +```ruby +Product.search "apples", aggs: {store_id: {limit: 10}} +``` + +#### Moving From Facets + +1. Replace `facets` with `aggs` in searches. **Note:** Range and stats facets are not supported at this time. + + ```ruby + products = Product.search "chuck taylor", facets: [:brand] + # to + products = Product.search "chuck taylor", aggs: [:brand] + ``` + +2. Replace the `facets` method with `aggs` for results. + + ```ruby + products.facets + # to + products.aggs + ``` + + The keys in results differ slightly. Instead of: + + ```json + { + "_type":"terms", + "missing":0, + "total":45, + "other":34, + "terms":[ + {"term":14.0,"count":11} + ] + } + ``` + + You get: + + ```json + { + "doc_count":45, + "doc_count_error_upper_bound":0, + "sum_other_doc_count":34, + "buckets":[ + {"key":14.0,"doc_count":11} + ] + } + ``` + + Update your application to handle this. + +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`. + +### Facets [deprecated] + +Facets have been deprecated in favor of aggregations as of Searchkick 0.9.2. See [how to upgrade](#moving-from-facets). ```ruby products = Product.search "chuck taylor", facets: [:product_type, :gender, :brand] @@ -693,6 +777,8 @@ City.search "san", boost_by_distance: {field: :location, origin: [37, -122], fun Searchkick supports [Elasticsearch’s routing feature](https://www.elastic.co/blog/customizing-your-document-routing). +**Note:** Routing is not yet supported for Elasticsearch 2.0. + ```ruby class Contact < ActiveRecord::Base searchkick routing: :user_id diff --git a/lib/searchkick/query.rb b/lib/searchkick/query.rb index e2e8fd3..8cc33ab 100644 --- a/lib/searchkick/query.rb +++ b/lib/searchkick/query.rb @@ -354,9 +354,9 @@ module Searchkick } } - agg_options.deep_merge!(where: options.fetch(:where, {}).reject { |k| k == field }) if options[:smart_aggs] == true - agg_filters = where_filters(agg_options[:where]) - + where = {} + where = (options[:where] || {}).reject { |k| k == field } unless options[:smart_aggs] == false + agg_filters = where_filters(where.merge(agg_options[:where] || {})) if agg_filters.any? payload[:aggs][field] = { filter: { diff --git a/test/aggs_test.rb b/test/aggs_test.rb index 495c0a3..d45f4bc 100644 --- a/test/aggs_test.rb +++ b/test/aggs_test.rb @@ -32,34 +32,34 @@ class AggsTest < Minitest::Test assert_equal(1, agg["sum_other_doc_count"]) if Gem::Version.new(Searchkick.server_version) >= Gem::Version.new("1.4.0") end - def test_where_no_smart_aggs - assert_equal ({2 => 2}), store_agg(where: {color: "red"}, aggs: {store_id: {where: {in_stock: false}}}) - assert_equal ({2 => 2}), store_agg(where: {color: "blue"}, aggs: {store_id: {where: {in_stock: false}}}) + def test_query_where + assert_equal ({1 => 1}), store_agg(where: {in_stock: true}, aggs: [:store_id]) end - def test_smart_aggs - assert_equal ({1 => 1}), store_agg(where: {in_stock: true}, aggs: [:store_id], smart_aggs: true) + def test_two_wheres + assert_equal ({2 => 1}), store_agg(where: {color: "red"}, aggs: {store_id: {where: {in_stock: false}}}) end - def test_smart_aggs_where - assert_equal ({2 => 1}), store_agg(where: {color: "red"}, aggs: {store_id: {where: {in_stock: false}}}, smart_aggs: true) + def test_where_override + assert_equal ({}), store_agg(where: {color: "red"}, aggs: {store_id: {where: {in_stock: false, color: "blue"}}}) + assert_equal ({2 => 1}), store_agg(where: {color: "blue"}, aggs: {store_id: {where: {in_stock: false, color: "red"}}}) end - def test_smart_aggs_where_override - assert_equal ({2 => 1}), store_agg(where: {color: "red"}, aggs: {store_id: {where: {in_stock: false, color: "blue"}}}, smart_aggs: true) - assert_equal ({}), store_agg(where: {color: "blue"}, aggs: {store_id: {where: {in_stock: false, color: "red"}}}, smart_aggs: true) + def test_skip + assert_equal ({1 => 1, 2 => 2}), store_agg(where: {store_id: 2}, aggs: [:store_id]) end - def test_smart_aggs_skip_agg - assert_equal ({1 => 1, 2 => 2}), store_agg(where: {store_id: 2}, aggs: [:store_id], smart_aggs: true) + def test_skip_complex + assert_equal ({1 => 1, 2 => 1}), store_agg(where: {store_id: 2, price: {gt: 5}}, aggs: [:store_id]) end - def test_smart_aggs_skip_agg_complex - assert_equal ({1 => 1, 2 => 1}), store_agg(where: {store_id: 2, price: {gt: 5}}, aggs: [:store_id], smart_aggs: true) + def test_multiple + assert_equal ({"store_id" => {1 => 1, 2 => 2}, "color" => {"blue" => 1, "green" => 1, "red" => 1}}), store_multiple_aggs(aggs: [:store_id, :color]) end - def test_multiple_aggs - assert_equal ({"store_id" => {1 => 1, 2 => 2}, "color" => {"blue" => 1, "green" => 1, "red" => 1}}), store_multiple_aggs(aggs: [:store_id, :color]) + def test_smart_aggs_false + assert_equal ({2 => 2}), store_agg(where: {color: "red"}, aggs: {store_id: {where: {in_stock: false}}}, smart_aggs: false) + assert_equal ({2 => 2}), store_agg(where: {color: "blue"}, aggs: {store_id: {where: {in_stock: false}}}, smart_aggs: false) end protected -- libgit2 0.21.0