Commit 1569a146711cb6c5e98b20223fc23771823c1f83
1 parent
6a71a686
Exists in
master
and in
21 other branches
[#90] - include facets constrains on demand
Showing
4 changed files
with
84 additions
and
4 deletions
Show diff stats
.gitignore
README.md
... | ... | @@ -416,6 +416,14 @@ price_ranges = [{to: 20}, {from: 20, to: 50}, {from: 50}] |
416 | 416 | Product.search "*", facets: {price: {ranges: price_ranges}} |
417 | 417 | ``` |
418 | 418 | |
419 | +With basic constrains | |
420 | + | |
421 | +* `include_constraints` - if set to true will use constrains from basic query inside facets | |
422 | + | |
423 | +```ruby | |
424 | +Product.search('*', where: { color: 'red' }, facets: {store_id: {where: {in_stock: false}}}, include_constraints: true) | |
425 | +``` | |
426 | + | |
419 | 427 | ### Highlight |
420 | 428 | |
421 | 429 | Highlight the search query in the results. | ... | ... |
lib/searchkick/query.rb
... | ... | @@ -239,6 +239,7 @@ module Searchkick |
239 | 239 | # offset is not possible |
240 | 240 | # http://elasticsearch-users.115913.n3.nabble.com/Is-pagination-possible-in-termsStatsFacet-td3422943.html |
241 | 241 | |
242 | + facet_options.deep_merge!(where: options[:where].reject{|k| k == field}) if options[:include_constraints] == true | |
242 | 243 | facet_filters = where_filters(facet_options[:where]) |
243 | 244 | if facet_filters.any? |
244 | 245 | payload[:facets][field][:facet_filter] = { |
... | ... | @@ -428,4 +429,4 @@ module Searchkick |
428 | 429 | end |
429 | 430 | |
430 | 431 | end |
431 | -end | |
432 | 432 | \ No newline at end of file |
433 | +end | ... | ... |
test/facets_test.rb
... | ... | @@ -5,9 +5,10 @@ class TestFacets < Minitest::Unit::TestCase |
5 | 5 | def setup |
6 | 6 | super |
7 | 7 | store [ |
8 | - {name: "Product Show", store_id: 1, in_stock: true, color: "blue", price: 21}, | |
9 | - {name: "Product Hide", store_id: 2, in_stock: false, color: "green", price: 25}, | |
10 | - {name: "Product B", store_id: 2, in_stock: false, color: "red", price: 5} | |
8 | + {name: "Product Show", latitude: 37.7833, longitude: 12.4167, store_id: 1, in_stock: true, color: "blue", price: 21}, | |
9 | + {name: "Product Hide", latitude: 29.4167, longitude: -98.5000, store_id: 2, in_stock: false, color: "green", price: 25}, | |
10 | + {name: "Product B", latitude: 43.9333, longitude: -122.4667, store_id: 2, in_stock: false, color: "red", price: 5}, | |
11 | + {name: "Foo", latitude: 43.9333, longitude: 12.4667, store_id: 3, in_stock: false, color: "yellow", price: 15} | |
11 | 12 | ] |
12 | 13 | end |
13 | 14 | |
... | ... | @@ -37,4 +38,73 @@ class TestFacets < Minitest::Unit::TestCase |
37 | 38 | assert_equal 0, facet["ranges"][1]["count"] |
38 | 39 | assert_equal 2, facet["ranges"][2]["count"] |
39 | 40 | end |
41 | + def test_constraints | |
42 | + facets = Product.search("Product", where: { in_stock: true }, | |
43 | + facets: [:store_id], include_constraints: true).facets | |
44 | + | |
45 | + assert_equal 1, facets['store_id']['terms'].size | |
46 | + assert_equal [1], facets['store_id']['terms'].map{|f| f['term']} | |
47 | + end | |
48 | + | |
49 | + def test_constraints_with_location | |
50 | + facets = Product.search("Product", where: {location: {near: [37, -122], within: "2000mi"}}, | |
51 | + facets: [:store_id], include_constraints: true).facets | |
52 | + | |
53 | + assert_equal 1, facets['store_id']['terms'].size | |
54 | + assert_equal 2, facets['store_id']['terms'][0]['term'] | |
55 | + end | |
56 | + | |
57 | + def test_constraints_with_location_and_or_statement | |
58 | + facets = Product.search("Product", where: {or: [[ | |
59 | + { location: {near: [37, -122], within: "2000mi"}}, {color: 'blue'} | |
60 | + ]]}, facets: [:store_id], include_constraints: true).facets | |
61 | + | |
62 | + assert_equal 2, facets['store_id']['terms'].size | |
63 | + assert_equal [1, 2], facets['store_id']['terms'].map{|f| f['term']}.sort | |
64 | + end | |
65 | + | |
66 | + def test_facets_and_basic_constrains_together | |
67 | + facets = Product.search("Product", where: { color: 'red' }, | |
68 | + facets: {store_id: {where: {in_stock: false}}}, include_constraints: true).facets | |
69 | + | |
70 | + assert_equal 1, facets['store_id']['terms'].size | |
71 | + assert_equal 2, facets['store_id']['terms'][0]['term'] | |
72 | + assert_equal 1, facets['store_id']['terms'][0]['count'] | |
73 | + end | |
74 | + | |
75 | + def test_facets_without_basic_constrains | |
76 | + facets = Product.search("Product", where: { color: 'red' }, | |
77 | + facets: {store_id: {where: {in_stock: false}}}, include_constraints: false).facets | |
78 | + | |
79 | + assert_equal 1, facets['store_id']['terms'].size | |
80 | + assert_equal 2, facets['store_id']['terms'][0]['term'] | |
81 | + assert_equal 2, facets['store_id']['terms'][0]['count'] | |
82 | + end | |
83 | + | |
84 | + def test_do_not_include_current_facets_filter | |
85 | + facets = Product.search("Product", where: { store_id: 2 }, | |
86 | + facets: [:store_id], include_constraints: true).facets | |
87 | + | |
88 | + assert_equal 2, facets['store_id']['terms'].size | |
89 | + assert_equal [1, 2], facets['store_id']['terms'].map{|f| f['term']}.sort | |
90 | + end | |
91 | + | |
92 | + def test_do_not_include_current_facets_filter_with_complex_call | |
93 | + facets = Product.search("Product", where: { store_id: 2, price: {gte: 4 }}, | |
94 | + facets: [:store_id], include_constraints: true).facets | |
95 | + | |
96 | + assert_equal 2, facets['store_id']['terms'].size | |
97 | + assert_equal [1, 2], facets['store_id']['terms'].map{|f| f['term']}.sort | |
98 | + end | |
99 | + | |
100 | + def test_should_still_limit_results | |
101 | + results = Product.search("*", where: { store_id: 2, price: {gte: 4 }}, | |
102 | + facets: [:in_stock, :store_id, :color], include_constraints: false) | |
103 | + | |
104 | + facets = results.facets | |
105 | + assert_equal 2, results.size | |
106 | + assert_equal ["Product B", "Product Hide"], results.map(&:name).sort | |
107 | + assert_equal 3, facets['store_id']['terms'].size | |
108 | + assert_equal [1, 2, 3], facets['store_id']['terms'].map{|f| f['term']}.sort | |
109 | + end | |
40 | 110 | end | ... | ... |