Multi-select Solr filtering and faceting

2019-07-27 19:32发布

问题:

I'm trying to implement facets for my Solr service, but I'm a bit confused as to what I'm seeing. I understand that Tags and Exclusions are used to ignore specific filter counts, such that something like this would happen:

[] Nike 55
[] Adidas 54
[] New Balance 32

[] Black 25
[] Blue 26
[] Red 29
[] Yellow 23
---------------

[X] Nike 55
[] Adidas 54
[] New Balance 32

[] Black 20
[] Blue 15
[] Red 13
[] Yellow 13


[X] Nike 20
[] Adidas 0
[] New Balance 0

[X] Black 20
[] Blue 15
[] Red 13
[] Yellow 13

I understand that in the above case, we would filter on brand for the Solr query, and pass in a tag/exclusion on the brand filter/facet for the counts to remain the same only on brand. Then, we filter by color, and keep THOSE counts the same while letting the other counts (Brand) change.

However, here is where I get stuck. On larger sites (like Newegg, Amazon, etc...) I notice that this is NOT the case. When I select by my first filter, the filter counts I selected do not change, while the other counts do.

[X] Nike 51
[] Adidas 54
[] New Balance 32

[] Black 20
[] Blue 15
[] Red 13
[] Yellow 13

Then, when I select by the second filter (different from the first), the second filter counts don't change, but the first filter counts change in a way that doesn't zero out the counts, like so:

[X] Nike 8
[] Adidas 12
[] New Balance 5

[X] Black 20
[] Blue 15
[] Red 13
[] Yellow 13

What is happening here? I feel like I'm sending in facets and filters to solr incorrectly. I only send in the tag and exclusion for the most recently selected filter. That always changes other counts based on the most recent selection. But in the last case I outlined, the brand filter didn't zero out even though I'm only searching for Black Nike shoes; I still get prospective counts for Adidas and New Balance. Sorry this post is so long, but I couldn't think of a good way to explain it without examples.

回答1:

The problem in your case is that when you filter your results second time you forget to tag you brand filter query.
Lets take an example to solve your problem.Please refer to the queries that I'm using

<lst name="brand">
<int name="Nike">6</int>
<int name="Adidas">3</int>
<int name="New Balance">1</int>
</lst>
<lst name="color">
<int name="Black">5</int>
<int name="Blue">5</int>
</lst>

User Selects "Nike"

First you select the "Nike" from Brand facet. We add the filter tagged with brand to exclude from results and re-issue the request

facet=true
&facet.field={!ex=brand}brand
&fq={!tag=brand}brand:Nike

The response we get

<lst name="facet_fields">
<lst name="brand">
<int name="Nike">6</int>
<int name="Adidas">3</int>
<int name="New Balance">1</int>
</lst>
<lst name="color">
<int name="Black">3</int>
<int name="Blue">3</int>
</lst>

User Selects "Black"

Now user select "Black" from color facet. We add another new filter query tagged with color to exclude it from result.

facet=true
&facet.field={!ex=brand}brand
&facet.field={!ex=color}color
&fq={!tag=brand}brand:Nike
&fq={!tag=color}color:Black

The response we get

<lst name="brand">
<int name="Nike">3</int>
<int name="Adidas">2</int>
<int name="New Balance">0</int>
</lst>
<lst name="color">
<int name="Black">3</int>
<int name="Blue">3</int>
</lst>