SOLR-10824: fixing NPE ExactSharedStatsCache, avoid maxdocs skew on

unique terms.
This commit is contained in:
Mikhail Khludnev 2017-06-19 12:28:25 +03:00
parent e43253312f
commit 3b07e7241e
4 changed files with 34 additions and 17 deletions

View File

@ -443,6 +443,9 @@ Bug Fixes
* SOLR-10763: Admin UI replication tab sometimes empty when failed replications (janhoy, Bojan Vitnik)
* SOLR-10824: fix NPE ExactSharedStatsCache, fixing maxdocs skew for terms which are absent at one of shards
when using one of Exact*StatsCache (Mikhail Khludnev)
Optimizations
----------------------
* SOLR-10634: JSON Facet API: When a field/terms facet will retrieve all buckets (i.e. limit:-1)

View File

@ -16,17 +16,17 @@
*/
package org.apache.solr.search.stats;
import java.lang.invoke.MethodHandles;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.solr.core.PluginInfo;
import org.apache.solr.handler.component.ResponseBuilder;
import org.apache.solr.request.SolrQueryRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.invoke.MethodHandles;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
public class ExactSharedStatsCache extends ExactStatsCache {
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@ -73,7 +73,7 @@ public class ExactSharedStatsCache extends ExactStatsCache {
protected TermStats getPerShardTermStats(SolrQueryRequest req, String t, String shard) {
Map<String,TermStats> cache = perShardTermStats.get(shard);
return cache.get(t);
return (cache != null) ? cache.get(t) : null; //Term doesn't exist in shard;
}
protected void addToGlobalColStats(SolrQueryRequest req,

View File

@ -163,6 +163,10 @@ public class ExactStatsCache extends StatsCache {
for (Term t : terms) {
TermContext termContext = TermContext.build(context, t);
if (!colMap.containsKey(t.field())) { // collection stats for this field
colMap.put(t.field(), new CollectionStats(searcher.localCollectionStatistics(t.field())));
}
TermStatistics tst = searcher.localTermStatistics(t, termContext);
if (tst.docFreq() == 0) { // skip terms that are not present here
continue;
@ -170,23 +174,22 @@ public class ExactStatsCache extends StatsCache {
statsMap.put(t.toString(), new TermStats(t.field(), tst));
rb.rsp.add(TERMS_KEY, t.toString());
if (!colMap.containsKey(t.field())) { // collection stats for this field
colMap.put(t.field(), new CollectionStats(searcher.localCollectionStatistics(t.field())));
}
}
if (statsMap.size() != 0 && colMap.size() != 0) { //Don't add empty keys
if (statsMap.size() != 0) { //Don't add empty keys
String termStatsString = StatsUtil.termStatsMapToString(statsMap);
rb.rsp.add(TERM_STATS_KEY, termStatsString);
if (LOG.isDebugEnabled()) {
LOG.debug("termStats=" + termStatsString + ", terms=" + terms + ", numDocs=" + searcher.maxDoc());
}
}
if (colMap.size() != 0){
String colStatsString = StatsUtil.colStatsMapToString(colMap);
rb.rsp.add(COL_STATS_KEY, colStatsString);
if (LOG.isDebugEnabled()) {
LOG.debug("termStats=" + termStatsString + ", collectionStats="
LOG.debug("collectionStats="
+ colStatsString + ", terms=" + terms + ", numDocs=" + searcher.maxDoc());
}
}
} catch (IOException e) {
LOG.error("Error collecting local stats, query='" + q.toString() + "'", e);
throw new SolrException(ErrorCode.SERVER_ERROR, "Error collecting local stats.", e);

View File

@ -40,11 +40,14 @@ public class TestDefaultStatsCache extends BaseDistributedSearchTestCase {
@Test
public void test() throws Exception {
del("*:*");
String aDocId=null;
for (int i = 0; i < clients.size(); i++) {
int shard = i + 1;
for (int j = 0; j <= i; j++) {
index_specific(i, id, docId++, "a_t", "one two three",
int currentId = docId++;
index_specific(i, id,currentId , "a_t", "one two three",
"shard_i", shard);
aDocId = rarely() ? currentId+"":aDocId;
}
}
commit();
@ -52,18 +55,26 @@ public class TestDefaultStatsCache extends BaseDistributedSearchTestCase {
handle.put("QTime", SKIPVAL);
handle.put("timestamp", SKIPVAL);
if (aDocId != null) {
dfQuery("q", "id:"+aDocId, "debugQuery", "true", "fl", "*,score");
}
dfQuery("q", "a_t:one", "debugQuery", "true", "fl", "*,score");
// add another document
for (int i = 0; i < clients.size(); i++) {
int shard = i + 1;
for (int j = 0; j <= i; j++) {
index_specific(i, id, docId++, "a_t", "one two three four five",
int currentId = docId++;
index_specific(i, id, currentId, "a_t", "one two three four five",
"shard_i", shard);
aDocId = rarely() ? currentId+"":aDocId;
}
}
commit();
if (aDocId != null) {
dfQuery("q", "id:"+aDocId,"debugQuery", "true", "fl", "*,score");
}
dfQuery("q", "a_t:one a_t:four", "debugQuery", "true", "fl", "*,score");
}