[ 
https://issues.apache.org/jira/browse/SOLR-6314?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14098119#comment-14098119
 ] 

Erick Erickson commented on SOLR-6314:
--------------------------------------

While arguably the behavior I started looking at is benign-but-annoying (if 
inefficient), there is bona-fide badness here. If you specify facet.query=blah 
twice in distributed mode, the result is twice the count it should be.

Try this: URL on the test docs, simple 2-shard setup:
http://localhost:8983/solr/collection1/query?q=*:*&facet=true&facet.range.mincount=1&facet.range=manufacturedate_dt&facet.range.start=NOW-100YEARS&facet.range.end=NOW&facet.range.gap=%2B10YEAR

The only non-zero entry is
"2004-08-14T22:53:07.852Z",
11

Now duplicate the field by adding another copy of:
&facet.range=manufacturedate_dt
the count goes to 22
oops.

Admittedly this is pilot error, but still it's incorrect.

I looked at de-duping in the facet component only, but that ran into weird null 
pointer exceptions. Given that I slightly favored deduping at a high level 
anyway, I'm not willing to pursue that avenue unless there's a really good 
counter-argument.

Long version:

The behavior is different because the distributed case is, of course, a 
separate code path. Part of that path is FacetComponent.parse (roughly line 
1000 in trunk). That method collects the facet.field parameters into a 
LinkedHashMap, so multiple entries are weeded out. In the case where we specify 
the field twice, the params are still _passed to the shards and calculated 
twice_. And returned twice. It just happens that the facets member var (which 
collected the names of the fields) only has one entry for the 
multiply-specified field since it's a HashMap. So it only asks for the facet 
counts from the response packet once for each shard. Since they're identical, 
it's OK.

However, take rangeFacets, roughly line 981 in FacetComponent is defined as a 
SimpleOrderedMap. Which checks to see if there is already an entry for the 
field in question... and if there is adds to it. 

I think that this adds weight to the somewhat invasive change I first tried. I 
don't know how many of these are hanging around. Based on them being 
SimpleOrderedMaps, I'm guessing at least date facets, pivot facets and interval 
facets at least have problems.

So rather than find them one-by-one I'm inclined to do the deduping at a higher 
level.

This is easy to demonstrate in the distributed tests, just hack 
TestDistributedSearch to duplicate one of the facet.range (or other facet types 
that use SimpleOrderedMaps) in the queries . Tests start failing.

I'll probably attach a new version of the patch tonight (running tests now). 
It's just like the old one except it adds duplicated fields to the distributed 
facets test (which will fail without the patch).

I spent some time trying to move the dedupe code to FacetComponent, but it's 
more tangled than I think is worth the effort. It's not difficult
to dedupe the parameters, but they're passed through in a SolrParams object. So 
far so good. But somehow that generates a null pointer exception down the road. 
I _think_ that the problem here is that there are some assumptions about how 
many entries should be there based on the original parameters in the request. 
Or something like that. Deduping on the highest level seems to avoid this 
altogether and I'm very afraid it's an N+1 problem.

Let me know if anyone disagrees violently. Otherwise I'll commit sometime this 
weekend assuming tests pass.


> Multi-threaded facet counts differ when SolrCloud has >1 shard
> --------------------------------------------------------------
>
>                 Key: SOLR-6314
>                 URL: https://issues.apache.org/jira/browse/SOLR-6314
>             Project: Solr
>          Issue Type: Bug
>          Components: SearchComponents - other, SolrCloud
>    Affects Versions: 5.0
>            Reporter: Vamsee Yarlagadda
>            Assignee: Erick Erickson
>         Attachments: SOLR-6314.patch
>
>
> I am trying to work with multi-threaded faceting on SolrCloud and in the 
> process i was hit by some issues.
> I am currently running the below upstream test on different SolrCloud 
> configurations and i am getting a different result set per configuration.
> https://github.com/apache/lucene-solr/blob/trunk/solr/core/src/test/org/apache/solr/request/TestFaceting.java#L654
> Setup:
> - *Indexed 50 docs into SolrCloud.*
> - *If the SolrCloud has only 1 shard, the facet field query has the below 
> output (which matches with the expected upstream test output - # facet fields 
> ~ 50).*
> {code}
> $ curl  
> "http://localhost:8983/solr/collection1/select?facet=true&fl=id&indent=true&q=id%3A*&facet.limit=-1&facet.threads=1000&facet.field=f0_ws&facet.field=f0_ws&facet.field=f0_ws&facet.field=f0_ws&facet.field=f0_ws&facet.field=f1_ws&facet.field=f1_ws&facet.field=f1_ws&facet.field=f1_ws&facet.field=f1_ws&facet.field=f2_ws&facet.field=f2_ws&facet.field=f2_ws&facet.field=f2_ws&facet.field=f2_ws&facet.field=f3_ws&facet.field=f3_ws&facet.field=f3_ws&facet.field=f3_ws&facet.field=f3_ws&facet.field=f4_ws&facet.field=f4_ws&facet.field=f4_ws&facet.field=f4_ws&facet.field=f4_ws&facet.field=f5_ws&facet.field=f5_ws&facet.field=f5_ws&facet.field=f5_ws&facet.field=f5_ws&facet.field=f6_ws&facet.field=f6_ws&facet.field=f6_ws&facet.field=f6_ws&facet.field=f6_ws&facet.field=f7_ws&facet.field=f7_ws&facet.field=f7_ws&facet.field=f7_ws&facet.field=f7_ws&facet.field=f8_ws&facet.field=f8_ws&facet.field=f8_ws&facet.field=f8_ws&facet.field=f8_ws&facet.field=f9_ws&facet.field=f9_ws&facet.field=f9_ws&facet.field=f9_ws&facet.field=f9_ws&rows=1&wt=xml";
> <?xml version="1.0" encoding="UTF-8"?>
> <response>
> <lst name="responseHeader">
>   <int name="status">0</int>
>   <int name="QTime">21</int>
>   <lst name="params">
>     <str name="facet">true</str>
>     <str name="fl">id</str>
>     <str name="indent">true</str>
>     <str name="q">id:*</str>
>     <str name="facet.limit">-1</str>
>     <str name="facet.threads">1000</str>
>     <arr name="facet.field">
>       <str>f0_ws</str>
>       <str>f0_ws</str>
>       <str>f0_ws</str>
>       <str>f0_ws</str>
>       <str>f0_ws</str>
>       <str>f1_ws</str>
>       <str>f1_ws</str>
>       <str>f1_ws</str>
>       <str>f1_ws</str>
>       <str>f1_ws</str>
>       <str>f2_ws</str>
>       <str>f2_ws</str>
>       <str>f2_ws</str>
>       <str>f2_ws</str>
>       <str>f2_ws</str>
>       <str>f3_ws</str>
>       <str>f3_ws</str>
>       <str>f3_ws</str>
>       <str>f3_ws</str>
>       <str>f3_ws</str>
>       <str>f4_ws</str>
>       <str>f4_ws</str>
>       <str>f4_ws</str>
>       <str>f4_ws</str>
>       <str>f4_ws</str>
>       <str>f5_ws</str>
>       <str>f5_ws</str>
>       <str>f5_ws</str>
>       <str>f5_ws</str>
>       <str>f5_ws</str>
>       <str>f6_ws</str>
>       <str>f6_ws</str>
>       <str>f6_ws</str>
>       <str>f6_ws</str>
>       <str>f6_ws</str>
>       <str>f7_ws</str>
>       <str>f7_ws</str>
>       <str>f7_ws</str>
>       <str>f7_ws</str>
>       <str>f7_ws</str>
>       <str>f8_ws</str>
>       <str>f8_ws</str>
>       <str>f8_ws</str>
>       <str>f8_ws</str>
>       <str>f8_ws</str>
>       <str>f9_ws</str>
>       <str>f9_ws</str>
>       <str>f9_ws</str>
>       <str>f9_ws</str>
>       <str>f9_ws</str>
>     </arr>
>     <str name="wt">xml</str>
>     <str name="rows">1</str>
>   </lst>
> </lst>
> <result name="response" numFound="50" start="0">
>   <doc>
>     <float name="id">0.0</float></doc>
> </result>
> <lst name="facet_counts">
>   <lst name="facet_queries"/>
>   <lst name="facet_fields">
>     <lst name="f0_ws">
>       <int name="zero_1">25</int>
>       <int name="zero_2">25</int>
>     </lst>
>     <lst name="f0_ws">
>       <int name="zero_1">25</int>
>       <int name="zero_2">25</int>
>     </lst>
>     <lst name="f0_ws">
>       <int name="zero_1">25</int>
>       <int name="zero_2">25</int>
>     </lst>
>     <lst name="f0_ws">
>       <int name="zero_1">25</int>
>       <int name="zero_2">25</int>
>     </lst>
>     <lst name="f0_ws">
>       <int name="zero_1">25</int>
>       <int name="zero_2">25</int>
>     </lst>
>     <lst name="f1_ws">
>       <int name="one_1">33</int>
>       <int name="one_3">17</int>
>     </lst>
>     <lst name="f1_ws">
>       <int name="one_1">33</int>
>       <int name="one_3">17</int>
>     </lst>
>     <lst name="f1_ws">
>       <int name="one_1">33</int>
>       <int name="one_3">17</int>
>     </lst>
>     <lst name="f1_ws">
>       <int name="one_1">33</int>
>       <int name="one_3">17</int>
>     </lst>
>     <lst name="f1_ws">
>       <int name="one_1">33</int>
>       <int name="one_3">17</int>
>     </lst>
>     <lst name="f2_ws">
>       <int name="two_1">37</int>
>       <int name="two_4">13</int>
>     </lst>
>     <lst name="f2_ws">
>       <int name="two_1">37</int>
>       <int name="two_4">13</int>
>     </lst>
>     <lst name="f2_ws">
>       <int name="two_1">37</int>
>       <int name="two_4">13</int>
>     </lst>
>     <lst name="f2_ws">
>       <int name="two_1">37</int>
>       <int name="two_4">13</int>
>     </lst>
>     <lst name="f2_ws">
>       <int name="two_1">37</int>
>       <int name="two_4">13</int>
>     </lst>
>     <lst name="f3_ws">
>       <int name="three_1">40</int>
>       <int name="three_5">10</int>
>     </lst>
>     <lst name="f3_ws">
>       <int name="three_1">40</int>
>       <int name="three_5">10</int>
>     </lst>
>     <lst name="f3_ws">
>       <int name="three_1">40</int>
>       <int name="three_5">10</int>
>     </lst>
>     <lst name="f3_ws">
>       <int name="three_1">40</int>
>       <int name="three_5">10</int>
>     </lst>
>     <lst name="f3_ws">
>       <int name="three_1">40</int>
>       <int name="three_5">10</int>
>     </lst>
>     <lst name="f4_ws">
>       <int name="four_1">41</int>
>       <int name="four_6">9</int>
>     </lst>
>     <lst name="f4_ws">
>       <int name="four_1">41</int>
>       <int name="four_6">9</int>
>     </lst>
>     <lst name="f4_ws">
>       <int name="four_1">41</int>
>       <int name="four_6">9</int>
>     </lst>
>     <lst name="f4_ws">
>       <int name="four_1">41</int>
>       <int name="four_6">9</int>
>     </lst>
>     <lst name="f4_ws">
>       <int name="four_1">41</int>
>       <int name="four_6">9</int>
>     </lst>
>     <lst name="f5_ws">
>       <int name="five_1">42</int>
>       <int name="five_7">8</int>
>     </lst>
>     <lst name="f5_ws">
>       <int name="five_1">42</int>
>       <int name="five_7">8</int>
>     </lst>
>     <lst name="f5_ws">
>       <int name="five_1">42</int>
>       <int name="five_7">8</int>
>     </lst>
>     <lst name="f5_ws">
>       <int name="five_1">42</int>
>       <int name="five_7">8</int>
>     </lst>
>     <lst name="f5_ws">
>       <int name="five_1">42</int>
>       <int name="five_7">8</int>
>     </lst>
>     <lst name="f6_ws">
>       <int name="six_1">43</int>
>       <int name="six_8">7</int>
>     </lst>
>     <lst name="f6_ws">
>       <int name="six_1">43</int>
>       <int name="six_8">7</int>
>     </lst>
>     <lst name="f6_ws">
>       <int name="six_1">43</int>
>       <int name="six_8">7</int>
>     </lst>
>     <lst name="f6_ws">
>       <int name="six_1">43</int>
>       <int name="six_8">7</int>
>     </lst>
>     <lst name="f6_ws">
>       <int name="six_1">43</int>
>       <int name="six_8">7</int>
>     </lst>
>     <lst name="f7_ws">
>       <int name="seven_1">44</int>
>       <int name="seven_9">6</int>
>     </lst>
>     <lst name="f7_ws">
>       <int name="seven_1">44</int>
>       <int name="seven_9">6</int>
>     </lst>
>     <lst name="f7_ws">
>       <int name="seven_1">44</int>
>       <int name="seven_9">6</int>
>     </lst>
>     <lst name="f7_ws">
>       <int name="seven_1">44</int>
>       <int name="seven_9">6</int>
>     </lst>
>     <lst name="f7_ws">
>       <int name="seven_1">44</int>
>       <int name="seven_9">6</int>
>     </lst>
>     <lst name="f8_ws">
>       <int name="eight_1">45</int>
>       <int name="eight_10">5</int>
>     </lst>
>     <lst name="f8_ws">
>       <int name="eight_1">45</int>
>       <int name="eight_10">5</int>
>     </lst>
>     <lst name="f8_ws">
>       <int name="eight_1">45</int>
>       <int name="eight_10">5</int>
>     </lst>
>     <lst name="f8_ws">
>       <int name="eight_1">45</int>
>       <int name="eight_10">5</int>
>     </lst>
>     <lst name="f8_ws">
>       <int name="eight_1">45</int>
>       <int name="eight_10">5</int>
>     </lst>
>     <lst name="f9_ws">
>       <int name="nine_1">45</int>
>       <int name="nine_11">5</int>
>     </lst>
>     <lst name="f9_ws">
>       <int name="nine_1">45</int>
>       <int name="nine_11">5</int>
>     </lst>
>     <lst name="f9_ws">
>       <int name="nine_1">45</int>
>       <int name="nine_11">5</int>
>     </lst>
>     <lst name="f9_ws">
>       <int name="nine_1">45</int>
>       <int name="nine_11">5</int>
>     </lst>
>     <lst name="f9_ws">
>       <int name="nine_1">45</int>
>       <int name="nine_11">5</int>
>     </lst>
>   </lst>
>   <lst name="facet_dates"/>
>   <lst name="facet_ranges"/>
> </lst>
> </response> 
> {code}
> - *Now, if a create a new collection with 2 shards (>1 shard SolrCloud), the 
> same above query results in a different output. (# facet fields ~ 10 ;  
> Expected 50)*
> {code}
> $ curl  
> "http://localhost:8983/solr/collection1/select?facet=true&fl=id&indent=true&q=id%3A*&facet.limit=-1&facet.threads=1000&facet.field=f0_ws&facet.field=f0_ws&facet.field=f0_ws&facet.field=f0_ws&facet.field=f0_ws&facet.field=f1_ws&facet.field=f1_ws&facet.field=f1_ws&facet.field=f1_ws&facet.field=f1_ws&facet.field=f2_ws&facet.field=f2_ws&facet.field=f2_ws&facet.field=f2_ws&facet.field=f2_ws&facet.field=f3_ws&facet.field=f3_ws&facet.field=f3_ws&facet.field=f3_ws&facet.field=f3_ws&facet.field=f4_ws&facet.field=f4_ws&facet.field=f4_ws&facet.field=f4_ws&facet.field=f4_ws&facet.field=f5_ws&facet.field=f5_ws&facet.field=f5_ws&facet.field=f5_ws&facet.field=f5_ws&facet.field=f6_ws&facet.field=f6_ws&facet.field=f6_ws&facet.field=f6_ws&facet.field=f6_ws&facet.field=f7_ws&facet.field=f7_ws&facet.field=f7_ws&facet.field=f7_ws&facet.field=f7_ws&facet.field=f8_ws&facet.field=f8_ws&facet.field=f8_ws&facet.field=f8_ws&facet.field=f8_ws&facet.field=f9_ws&facet.field=f9_ws&facet.field=f9_ws&facet.field=f9_ws&facet.field=f9_ws&rows=1&wt=xml";
>  
> <?xml version="1.0" encoding="UTF-8"?>
> <response>
> <lst name="responseHeader">
>   <int name="status">0</int>
>   <int name="QTime">31</int>
>   <lst name="params">
>     <str name="facet">true</str>
>     <str name="fl">id</str>
>     <str name="indent">true</str>
>     <str name="q">id:*</str>
>     <str name="facet.limit">-1</str>
>     <str name="facet.threads">1000</str>
>     <arr name="facet.field">
>       <str>f0_ws</str>
>       <str>f0_ws</str>
>       <str>f0_ws</str>
>       <str>f0_ws</str>
>       <str>f0_ws</str>
>       <str>f1_ws</str>
>       <str>f1_ws</str>
>       <str>f1_ws</str>
>       <str>f1_ws</str>
>       <str>f1_ws</str>
>       <str>f2_ws</str>
>       <str>f2_ws</str>
>       <str>f2_ws</str>
>       <str>f2_ws</str>
>       <str>f2_ws</str>
>       <str>f3_ws</str>
>       <str>f3_ws</str>
>       <str>f3_ws</str>
>       <str>f3_ws</str>
>       <str>f3_ws</str>
>       <str>f4_ws</str>
>       <str>f4_ws</str>
>       <str>f4_ws</str>
>       <str>f4_ws</str>
>       <str>f4_ws</str>
>       <str>f5_ws</str>
>       <str>f5_ws</str>
>       <str>f5_ws</str>
>       <str>f5_ws</str>
>       <str>f5_ws</str>
>       <str>f6_ws</str>
>       <str>f6_ws</str>
>       <str>f6_ws</str>
>       <str>f6_ws</str>
>       <str>f6_ws</str>
>       <str>f7_ws</str>
>       <str>f7_ws</str>
>       <str>f7_ws</str>
>       <str>f7_ws</str>
>       <str>f7_ws</str>
>       <str>f8_ws</str>
>       <str>f8_ws</str>
>       <str>f8_ws</str>
>       <str>f8_ws</str>
>       <str>f8_ws</str>
>       <str>f9_ws</str>
>       <str>f9_ws</str>
>       <str>f9_ws</str>
>       <str>f9_ws</str>
>       <str>f9_ws</str>
>     </arr>
>     <str name="wt">xml</str>
>     <str name="rows">1</str>
>   </lst>
> </lst>
> <result name="response" numFound="50" start="0" maxScore="1.0">
>   <doc>
>     <float name="id">2.0</float></doc>
> </result>
> <lst name="facet_counts">
>   <lst name="facet_queries"/>
>   <lst name="facet_fields">
>     <lst name="f0_ws">
>       <int name="zero_1">25</int>
>       <int name="zero_2">25</int>
>     </lst>
>     <lst name="f1_ws">
>       <int name="one_1">33</int>
>       <int name="one_3">17</int>
>     </lst>
>     <lst name="f2_ws">
>       <int name="two_1">37</int>
>       <int name="two_4">13</int>
>     </lst>
>     <lst name="f3_ws">
>       <int name="three_1">40</int>
>       <int name="three_5">10</int>
>     </lst>
>     <lst name="f4_ws">
>       <int name="four_1">41</int>
>       <int name="four_6">9</int>
>     </lst>
>     <lst name="f5_ws">
>       <int name="five_1">42</int>
>       <int name="five_7">8</int>
>     </lst>
>     <lst name="f6_ws">
>       <int name="six_1">43</int>
>       <int name="six_8">7</int>
>     </lst>
>     <lst name="f7_ws">
>       <int name="seven_1">44</int>
>       <int name="seven_9">6</int>
>     </lst>
>     <lst name="f8_ws">
>       <int name="eight_1">45</int>
>       <int name="eight_10">5</int>
>     </lst>
>     <lst name="f9_ws">
>       <int name="nine_1">45</int>
>       <int name="nine_11">5</int>
>     </lst>
>   </lst>
>   <lst name="facet_dates"/>
>   <lst name="facet_ranges"/>
> </lst>
> </response>
> {code}
> This behavior is quite strange as it is being dependent on the number of 
> shards in SolrCloud. It would be great if someone can shed some light on this?



--
This message was sent by Atlassian JIRA
(v6.2#6252)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@lucene.apache.org
For additional commands, e-mail: dev-h...@lucene.apache.org

Reply via email to