SOLR-6314: Multi-threaded facet counts differ when SolrCloud has >1 shard

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1618716 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Erick Erickson 2014-08-18 19:45:17 +00:00
parent 46d60dadb4
commit 3b5b5fe94c
4 changed files with 35 additions and 14 deletions

View File

@ -292,6 +292,8 @@ Bug Fixes
* SOLR-6338: coreRootDirectory requires trailing slash, or SolrCloud cores are created in wrong location.
(Primož Skale via Erick Erickson)
* SOLR-6314: Multi-threaded facet counts differ when SolrCloud has >1 shard (Erick Erickson)
Optimizations
---------------------

View File

@ -24,10 +24,11 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
@ -84,8 +85,22 @@ public class FacetComponent extends SearchComponent {
*/
@Override
public void process(ResponseBuilder rb) throws IOException {
//SolrParams params = rb.req.getParams();
if (rb.doFacets) {
SolrParams params = rb.req.getParams();
ModifiableSolrParams params = new ModifiableSolrParams();
SolrParams origParams = rb.req.getParams();
Iterator<String> iter = origParams.getParameterNamesIterator();
while (iter.hasNext()) {
String paramName = iter.next();
// Deduplicate the list with LinkedHashSet, but _only_ for facet params.
if (paramName.startsWith(FacetParams.FACET) == false) {
params.add(paramName, origParams.getParams(paramName));
continue;
}
HashSet<String> deDupe = new LinkedHashSet<>(Arrays.asList(origParams.getParams(paramName)));
params.add(paramName, deDupe.toArray(new String[deDupe.size()]));
}
SimpleFacets f = new SimpleFacets(rb.req, rb.getResults().docSet, params, rb);

View File

@ -168,9 +168,9 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase {
// then the primary sort should always be a tie and then the secondary should always decide
query("q","{!func}ms(NOW)", "sort","score desc,"+i1+" desc","fl","id");
query("q","*:*", "rows",0, "facet","true", "facet.field",t1);
query("q","*:*", "rows",0, "facet","true", "facet.field",t1, "facet.field",t1);
query("q","*:*", "rows",0, "facet","true", "facet.field",t1,"facet.limit",1);
query("q","*:*", "rows",0, "facet","true", "facet.query","quick", "facet.query","all", "facet.query","*:*");
query("q","*:*", "rows",0, "facet","true", "facet.query","quick", "facet.query","quick", "facet.query","all", "facet.query","*:*");
query("q","*:*", "rows",0, "facet","true", "facet.field",t1, "facet.mincount",2);
// a facet query to test out chars out of the ascii range
@ -188,6 +188,7 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase {
// simple date facet on one field
query("q","*:*", "rows",100, "facet","true",
"facet.date",tdate_a,
"facet.date",tdate_a,
"facet.date.other", "all",
"facet.date.start","2010-05-01T11:00:00Z",
@ -198,6 +199,7 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase {
query("q","*:*", "rows",100, "facet","true",
"facet.date",tdate_a,
"facet.date",tdate_b,
"facet.date",tdate_a,
"facet.date.other", "all",
"f."+tdate_b+".facet.date.start","2009-05-01T11:00:00Z",
"f."+tdate_b+".facet.date.gap","+3MONTHS",
@ -207,6 +209,7 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase {
// simple range facet on one field
query("q","*:*", "rows",100, "facet","true",
"facet.range",tlong,
"facet.range",tlong,
"facet.range.start",200,
"facet.range.gap",100,
@ -378,6 +381,7 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase {
"q","*:*",
"facet","true",
"facet.field",t1,
"facet.field",t1,
"facet.limit",5,
ShardParams.SHARDS_INFO,"true",
ShardParams.SHARDS_TOLERANT,"true");
@ -386,6 +390,7 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase {
"q", "*:*",
"facet", "true",
"facet.query", i1 + ":[1 TO 50]",
"facet.query", i1 + ":[1 TO 50]",
ShardParams.SHARDS_INFO, "true",
ShardParams.SHARDS_TOLERANT, "true");

View File

@ -713,8 +713,8 @@ public class TestFaceting extends SolrTestCaseJ4 {
, "facet.threads", "1000"
, "facet.limit", "-1"
)
, "*[count(//lst[@name='facet_fields']/lst)=50]"
, "*[count(//lst[@name='facet_fields']/lst/int)=100]"
, "*[count(//lst[@name='facet_fields']/lst)=10]"
, "*[count(//lst[@name='facet_fields']/lst/int)=20]"
);
}
@ -859,8 +859,7 @@ public class TestFaceting extends SolrTestCaseJ4 {
);
// After this all, the uninverted fields should be exactly the same as they were the first time, even if we
// blast a whole bunch of identical fields at the facet code. Which, BTW, doesn't detect
// if you've asked for the same field more than once.
// blast a whole bunch of identical fields at the facet code.
// The way fetching the uninverted field is written, all this is really testing is if the cache is working.
// It's NOT testing whether the pending/sleep is actually functioning, I had to do that by hand since I don't
// see how to make sure that uninverting the field multiple times actually happens to hit the wait state.
@ -920,8 +919,8 @@ public class TestFaceting extends SolrTestCaseJ4 {
, "facet.threads", "1000"
, "facet.limit", "-1"
)
, "*[count(//lst[@name='facet_fields']/lst)=50]"
, "*[count(//lst[@name='facet_fields']/lst/int)=100]"
, "*[count(//lst[@name='facet_fields']/lst)=10]"
, "*[count(//lst[@name='facet_fields']/lst/int)=20]"
);
} finally {
currentSearcherRef.decref();