Commit 200a33875d53e43ad35d9d7d3c71423647a0fe94
1 parent
8d3b7e8b
Exists in
master
and in
21 other branches
Merged aggs
Showing
3 changed files
with
108 additions
and
22 deletions
Show diff stats
README.md
@@ -541,11 +541,95 @@ products = Product.search "peantu butta", suggest: true | @@ -541,11 +541,95 @@ products = Product.search "peantu butta", suggest: true | ||
541 | products.suggestions # ["peanut butter"] | 541 | products.suggestions # ["peanut butter"] |
542 | ``` | 542 | ``` |
543 | 543 | ||
544 | -### Facets | 544 | +### Aggregations |
545 | 545 | ||
546 | -[Facets](http://www.elasticsearch.org/guide/reference/api/search/facets/) provide aggregated search data. | 546 | +[Aggregations](http://www.elasticsearch.org/guide/reference/api/search/facets/) provide aggregated search data. |
547 | 547 | ||
548 | - | 548 | + |
549 | + | ||
550 | +```ruby | ||
551 | +products = Product.search "chuck taylor", aggs: [:product_type, :gender, :brand] | ||
552 | +products.aggs | ||
553 | +``` | ||
554 | + | ||
555 | +By default, `where` conditions apply to aggregations. | ||
556 | + | ||
557 | +```ruby | ||
558 | +Product.search "wingtips", where: {color: "brandy"}, aggs: [:size] | ||
559 | +# aggregations for brandy wingtips are returned | ||
560 | +``` | ||
561 | + | ||
562 | +Change this with: | ||
563 | + | ||
564 | +```ruby | ||
565 | +Product.search "wingtips", where: {color: "brandy"}, aggs: [:size], smart_aggs: false | ||
566 | +# aggregations for all wingtips are returned | ||
567 | +``` | ||
568 | + | ||
569 | +Set `where` conditions for each aggregation separately with: | ||
570 | + | ||
571 | +```ruby | ||
572 | +Product.search "wingtips", aggs: {size: {where: {color: "brandy"}}} | ||
573 | +``` | ||
574 | + | ||
575 | +Limit | ||
576 | + | ||
577 | +```ruby | ||
578 | +Product.search "apples", aggs: {store_id: {limit: 10}} | ||
579 | +``` | ||
580 | + | ||
581 | +#### Moving From Facets | ||
582 | + | ||
583 | +1. Replace `facets` with `aggs` in searches. **Note:** Range and stats facets are not supported at this time. | ||
584 | + | ||
585 | + ```ruby | ||
586 | + products = Product.search "chuck taylor", facets: [:brand] | ||
587 | + # to | ||
588 | + products = Product.search "chuck taylor", aggs: [:brand] | ||
589 | + ``` | ||
590 | + | ||
591 | +2. Replace the `facets` method with `aggs` for results. | ||
592 | + | ||
593 | + ```ruby | ||
594 | + products.facets | ||
595 | + # to | ||
596 | + products.aggs | ||
597 | + ``` | ||
598 | + | ||
599 | + The keys in results differ slightly. Instead of: | ||
600 | + | ||
601 | + ```json | ||
602 | + { | ||
603 | + "_type":"terms", | ||
604 | + "missing":0, | ||
605 | + "total":45, | ||
606 | + "other":34, | ||
607 | + "terms":[ | ||
608 | + {"term":14.0,"count":11} | ||
609 | + ] | ||
610 | + } | ||
611 | + ``` | ||
612 | + | ||
613 | + You get: | ||
614 | + | ||
615 | + ```json | ||
616 | + { | ||
617 | + "doc_count":45, | ||
618 | + "doc_count_error_upper_bound":0, | ||
619 | + "sum_other_doc_count":34, | ||
620 | + "buckets":[ | ||
621 | + {"key":14.0,"doc_count":11} | ||
622 | + ] | ||
623 | + } | ||
624 | + ``` | ||
625 | + | ||
626 | + Update your application to handle this. | ||
627 | + | ||
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`. | ||
629 | + | ||
630 | +### Facets [deprecated] | ||
631 | + | ||
632 | +Facets have been deprecated in favor of aggregations as of Searchkick 0.9.2. See [how to upgrade](#moving-from-facets). | ||
549 | 633 | ||
550 | ```ruby | 634 | ```ruby |
551 | products = Product.search "chuck taylor", facets: [:product_type, :gender, :brand] | 635 | products = Product.search "chuck taylor", facets: [:product_type, :gender, :brand] |
@@ -687,6 +771,8 @@ City.search "san", boost_by_distance: {field: :location, origin: [37, -122], fun | @@ -687,6 +771,8 @@ City.search "san", boost_by_distance: {field: :location, origin: [37, -122], fun | ||
687 | 771 | ||
688 | Searchkick supports [Elasticsearch’s routing feature](https://www.elastic.co/blog/customizing-your-document-routing). | 772 | Searchkick supports [Elasticsearch’s routing feature](https://www.elastic.co/blog/customizing-your-document-routing). |
689 | 773 | ||
774 | +**Note:** Routing is not yet supported for Elasticsearch 2.0. | ||
775 | + | ||
690 | ```ruby | 776 | ```ruby |
691 | class Contact < ActiveRecord::Base | 777 | class Contact < ActiveRecord::Base |
692 | searchkick routing: :user_id | 778 | searchkick routing: :user_id |
lib/searchkick/query.rb
@@ -354,9 +354,9 @@ module Searchkick | @@ -354,9 +354,9 @@ module Searchkick | ||
354 | } | 354 | } |
355 | } | 355 | } |
356 | 356 | ||
357 | - agg_options.deep_merge!(where: options.fetch(:where, {}).reject { |k| k == field }) if options[:smart_aggs] == true | ||
358 | - agg_filters = where_filters(agg_options[:where]) | ||
359 | - | 357 | + where = {} |
358 | + where = (options[:where] || {}).reject { |k| k == field } unless options[:smart_aggs] == false | ||
359 | + agg_filters = where_filters(where.merge(agg_options[:where] || {})) | ||
360 | if agg_filters.any? | 360 | if agg_filters.any? |
361 | payload[:aggs][field] = { | 361 | payload[:aggs][field] = { |
362 | filter: { | 362 | filter: { |
test/aggs_test.rb
@@ -32,34 +32,34 @@ class AggsTest < Minitest::Test | @@ -32,34 +32,34 @@ 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_where_no_smart_aggs | ||
36 | - assert_equal ({2 => 2}), store_agg(where: {color: "red"}, aggs: {store_id: {where: {in_stock: false}}}) | ||
37 | - assert_equal ({2 => 2}), store_agg(where: {color: "blue"}, aggs: {store_id: {where: {in_stock: false}}}) | 35 | + def test_query_where |
36 | + assert_equal ({1 => 1}), store_agg(where: {in_stock: true}, aggs: [:store_id]) | ||
38 | end | 37 | end |
39 | 38 | ||
40 | - def test_smart_aggs | ||
41 | - assert_equal ({1 => 1}), store_agg(where: {in_stock: true}, aggs: [:store_id], smart_aggs: true) | 39 | + def test_two_wheres |
40 | + assert_equal ({2 => 1}), store_agg(where: {color: "red"}, aggs: {store_id: {where: {in_stock: false}}}) | ||
42 | end | 41 | end |
43 | 42 | ||
44 | - def test_smart_aggs_where | ||
45 | - assert_equal ({2 => 1}), store_agg(where: {color: "red"}, aggs: {store_id: {where: {in_stock: false}}}, smart_aggs: true) | 43 | + def test_where_override |
44 | + assert_equal ({}), store_agg(where: {color: "red"}, aggs: {store_id: {where: {in_stock: false, color: "blue"}}}) | ||
45 | + assert_equal ({2 => 1}), store_agg(where: {color: "blue"}, aggs: {store_id: {where: {in_stock: false, color: "red"}}}) | ||
46 | end | 46 | end |
47 | 47 | ||
48 | - def test_smart_aggs_where_override | ||
49 | - assert_equal ({2 => 1}), store_agg(where: {color: "red"}, aggs: {store_id: {where: {in_stock: false, color: "blue"}}}, smart_aggs: true) | ||
50 | - assert_equal ({}), store_agg(where: {color: "blue"}, aggs: {store_id: {where: {in_stock: false, color: "red"}}}, smart_aggs: true) | 48 | + def test_skip |
49 | + assert_equal ({1 => 1, 2 => 2}), store_agg(where: {store_id: 2}, aggs: [:store_id]) | ||
51 | end | 50 | end |
52 | 51 | ||
53 | - def test_smart_aggs_skip_agg | ||
54 | - assert_equal ({1 => 1, 2 => 2}), store_agg(where: {store_id: 2}, aggs: [:store_id], smart_aggs: true) | 52 | + def test_skip_complex |
53 | + assert_equal ({1 => 1, 2 => 1}), store_agg(where: {store_id: 2, price: {gt: 5}}, aggs: [:store_id]) | ||
55 | end | 54 | end |
56 | 55 | ||
57 | - def test_smart_aggs_skip_agg_complex | ||
58 | - assert_equal ({1 => 1, 2 => 1}), store_agg(where: {store_id: 2, price: {gt: 5}}, aggs: [:store_id], smart_aggs: true) | 56 | + def test_multiple |
57 | + assert_equal ({"store_id" => {1 => 1, 2 => 2}, "color" => {"blue" => 1, "green" => 1, "red" => 1}}), store_multiple_aggs(aggs: [:store_id, :color]) | ||
59 | end | 58 | end |
60 | 59 | ||
61 | - def test_multiple_aggs | ||
62 | - assert_equal ({"store_id" => {1 => 1, 2 => 2}, "color" => {"blue" => 1, "green" => 1, "red" => 1}}), store_multiple_aggs(aggs: [:store_id, :color]) | 60 | + def test_smart_aggs_false |
61 | + assert_equal ({2 => 2}), store_agg(where: {color: "red"}, aggs: {store_id: {where: {in_stock: false}}}, smart_aggs: false) | ||
62 | + assert_equal ({2 => 2}), store_agg(where: {color: "blue"}, aggs: {store_id: {where: {in_stock: false}}}, smart_aggs: false) | ||
63 | end | 63 | end |
64 | 64 | ||
65 | protected | 65 | protected |