SOLR-12375: Optimize Lucene ScoreMode use:

* A non-cached filter query could be told incorrectly that scores were needed.
* The /export (ExportQParserPlugin) would declare incorrectly that scores are needed.
* Expanded docs (expand component) could be told incorrectly that scores are needed.
This commit is contained in:
David Smiley 2018-05-23 15:37:33 -04:00
parent d32ce81eab
commit 53a3de3b98
5 changed files with 40 additions and 25 deletions

View File

@ -256,6 +256,11 @@ Optimizations
* SOLR-11880: Avoid creating new exceptions for every request made to MDCAwareThreadPoolExecutor by distributed
search and update operations. (Varun Thacker, shalin)
* SOLR-12375: Optimize Lucene ScoreMode use:
A non-cached filter query could be told incorrectly that scores were needed.
The /export (ExportQParserPlugin) would declare incorrectly that scores are needed.
Expanded docs (expand component) could be told incorrectly that scores are needed. (David Smiley)
Other Changes
----------------------

View File

@ -551,11 +551,6 @@ public class ExpandComponent extends SearchComponent implements PluginInfoInitia
}
}
@Override
public ScoreMode scoreMode() {
return ScoreMode.COMPLETE; // TODO: is this always true?
}
public LeafCollector getLeafCollector(LeafReaderContext context) throws IOException {
final int docBase = context.docBase;
@ -634,11 +629,6 @@ public class ExpandComponent extends SearchComponent implements PluginInfoInitia
this.field = field;
this.collapsedSet = collapsedSet;
}
@Override
public ScoreMode scoreMode() {
return ScoreMode.COMPLETE; // TODO: is this always true?
}
public LeafCollector getLeafCollector(LeafReaderContext context) throws IOException {
final int docBase = context.docBase;
@ -683,8 +673,19 @@ public class ExpandComponent extends SearchComponent implements PluginInfoInitia
}
private interface GroupCollector {
//TODO lets just do simple abstract base class -- a fine use of inheritance
private interface GroupCollector extends Collector {
public LongObjectMap<Collector> getGroups();
@Override
default ScoreMode scoreMode() {
final LongObjectMap<Collector> groups = getGroups();
if (groups.isEmpty()) {
return ScoreMode.COMPLETE; // doesn't matter?
} else {
return groups.iterator().next().value.scoreMode(); // we assume all the collectors should have the same nature
}
}
}
private Query getGroupQuery(String fname,

View File

@ -16,19 +16,27 @@
*/
package org.apache.solr.search;
import org.apache.lucene.util.FixedBitSet;
import org.apache.solr.handler.component.MergeStrategy;
import org.apache.solr.request.SolrRequestInfo;
import org.apache.lucene.search.*;
import org.apache.lucene.index.*;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.common.params.SolrParams;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.LeafCollector;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.TopDocsCollector;
import org.apache.lucene.search.Weight;
import org.apache.lucene.util.FixedBitSet;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.handler.component.MergeStrategy;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestInfo;
public class ExportQParserPlugin extends QParserPlugin {
public static final String NAME = "xport";
@ -73,7 +81,7 @@ public class ExportQParserPlugin extends QParserPlugin {
@Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException{
return mainQuery.createWeight(searcher, ScoreMode.COMPLETE, boost);
return mainQuery.createWeight(searcher, scoreMode, boost);
}
public Query rewrite(IndexReader reader) throws IOException {
@ -177,7 +185,7 @@ public class ExportQParserPlugin extends QParserPlugin {
@Override
public ScoreMode scoreMode() {
return ScoreMode.COMPLETE; // TODO: is this the case?
return ScoreMode.COMPLETE_NO_SCORES;
}
}

View File

@ -65,6 +65,7 @@ public class ReRankCollector extends TopDocsCollector {
this.mainCollector = TopScoreDocCollector.create(Math.max(this.reRankDocs, length));
} else {
sort = sort.rewrite(searcher);
//scores are needed for Rescorer (regardless of whether sort needs it)
this.mainCollector = TopFieldCollector.create(sort, Math.max(this.reRankDocs, length), false, true, true, true);
}
this.searcher = searcher;
@ -82,7 +83,7 @@ public class ReRankCollector extends TopDocsCollector {
@Override
public ScoreMode scoreMode() {
return ScoreMode.COMPLETE;
return ScoreMode.COMPLETE; // since the scores will be needed by Rescorer as input regardless of mainCollector
}
public TopDocs topDocs(int start, int howMany) {

View File

@ -1061,7 +1061,7 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
List<Weight> weights = new ArrayList<>(notCached.size());
for (Query q : notCached) {
Query qq = QueryUtils.makeQueryable(q);
weights.add(createWeight(rewrite(qq), ScoreMode.COMPLETE, 1));
weights.add(createWeight(rewrite(qq), ScoreMode.COMPLETE_NO_SCORES, 1));
}
pf.filter = new FilterImpl(answer, weights);
pf.hasDeletedDocs = (answer == null); // if all clauses were uncached, the resulting filter may match deleted docs
@ -1672,7 +1672,7 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
@Override
public ScoreMode scoreMode() {
return ScoreMode.COMPLETE;
return ScoreMode.TOP_SCORES;
}
};