mirror of https://github.com/apache/lucene.git
SOLR-13289: Rename minExactHits to minExactCount (#1511)
This commit is contained in:
parent
5e9483e788
commit
3ca7628c43
|
@ -133,7 +133,7 @@ Optimizations
|
|||
|
||||
* LUCENE-7788: fail precommit on unparameterised log messages and examine for wasted work/objects (Erick Erickson)
|
||||
|
||||
* SOLR-13289: When the "minExactHits" parameters is provided in queries and it's value is lower than the number of hits,
|
||||
* SOLR-13289: When the "minExactCount" parameters is provided in queries and it's value is lower than the number of hits,
|
||||
Solr can speedup the query resolution by using the Block-Max WAND algorithm (see LUCENE-8135). When doing this, the
|
||||
value of matching documents in the response (numFound) will be an approximation.
|
||||
(Ishan Chattopadhyaya, Munendra S N, Tomás Fernández Löbbe, David Smiley)
|
||||
|
|
|
@ -366,7 +366,7 @@ public class QueryComponent extends SearchComponent
|
|||
|
||||
QueryCommand cmd = rb.createQueryCommand();
|
||||
cmd.setTimeAllowed(timeAllowed);
|
||||
cmd.setMinExactHits(getMinExactHits(params));
|
||||
cmd.setMinExactCount(getMinExactCount(params));
|
||||
|
||||
req.getContext().put(SolrIndexSearcher.STATS_SOURCE, statsCache.get(req));
|
||||
|
||||
|
@ -403,12 +403,12 @@ public class QueryComponent extends SearchComponent
|
|||
doProcessUngroupedSearch(rb, cmd, result);
|
||||
}
|
||||
|
||||
private int getMinExactHits(SolrParams params) {
|
||||
long minExactHits = params.getLong(CommonParams.MIN_EXACT_HITS, Integer.MAX_VALUE);
|
||||
if (minExactHits < 0 || minExactHits > Integer.MAX_VALUE) {
|
||||
minExactHits = Integer.MAX_VALUE;
|
||||
private int getMinExactCount(SolrParams params) {
|
||||
long minExactCount = params.getLong(CommonParams.MIN_EXACT_COUNT, Integer.MAX_VALUE);
|
||||
if (minExactCount < 0 || minExactCount > Integer.MAX_VALUE) {
|
||||
minExactCount = Integer.MAX_VALUE;
|
||||
}
|
||||
return (int)minExactHits;
|
||||
return (int)minExactCount;
|
||||
}
|
||||
|
||||
protected void doFieldSortValues(ResponseBuilder rb, SolrIndexSearcher searcher) throws IOException
|
||||
|
|
|
@ -37,7 +37,7 @@ public class QueryCommand {
|
|||
private int supersetMaxDoc;
|
||||
private int flags;
|
||||
private long timeAllowed = -1;
|
||||
private int minExactHits = Integer.MAX_VALUE;
|
||||
private int minExactCount = Integer.MAX_VALUE;
|
||||
private CursorMark cursorMark;
|
||||
|
||||
public CursorMark getCursorMark() {
|
||||
|
@ -184,12 +184,12 @@ public class QueryCommand {
|
|||
return this;
|
||||
}
|
||||
|
||||
public int getMinExactHits() {
|
||||
return minExactHits;
|
||||
public int getMinExactCount() {
|
||||
return minExactCount;
|
||||
}
|
||||
|
||||
public QueryCommand setMinExactHits(int hits) {
|
||||
this.minExactHits = hits;
|
||||
public QueryCommand setMinExactCount(int count) {
|
||||
this.minExactCount = count;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ public final class QueryResultKey implements Accountable {
|
|||
final SortField[] sfields;
|
||||
final List<Query> filters;
|
||||
final int nc_flags; // non-comparable flags... ignored by hashCode and equals
|
||||
final int minExactHits;
|
||||
final int minExactCount;
|
||||
|
||||
private final int hc; // cached hashCode
|
||||
private final long ramBytesUsed; // cached
|
||||
|
@ -48,12 +48,12 @@ public final class QueryResultKey implements Accountable {
|
|||
this(query, filters, sort, nc_flags, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
public QueryResultKey(Query query, List<Query> filters, Sort sort, int nc_flags, int minExactHits) {
|
||||
public QueryResultKey(Query query, List<Query> filters, Sort sort, int nc_flags, int minExactCount) {
|
||||
this.query = query;
|
||||
this.sort = sort;
|
||||
this.filters = filters;
|
||||
this.nc_flags = nc_flags;
|
||||
this.minExactHits = minExactHits;
|
||||
this.minExactCount = minExactCount;
|
||||
|
||||
int h = query.hashCode();
|
||||
|
||||
|
@ -70,7 +70,7 @@ public final class QueryResultKey implements Accountable {
|
|||
h = h*29 + sf.hashCode();
|
||||
ramSfields += BASE_SF_RAM_BYTES_USED + RamUsageEstimator.sizeOfObject(sf.getField());
|
||||
}
|
||||
h = h*31 + minExactHits;
|
||||
h = h*31 + minExactCount;
|
||||
|
||||
hc = h;
|
||||
|
||||
|
@ -102,7 +102,7 @@ public final class QueryResultKey implements Accountable {
|
|||
if (this.sfields.length != other.sfields.length) return false;
|
||||
if (!this.query.equals(other.query)) return false;
|
||||
if (!unorderedCompare(this.filters, other.filters)) return false;
|
||||
if (this.minExactHits != other.minExactHits) return false;
|
||||
if (this.minExactCount != other.minExactCount) return false;
|
||||
|
||||
for (int i=0; i<sfields.length; i++) {
|
||||
SortField sf1 = this.sfields[i];
|
||||
|
|
|
@ -1308,7 +1308,7 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
|
|||
&& (flags & (NO_CHECK_QCACHE | NO_SET_QCACHE)) != ((NO_CHECK_QCACHE | NO_SET_QCACHE))) {
|
||||
// all of the current flags can be reused during warming,
|
||||
// so set all of them on the cache key.
|
||||
key = new QueryResultKey(q, cmd.getFilterList(), cmd.getSort(), flags, cmd.getMinExactHits());
|
||||
key = new QueryResultKey(q, cmd.getFilterList(), cmd.getSort(), flags, cmd.getMinExactCount());
|
||||
if ((flags & NO_CHECK_QCACHE) == 0) {
|
||||
superset = queryResultCache.get(key);
|
||||
|
||||
|
@ -1485,7 +1485,7 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
|
|||
* The Command whose properties should determine the type of TopDocsCollector to use.
|
||||
*/
|
||||
private TopDocsCollector buildTopDocsCollector(int len, QueryCommand cmd) throws IOException {
|
||||
int minNumFound = cmd.getMinExactHits();
|
||||
int minNumFound = cmd.getMinExactCount();
|
||||
Query q = cmd.getQuery();
|
||||
if (q instanceof RankQuery) {
|
||||
RankQuery rq = (RankQuery) q;
|
||||
|
@ -1628,7 +1628,7 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
|
|||
|
||||
boolean needScores = (cmd.getFlags() & GET_SCORES) != 0;
|
||||
int maxDoc = maxDoc();
|
||||
cmd.setMinExactHits(Integer.MAX_VALUE);// We need the full DocSet
|
||||
cmd.setMinExactCount(Integer.MAX_VALUE);// We need the full DocSet
|
||||
|
||||
ProcessedFilter pf = getProcessedFilter(cmd.getFilter(), cmd.getFilterList());
|
||||
final Query query = QueryUtils.combineQueryAndFilter(QueryUtils.makeQueryable(cmd.getQuery()), pf.filter);
|
||||
|
|
|
@ -211,7 +211,7 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase {
|
|||
query("q","*:*", "sort","n_tl1 desc");
|
||||
|
||||
handle.put("maxScore", SKIPVAL);
|
||||
testMinExactHits();
|
||||
testMinExactCount();
|
||||
|
||||
query("q","{!func}"+i1);// does not expect maxScore. So if it comes ,ignore it. JavaBinCodec.writeSolrDocumentList()
|
||||
//is agnostic of request params.
|
||||
|
@ -1090,13 +1090,13 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase {
|
|||
"stats.facet", fieldName);
|
||||
}
|
||||
|
||||
private void testMinExactHits() throws Exception {
|
||||
assertIsExactHitCount("q","{!cache=false}dog OR men OR cow OR country OR dumpty", CommonParams.MIN_EXACT_HITS, "200", CommonParams.ROWS, "2", CommonParams.SORT, "score desc, id asc");
|
||||
assertIsExactHitCount("q","{!cache=false}dog OR men OR cow OR country OR dumpty", CommonParams.MIN_EXACT_HITS, "-1", CommonParams.ROWS, "2", CommonParams.SORT, "score desc, id asc");
|
||||
assertIsExactHitCount("q","{!cache=false}dog OR men OR cow OR country OR dumpty", CommonParams.MIN_EXACT_HITS, "1", CommonParams.ROWS, "200", CommonParams.SORT, "score desc, id asc");
|
||||
assertIsExactHitCount("q","{!cache=false}dog OR men OR cow OR country OR dumpty", "facet", "true", "facet.field", s1, CommonParams.MIN_EXACT_HITS,"1", CommonParams.ROWS, "200", CommonParams.SORT, "score desc, id asc");
|
||||
assertIsExactHitCount("q","{!cache=false}id:1", CommonParams.MIN_EXACT_HITS,"1", CommonParams.ROWS, "1");
|
||||
assertApproximatedHitCount("q","{!cache=false}dog OR men OR cow OR country OR dumpty", CommonParams.MIN_EXACT_HITS,"2", CommonParams.ROWS, "2", CommonParams.SORT, "score desc, id asc");
|
||||
private void testMinExactCount() throws Exception {
|
||||
assertIsExactHitCount("q","{!cache=false}dog OR men OR cow OR country OR dumpty", CommonParams.MIN_EXACT_COUNT, "200", CommonParams.ROWS, "2", CommonParams.SORT, "score desc, id asc");
|
||||
assertIsExactHitCount("q","{!cache=false}dog OR men OR cow OR country OR dumpty", CommonParams.MIN_EXACT_COUNT, "-1", CommonParams.ROWS, "2", CommonParams.SORT, "score desc, id asc");
|
||||
assertIsExactHitCount("q","{!cache=false}dog OR men OR cow OR country OR dumpty", CommonParams.MIN_EXACT_COUNT, "1", CommonParams.ROWS, "200", CommonParams.SORT, "score desc, id asc");
|
||||
assertIsExactHitCount("q","{!cache=false}dog OR men OR cow OR country OR dumpty", "facet", "true", "facet.field", s1, CommonParams.MIN_EXACT_COUNT,"1", CommonParams.ROWS, "200", CommonParams.SORT, "score desc, id asc");
|
||||
assertIsExactHitCount("q","{!cache=false}id:1", CommonParams.MIN_EXACT_COUNT,"1", CommonParams.ROWS, "1");
|
||||
assertApproximatedHitCount("q","{!cache=false}dog OR men OR cow OR country OR dumpty", CommonParams.MIN_EXACT_COUNT,"2", CommonParams.ROWS, "2", CommonParams.SORT, "score desc, id asc");
|
||||
}
|
||||
|
||||
private void assertIsExactHitCount(Object... requestParams) throws Exception {
|
||||
|
|
|
@ -950,7 +950,7 @@ public class TestGroupingSearch extends SolrTestCaseJ4 {
|
|||
}
|
||||
ModifiableSolrParams params = new ModifiableSolrParams();
|
||||
params.set("q", FOO_STRING_FIELD + ":Book1");
|
||||
assertQ(req(params, CommonParams.MIN_EXACT_HITS, "2", CommonParams.ROWS, "2")
|
||||
assertQ(req(params, CommonParams.MIN_EXACT_COUNT, "2", CommonParams.ROWS, "2")
|
||||
,"/response/result[@numFoundExact='false']"
|
||||
);
|
||||
params.set("group", true);
|
||||
|
@ -959,7 +959,7 @@ public class TestGroupingSearch extends SolrTestCaseJ4 {
|
|||
,"/response/lst[@name='grouped']/lst[@name='"+FOO_STRING_FIELD+"']/arr[@name='groups']/lst[1]/result[@numFoundExact='true']"
|
||||
);
|
||||
|
||||
assertQ(req(params, CommonParams.MIN_EXACT_HITS, "2", CommonParams.ROWS, "2")
|
||||
assertQ(req(params, CommonParams.MIN_EXACT_COUNT, "2", CommonParams.ROWS, "2")
|
||||
,"/response/lst[@name='grouped']/lst[@name='"+FOO_STRING_FIELD+"']/arr[@name='groups']/lst[1]/result[@numFoundExact='true']"
|
||||
);
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ public class QueryResultKeyTest extends SolrTestCaseJ4 {
|
|||
assert minIters <= iter;
|
||||
}
|
||||
|
||||
public void testMinExactHits() {
|
||||
public void testMinExactCount() {
|
||||
int[] nums = smallArrayOfRandomNumbers();
|
||||
final Query base = new FlatHashTermQuery("base");
|
||||
assertKeyEquals(new QueryResultKey(base, buildFiltersFromNumbers(nums), null, 0, 10),
|
||||
|
|
|
@ -935,7 +935,7 @@ public class TestFaceting extends SolrTestCaseJ4 {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testFacetCountsWithMinExactHits() throws Exception {
|
||||
public void testFacetCountsWithMinExactCount() throws Exception {
|
||||
final int NUM_DOCS = 20;
|
||||
for (int i = 0; i < NUM_DOCS ; i++) {
|
||||
assertU(adoc("id", String.valueOf(i), "title_ws", "Book1"));
|
||||
|
@ -950,8 +950,8 @@ public class TestFaceting extends SolrTestCaseJ4 {
|
|||
,"//*[@numFoundExact='true']"
|
||||
,"//*[@numFound='" + NUM_DOCS + "']");
|
||||
|
||||
// It doesn't matter if we request minExactHits, when requesting facets, the numFound value is precise
|
||||
assertQ(req(params, CommonParams.MIN_EXACT_HITS, "2", CommonParams.ROWS, "2"),
|
||||
// It doesn't matter if we request minExactCount, when requesting facets, the numFound value is precise
|
||||
assertQ(req(params, CommonParams.MIN_EXACT_COUNT, "2", CommonParams.ROWS, "2"),
|
||||
"//lst[@name='facet_fields']/lst[@name='title_ws']/int[1][@name='Book1'][.='20']"
|
||||
,"//*[@numFoundExact='true']"
|
||||
,"//*[@numFound='" + NUM_DOCS + "']");
|
||||
|
|
|
@ -65,27 +65,27 @@ public class SolrIndexSearcherTest extends SolrTestCaseJ4 {
|
|||
super.setUp();
|
||||
}
|
||||
|
||||
public void testMinExactHitsLongValue() {
|
||||
public void testMinExactCountLongValue() {
|
||||
assertQ("test query on empty index",
|
||||
req("q", "field1_s:foo",
|
||||
"minExactHits", Long.toString(10L * Integer.MAX_VALUE),
|
||||
"minExactCount", Long.toString(10L * Integer.MAX_VALUE),
|
||||
"rows", "2")
|
||||
,"//*[@numFoundExact='true']"
|
||||
,"//*[@numFound='" + NUM_DOCS + "']"
|
||||
);
|
||||
}
|
||||
|
||||
public void testMinExactHits() {
|
||||
assertQ("minExactHits is lower than numFound,should produce approximated results",
|
||||
public void testMinExactCount() {
|
||||
assertQ("minExactCount is lower than numFound,should produce approximated results",
|
||||
req("q", "field1_s:foo",
|
||||
"minExactHits", "2",
|
||||
"minExactCount", "2",
|
||||
"rows", "2")
|
||||
,"//*[@numFoundExact='false']"
|
||||
,"//*[@numFound<='" + NUM_DOCS + "']"
|
||||
);
|
||||
assertQ("minExactHits is higher than numFound,should produce exact results",
|
||||
assertQ("minExactCount is higher than numFound,should produce exact results",
|
||||
req("q", "field1_s:foo",
|
||||
"minExactHits", "200",
|
||||
"minExactCount", "200",
|
||||
"rows", "2")
|
||||
,"//*[@numFoundExact='true']"
|
||||
,"//*[@numFound='" + NUM_DOCS + "']"
|
||||
|
@ -108,7 +108,7 @@ public class SolrIndexSearcherTest extends SolrTestCaseJ4 {
|
|||
return qr;
|
||||
}
|
||||
|
||||
public void testLowMinExactHitsGeneratesApproximation() throws IOException {
|
||||
public void testLowMinExactCountGeneratesApproximation() throws IOException {
|
||||
h.getCore().withSearcher(searcher -> {
|
||||
QueryCommand cmd = createBasicQueryCommand(NUM_DOCS / 2, 10, "field1_s", "foo");
|
||||
assertMatchesGreaterThan(NUM_DOCS, searcher, cmd);
|
||||
|
@ -122,7 +122,7 @@ public class SolrIndexSearcherTest extends SolrTestCaseJ4 {
|
|||
});
|
||||
}
|
||||
|
||||
public void testHighMinExactHitsGeneratesExactCount() throws IOException {
|
||||
public void testHighMinExactCountGeneratesExactCount() throws IOException {
|
||||
h.getCore().withSearcher(searcher -> {
|
||||
QueryCommand cmd = createBasicQueryCommand(NUM_DOCS, 10, "field1_s", "foo");
|
||||
assertMatchesEqual(NUM_DOCS, searcher, cmd);
|
||||
|
@ -138,7 +138,7 @@ public class SolrIndexSearcherTest extends SolrTestCaseJ4 {
|
|||
|
||||
|
||||
|
||||
public void testLowMinExactHitsWithQueryResultCache() throws IOException {
|
||||
public void testLowMinExactCountWithQueryResultCache() throws IOException {
|
||||
h.getCore().withSearcher(searcher -> {
|
||||
QueryCommand cmd = createBasicQueryCommand(NUM_DOCS / 2, 10, "field1_s", "foo");
|
||||
cmd.clearFlags(SolrIndexSearcher.NO_CHECK_QCACHE | SolrIndexSearcher.NO_SET_QCACHE);
|
||||
|
@ -148,7 +148,7 @@ public class SolrIndexSearcherTest extends SolrTestCaseJ4 {
|
|||
});
|
||||
}
|
||||
|
||||
public void testHighMinExactHitsWithQueryResultCache() throws IOException {
|
||||
public void testHighMinExactCountWithQueryResultCache() throws IOException {
|
||||
h.getCore().withSearcher(searcher -> {
|
||||
QueryCommand cmd = createBasicQueryCommand(NUM_DOCS, 2, "field1_s", "foo");
|
||||
cmd.clearFlags(SolrIndexSearcher.NO_CHECK_QCACHE | SolrIndexSearcher.NO_SET_QCACHE);
|
||||
|
@ -158,7 +158,7 @@ public class SolrIndexSearcherTest extends SolrTestCaseJ4 {
|
|||
});
|
||||
}
|
||||
|
||||
public void testMinExactHitsMoreRows() throws IOException {
|
||||
public void testMinExactCountMoreRows() throws IOException {
|
||||
h.getCore().withSearcher(searcher -> {
|
||||
QueryCommand cmd = createBasicQueryCommand(2, NUM_DOCS, "field1_s", "foo");
|
||||
assertMatchesEqual(NUM_DOCS, searcher, cmd);
|
||||
|
@ -166,7 +166,7 @@ public class SolrIndexSearcherTest extends SolrTestCaseJ4 {
|
|||
});
|
||||
}
|
||||
|
||||
public void testMinExactHitsMatchWithDocSet() throws IOException {
|
||||
public void testMinExactCountMatchWithDocSet() throws IOException {
|
||||
h.getCore().withSearcher(searcher -> {
|
||||
QueryCommand cmd = createBasicQueryCommand(2, 2, "field1_s", "foo");
|
||||
assertMatchesGreaterThan(NUM_DOCS, searcher, cmd);
|
||||
|
@ -177,7 +177,7 @@ public class SolrIndexSearcherTest extends SolrTestCaseJ4 {
|
|||
});
|
||||
}
|
||||
|
||||
public void testMinExactHitsWithMaxScoreRequested() throws IOException {
|
||||
public void testMinExactCountWithMaxScoreRequested() throws IOException {
|
||||
h.getCore().withSearcher(searcher -> {
|
||||
QueryCommand cmd = createBasicQueryCommand(2, 2, "field1_s", "foo");
|
||||
cmd.setFlags(SolrIndexSearcher.GET_SCORES);
|
||||
|
@ -248,9 +248,9 @@ public class SolrIndexSearcherTest extends SolrTestCaseJ4 {
|
|||
});
|
||||
}
|
||||
|
||||
private QueryCommand createBasicQueryCommand(int minExactHits, int length, String field, String q) {
|
||||
private QueryCommand createBasicQueryCommand(int minExactCount, int length, String field, String q) {
|
||||
QueryCommand cmd = new QueryCommand();
|
||||
cmd.setMinExactHits(minExactHits);
|
||||
cmd.setMinExactCount(minExactCount);
|
||||
cmd.setLen(length);
|
||||
cmd.setFlags(SolrIndexSearcher.NO_CHECK_QCACHE | SolrIndexSearcher.NO_SET_QCACHE);
|
||||
cmd.setQuery(new TermQuery(new Term(field, q)));
|
||||
|
|
|
@ -1041,7 +1041,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testMinExactHitsDisabledByCollapse() throws Exception {
|
||||
public void testMinExactCountDisabledByCollapse() throws Exception {
|
||||
int numDocs = 10;
|
||||
String collapseFieldInt = "field_ti_dv";
|
||||
String collapseFieldFloat = "field_tf_dv";
|
||||
|
@ -1060,7 +1060,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
|
|||
assertQ(req(
|
||||
"q", "{!cache=false}field_s:1",
|
||||
"rows", "1",
|
||||
"minExactHits", "1",
|
||||
"minExactCount", "1",
|
||||
// this collapse will end up matching all docs
|
||||
"fq", "{!collapse field=" + collapseField + " nullPolicy=expand}"// nullPolicy needed due to a bug when val=0
|
||||
),"//*[@numFoundExact='true']"
|
||||
|
|
|
@ -164,10 +164,10 @@ public interface CommonParams {
|
|||
String TIME_ALLOWED = "timeAllowed";
|
||||
|
||||
/**
|
||||
* The number of hits that need to be counted accurately. If more than {@link #MIN_EXACT_HITS} documents
|
||||
* The number of hits that need to be counted accurately. If more than {@link #MIN_EXACT_COUNT} documents
|
||||
* match a query, then the value in "numFound" may be an estimate to speedup search.
|
||||
*/
|
||||
String MIN_EXACT_HITS = "minExactHits";
|
||||
String MIN_EXACT_COUNT = "minExactCount";
|
||||
|
||||
/** 'true' if the header should include the handler name */
|
||||
String HEADER_ECHO_HANDLER = "echoHandler";
|
||||
|
|
|
@ -34,5 +34,5 @@ public class CommonParamsTest extends SolrTestCase
|
|||
|
||||
public void testPreferLocalShards() { assertEquals("preferLocalShards", CommonParams.PREFER_LOCAL_SHARDS); }
|
||||
|
||||
public void testMinExactHits() { assertEquals("minExactHits", CommonParams.MIN_EXACT_HITS); }
|
||||
public void testMinExactCount() { assertEquals("minExactCount", CommonParams.MIN_EXACT_COUNT); }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue