|
@@ -24,25 +24,21 @@ import org.apache.lucene.document.Document;
|
|
|
import org.apache.lucene.document.Field.Store;
|
|
|
import org.apache.lucene.document.LatLonDocValuesField;
|
|
|
import org.apache.lucene.document.LatLonPoint;
|
|
|
-import org.apache.lucene.document.LongPoint;
|
|
|
import org.apache.lucene.document.NumericDocValuesField;
|
|
|
import org.apache.lucene.document.SortedSetDocValuesField;
|
|
|
import org.apache.lucene.document.StringField;
|
|
|
import org.apache.lucene.document.TextField;
|
|
|
import org.apache.lucene.index.DirectoryReader;
|
|
|
import org.apache.lucene.index.IndexReader;
|
|
|
-import org.apache.lucene.index.IndexWriter;
|
|
|
import org.apache.lucene.index.IndexWriterConfig;
|
|
|
import org.apache.lucene.index.LeafReaderContext;
|
|
|
import org.apache.lucene.index.NoMergePolicy;
|
|
|
import org.apache.lucene.index.RandomIndexWriter;
|
|
|
import org.apache.lucene.index.Term;
|
|
|
import org.apache.lucene.queries.MinDocQuery;
|
|
|
-import org.apache.lucene.search.BooleanClause;
|
|
|
import org.apache.lucene.search.BooleanClause.Occur;
|
|
|
import org.apache.lucene.search.BooleanQuery;
|
|
|
import org.apache.lucene.search.Collector;
|
|
|
-import org.apache.lucene.search.CollectorManager;
|
|
|
import org.apache.lucene.search.ConstantScoreQuery;
|
|
|
import org.apache.lucene.search.DocValuesFieldExistsQuery;
|
|
|
import org.apache.lucene.search.FieldComparator;
|
|
@@ -54,11 +50,9 @@ import org.apache.lucene.search.LeafCollector;
|
|
|
import org.apache.lucene.search.MatchAllDocsQuery;
|
|
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
|
|
import org.apache.lucene.search.Query;
|
|
|
-import org.apache.lucene.search.ScoreDoc;
|
|
|
import org.apache.lucene.search.Sort;
|
|
|
import org.apache.lucene.search.SortField;
|
|
|
import org.apache.lucene.search.TermQuery;
|
|
|
-import org.apache.lucene.search.TopDocs;
|
|
|
import org.apache.lucene.search.TotalHitCountCollector;
|
|
|
import org.apache.lucene.search.TotalHits;
|
|
|
import org.apache.lucene.search.Weight;
|
|
@@ -71,16 +65,11 @@ import org.apache.lucene.util.BytesRef;
|
|
|
import org.apache.lucene.util.FixedBitSet;
|
|
|
import org.elasticsearch.action.search.SearchTask;
|
|
|
import org.elasticsearch.common.settings.Settings;
|
|
|
-import org.elasticsearch.index.mapper.DateFieldMapper;
|
|
|
-import org.elasticsearch.index.mapper.MappedFieldType;
|
|
|
-import org.elasticsearch.index.mapper.MapperService;
|
|
|
-import org.elasticsearch.index.mapper.NumberFieldMapper;
|
|
|
import org.elasticsearch.index.query.ParsedQuery;
|
|
|
import org.elasticsearch.index.search.ESToParentBlockJoinQuery;
|
|
|
import org.elasticsearch.index.shard.IndexShard;
|
|
|
import org.elasticsearch.index.shard.IndexShardTestCase;
|
|
|
import org.elasticsearch.search.DocValueFormat;
|
|
|
-import org.elasticsearch.search.internal.ContextIndexSearcher;
|
|
|
import org.elasticsearch.search.internal.ScrollContext;
|
|
|
import org.elasticsearch.search.internal.SearchContext;
|
|
|
import org.elasticsearch.search.sort.SortAndFormats;
|
|
@@ -91,15 +80,10 @@ import java.util.ArrayList;
|
|
|
import java.util.Collections;
|
|
|
import java.util.List;
|
|
|
|
|
|
-import static org.elasticsearch.search.query.QueryPhase.indexFieldHasDuplicateData;
|
|
|
-import static org.elasticsearch.search.query.TopDocsCollectorContext.hasInfMaxScore;
|
|
|
import static org.hamcrest.Matchers.anyOf;
|
|
|
import static org.hamcrest.Matchers.equalTo;
|
|
|
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
|
|
import static org.hamcrest.Matchers.instanceOf;
|
|
|
-import static org.mockito.Mockito.mock;
|
|
|
-import static org.mockito.Mockito.when;
|
|
|
-import static org.mockito.Mockito.spy;
|
|
|
|
|
|
public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
|
|
@@ -123,17 +107,18 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
}
|
|
|
|
|
|
private void countTestCase(Query query, IndexReader reader, boolean shouldCollectSearch, boolean shouldCollectCount) throws Exception {
|
|
|
- ContextIndexSearcher searcher = shouldCollectSearch ? newContextSearcher(reader) :
|
|
|
- newEarlyTerminationContextSearcher(reader, 0);
|
|
|
- TestSearchContext context = new TestSearchContext(null, indexShard, searcher);
|
|
|
+ TestSearchContext context = new TestSearchContext(null, indexShard);
|
|
|
context.parsedQuery(new ParsedQuery(query));
|
|
|
context.setSize(0);
|
|
|
context.setTask(new SearchTask(123L, "", "", "", null, Collections.emptyMap()));
|
|
|
- final boolean rescore = QueryPhase.executeInternal(context);
|
|
|
- assertFalse(rescore);
|
|
|
|
|
|
- ContextIndexSearcher countSearcher = shouldCollectCount ? newContextSearcher(reader) :
|
|
|
- newEarlyTerminationContextSearcher(reader, 0);
|
|
|
+ final IndexSearcher searcher = shouldCollectSearch ? new IndexSearcher(reader) :
|
|
|
+ getAssertingEarlyTerminationSearcher(reader, 0);
|
|
|
+
|
|
|
+ final boolean rescore = QueryPhase.execute(context, searcher, checkCancelled -> {});
|
|
|
+ assertFalse(rescore);
|
|
|
+ IndexSearcher countSearcher = shouldCollectCount ? new IndexSearcher(reader) :
|
|
|
+ getAssertingEarlyTerminationSearcher(reader, 0);
|
|
|
assertEquals(countSearcher.count(query), context.queryResult().topDocs().topDocs.totalHits.value);
|
|
|
}
|
|
|
|
|
@@ -211,17 +196,17 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
w.close();
|
|
|
|
|
|
IndexReader reader = DirectoryReader.open(dir);
|
|
|
- TestSearchContext context =
|
|
|
- new TestSearchContext(null, indexShard, newEarlyTerminationContextSearcher(reader, 0));
|
|
|
+ IndexSearcher contextSearcher = getAssertingEarlyTerminationSearcher(reader, 0);
|
|
|
+ TestSearchContext context = new TestSearchContext(null, indexShard);
|
|
|
context.setTask(new SearchTask(123L, "", "", "", null, Collections.emptyMap()));
|
|
|
context.parsedQuery(new ParsedQuery(new MatchAllDocsQuery()));
|
|
|
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertEquals(1, context.queryResult().topDocs().topDocs.totalHits.value);
|
|
|
|
|
|
- context.setSearcher(newContextSearcher(reader));
|
|
|
+ contextSearcher = new IndexSearcher(reader);
|
|
|
context.parsedPostFilter(new ParsedQuery(new MatchNoDocsQuery()));
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertEquals(0, context.queryResult().topDocs().topDocs.totalHits.value);
|
|
|
reader.close();
|
|
|
dir.close();
|
|
@@ -241,14 +226,15 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
w.close();
|
|
|
|
|
|
IndexReader reader = DirectoryReader.open(dir);
|
|
|
- TestSearchContext context = new TestSearchContext(null, indexShard, newContextSearcher(reader));
|
|
|
+ IndexSearcher contextSearcher = new IndexSearcher(reader);
|
|
|
+ TestSearchContext context = new TestSearchContext(null, indexShard);
|
|
|
context.setTask(new SearchTask(123L, "", "", "", null, Collections.emptyMap()));
|
|
|
context.parsedQuery(new ParsedQuery(new MatchAllDocsQuery()));
|
|
|
context.terminateAfter(1);
|
|
|
context.setSize(10);
|
|
|
for (int i = 0; i < 10; i++) {
|
|
|
context.parsedPostFilter(new ParsedQuery(new TermQuery(new Term("foo", Integer.toString(i)))));
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertEquals(1, context.queryResult().topDocs().topDocs.totalHits.value);
|
|
|
assertThat(context.queryResult().topDocs().topDocs.scoreDocs.length, equalTo(1));
|
|
|
}
|
|
@@ -267,22 +253,27 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
w.close();
|
|
|
|
|
|
IndexReader reader = DirectoryReader.open(dir);
|
|
|
- TestSearchContext context =
|
|
|
- new TestSearchContext(null, indexShard, newEarlyTerminationContextSearcher(reader, 0));
|
|
|
+ IndexSearcher contextSearcher = getAssertingEarlyTerminationSearcher(reader, 0);
|
|
|
+ TestSearchContext context = new TestSearchContext(null, indexShard);
|
|
|
context.parsedQuery(new ParsedQuery(new MatchAllDocsQuery()));
|
|
|
context.setSize(0);
|
|
|
context.setTask(new SearchTask(123L, "", "", "", null, Collections.emptyMap()));
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertEquals(1, context.queryResult().topDocs().topDocs.totalHits.value);
|
|
|
|
|
|
+ contextSearcher = new IndexSearcher(reader);
|
|
|
context.minimumScore(100);
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertEquals(0, context.queryResult().topDocs().topDocs.totalHits.value);
|
|
|
reader.close();
|
|
|
dir.close();
|
|
|
}
|
|
|
|
|
|
public void testQueryCapturesThreadPoolStats() throws Exception {
|
|
|
+ TestSearchContext context = new TestSearchContext(null, indexShard);
|
|
|
+ context.setTask(new SearchTask(123L, "", "", "", null, Collections.emptyMap()));
|
|
|
+ context.parsedQuery(new ParsedQuery(new MatchAllDocsQuery()));
|
|
|
+
|
|
|
Directory dir = newDirectory();
|
|
|
IndexWriterConfig iwc = newIndexWriterConfig();
|
|
|
RandomIndexWriter w = new RandomIndexWriter(random(), dir, iwc);
|
|
@@ -292,11 +283,9 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
}
|
|
|
w.close();
|
|
|
IndexReader reader = DirectoryReader.open(dir);
|
|
|
- TestSearchContext context = new TestSearchContext(null, indexShard, newContextSearcher(reader));
|
|
|
- context.setTask(new SearchTask(123L, "", "", "", null, Collections.emptyMap()));
|
|
|
- context.parsedQuery(new ParsedQuery(new MatchAllDocsQuery()));
|
|
|
+ IndexSearcher contextSearcher = new IndexSearcher(reader);
|
|
|
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
QuerySearchResult results = context.queryResult();
|
|
|
assertThat(results.serviceTimeEWMA(), greaterThanOrEqualTo(0L));
|
|
|
assertThat(results.nodeQueueSize(), greaterThanOrEqualTo(0));
|
|
@@ -316,7 +305,8 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
}
|
|
|
w.close();
|
|
|
IndexReader reader = DirectoryReader.open(dir);
|
|
|
- TestSearchContext context = new TestSearchContext(null, indexShard, newContextSearcher(reader));
|
|
|
+ IndexSearcher contextSearcher = new IndexSearcher(reader);
|
|
|
+ TestSearchContext context = new TestSearchContext(null, indexShard);
|
|
|
context.parsedQuery(new ParsedQuery(new MatchAllDocsQuery()));
|
|
|
ScrollContext scrollContext = new ScrollContext();
|
|
|
scrollContext.lastEmittedDoc = null;
|
|
@@ -327,14 +317,14 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
int size = randomIntBetween(2, 5);
|
|
|
context.setSize(size);
|
|
|
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertThat(context.queryResult().topDocs().topDocs.totalHits.value, equalTo((long) numDocs));
|
|
|
assertNull(context.queryResult().terminatedEarly());
|
|
|
assertThat(context.terminateAfter(), equalTo(0));
|
|
|
assertThat(context.queryResult().getTotalHits().value, equalTo((long) numDocs));
|
|
|
|
|
|
- context.setSearcher(newEarlyTerminationContextSearcher(reader, size));
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ contextSearcher = getAssertingEarlyTerminationSearcher(reader, size);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertThat(context.queryResult().topDocs().topDocs.totalHits.value, equalTo((long) numDocs));
|
|
|
assertThat(context.terminateAfter(), equalTo(size));
|
|
|
assertThat(context.queryResult().getTotalHits().value, equalTo((long) numDocs));
|
|
@@ -360,17 +350,19 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
w.addDocument(doc);
|
|
|
}
|
|
|
w.close();
|
|
|
- final IndexReader reader = DirectoryReader.open(dir);
|
|
|
- TestSearchContext context = new TestSearchContext(null, indexShard, newContextSearcher(reader));
|
|
|
+ TestSearchContext context = new TestSearchContext(null, indexShard);
|
|
|
context.setTask(new SearchTask(123L, "", "", "", null, Collections.emptyMap()));
|
|
|
context.parsedQuery(new ParsedQuery(new MatchAllDocsQuery()));
|
|
|
|
|
|
+ final IndexReader reader = DirectoryReader.open(dir);
|
|
|
+ IndexSearcher contextSearcher = new IndexSearcher(reader);
|
|
|
+
|
|
|
context.terminateAfter(numDocs);
|
|
|
{
|
|
|
context.setSize(10);
|
|
|
TotalHitCountCollector collector = new TotalHitCountCollector();
|
|
|
context.queryCollectors().put(TotalHitCountCollector.class, collector);
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertFalse(context.queryResult().terminatedEarly());
|
|
|
assertThat(context.queryResult().topDocs().topDocs.totalHits.value, equalTo((long) numDocs));
|
|
|
assertThat(context.queryResult().topDocs().topDocs.scoreDocs.length, equalTo(10));
|
|
@@ -380,13 +372,13 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
context.terminateAfter(1);
|
|
|
{
|
|
|
context.setSize(1);
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertTrue(context.queryResult().terminatedEarly());
|
|
|
assertThat(context.queryResult().topDocs().topDocs.totalHits.value, equalTo(1L));
|
|
|
assertThat(context.queryResult().topDocs().topDocs.scoreDocs.length, equalTo(1));
|
|
|
|
|
|
context.setSize(0);
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertTrue(context.queryResult().terminatedEarly());
|
|
|
assertThat(context.queryResult().topDocs().topDocs.totalHits.value, equalTo(1L));
|
|
|
assertThat(context.queryResult().topDocs().topDocs.scoreDocs.length, equalTo(0));
|
|
@@ -394,7 +386,7 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
|
|
|
{
|
|
|
context.setSize(1);
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertTrue(context.queryResult().terminatedEarly());
|
|
|
assertThat(context.queryResult().topDocs().topDocs.totalHits.value, equalTo(1L));
|
|
|
assertThat(context.queryResult().topDocs().topDocs.scoreDocs.length, equalTo(1));
|
|
@@ -406,14 +398,14 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
.add(new TermQuery(new Term("foo", "baz")), Occur.SHOULD)
|
|
|
.build();
|
|
|
context.parsedQuery(new ParsedQuery(bq));
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertTrue(context.queryResult().terminatedEarly());
|
|
|
assertThat(context.queryResult().topDocs().topDocs.totalHits.value, equalTo(1L));
|
|
|
assertThat(context.queryResult().topDocs().topDocs.scoreDocs.length, equalTo(1));
|
|
|
|
|
|
context.setSize(0);
|
|
|
context.parsedQuery(new ParsedQuery(bq));
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertTrue(context.queryResult().terminatedEarly());
|
|
|
assertThat(context.queryResult().topDocs().topDocs.totalHits.value, equalTo(1L));
|
|
|
assertThat(context.queryResult().topDocs().topDocs.scoreDocs.length, equalTo(0));
|
|
@@ -422,7 +414,7 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
context.setSize(1);
|
|
|
TotalHitCountCollector collector = new TotalHitCountCollector();
|
|
|
context.queryCollectors().put(TotalHitCountCollector.class, collector);
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertTrue(context.queryResult().terminatedEarly());
|
|
|
assertThat(context.queryResult().topDocs().topDocs.totalHits.value, equalTo(1L));
|
|
|
assertThat(context.queryResult().topDocs().topDocs.scoreDocs.length, equalTo(1));
|
|
@@ -433,7 +425,7 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
context.setSize(0);
|
|
|
TotalHitCountCollector collector = new TotalHitCountCollector();
|
|
|
context.queryCollectors().put(TotalHitCountCollector.class, collector);
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertTrue(context.queryResult().terminatedEarly());
|
|
|
assertThat(context.queryResult().topDocs().topDocs.totalHits.value, equalTo(1L));
|
|
|
assertThat(context.queryResult().topDocs().topDocs.scoreDocs.length, equalTo(0));
|
|
@@ -463,15 +455,15 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
}
|
|
|
w.close();
|
|
|
|
|
|
- final IndexReader reader = DirectoryReader.open(dir);
|
|
|
- TestSearchContext context = new TestSearchContext(null, indexShard, newContextSearcher(reader));
|
|
|
+ TestSearchContext context = new TestSearchContext(null, indexShard);
|
|
|
context.parsedQuery(new ParsedQuery(new MatchAllDocsQuery()));
|
|
|
context.setSize(1);
|
|
|
context.setTask(new SearchTask(123L, "", "", "", null, Collections.emptyMap()));
|
|
|
context.sort(new SortAndFormats(sort, new DocValueFormat[] {DocValueFormat.RAW}));
|
|
|
|
|
|
-
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ final IndexReader reader = DirectoryReader.open(dir);
|
|
|
+ IndexSearcher contextSearcher = new IndexSearcher(reader);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertThat(context.queryResult().topDocs().topDocs.totalHits.value, equalTo((long) numDocs));
|
|
|
assertThat(context.queryResult().topDocs().topDocs.scoreDocs.length, equalTo(1));
|
|
|
assertThat(context.queryResult().topDocs().topDocs.scoreDocs[0], instanceOf(FieldDoc.class));
|
|
@@ -480,7 +472,7 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
|
|
|
{
|
|
|
context.parsedPostFilter(new ParsedQuery(new MinDocQuery(1)));
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertNull(context.queryResult().terminatedEarly());
|
|
|
assertThat(context.queryResult().topDocs().topDocs.totalHits.value, equalTo(numDocs - 1L));
|
|
|
assertThat(context.queryResult().topDocs().topDocs.scoreDocs.length, equalTo(1));
|
|
@@ -490,7 +482,7 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
|
|
|
final TotalHitCountCollector totalHitCountCollector = new TotalHitCountCollector();
|
|
|
context.queryCollectors().put(TotalHitCountCollector.class, totalHitCountCollector);
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertNull(context.queryResult().terminatedEarly());
|
|
|
assertThat(context.queryResult().topDocs().topDocs.totalHits.value, equalTo((long) numDocs));
|
|
|
assertThat(context.queryResult().topDocs().topDocs.scoreDocs.length, equalTo(1));
|
|
@@ -501,15 +493,15 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
}
|
|
|
|
|
|
{
|
|
|
- context.setSearcher(newEarlyTerminationContextSearcher(reader, 1));
|
|
|
+ contextSearcher = getAssertingEarlyTerminationSearcher(reader, 1);
|
|
|
context.trackTotalHitsUpTo(SearchContext.TRACK_TOTAL_HITS_DISABLED);
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertNull(context.queryResult().terminatedEarly());
|
|
|
assertThat(context.queryResult().topDocs().topDocs.scoreDocs.length, equalTo(1));
|
|
|
assertThat(context.queryResult().topDocs().topDocs.scoreDocs[0], instanceOf(FieldDoc.class));
|
|
|
assertThat(fieldDoc.fields[0], anyOf(equalTo(1), equalTo(2)));
|
|
|
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertNull(context.queryResult().terminatedEarly());
|
|
|
assertThat(context.queryResult().topDocs().topDocs.scoreDocs.length, equalTo(1));
|
|
|
assertThat(context.queryResult().topDocs().topDocs.scoreDocs[0], instanceOf(FieldDoc.class));
|
|
@@ -545,7 +537,8 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
// search sort is a prefix of the index sort
|
|
|
searchSortAndFormats.add(new SortAndFormats(new Sort(indexSort.getSort()[0]), new DocValueFormat[]{DocValueFormat.RAW}));
|
|
|
for (SortAndFormats searchSortAndFormat : searchSortAndFormats) {
|
|
|
- TestSearchContext context = new TestSearchContext(null, indexShard, newContextSearcher(reader));
|
|
|
+ IndexSearcher contextSearcher = new IndexSearcher(reader);
|
|
|
+ TestSearchContext context = new TestSearchContext(null, indexShard);
|
|
|
context.parsedQuery(new ParsedQuery(new MatchAllDocsQuery()));
|
|
|
ScrollContext scrollContext = new ScrollContext();
|
|
|
scrollContext.lastEmittedDoc = null;
|
|
@@ -556,7 +549,7 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
context.setSize(10);
|
|
|
context.sort(searchSortAndFormat);
|
|
|
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertThat(context.queryResult().topDocs().topDocs.totalHits.value, equalTo((long) numDocs));
|
|
|
assertNull(context.queryResult().terminatedEarly());
|
|
|
assertThat(context.terminateAfter(), equalTo(0));
|
|
@@ -564,8 +557,8 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
int sizeMinus1 = context.queryResult().topDocs().topDocs.scoreDocs.length - 1;
|
|
|
FieldDoc lastDoc = (FieldDoc) context.queryResult().topDocs().topDocs.scoreDocs[sizeMinus1];
|
|
|
|
|
|
- context.setSearcher(newEarlyTerminationContextSearcher(reader, 10));
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ contextSearcher = getAssertingEarlyTerminationSearcher(reader, 10);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertNull(context.queryResult().terminatedEarly());
|
|
|
assertThat(context.queryResult().topDocs().topDocs.totalHits.value, equalTo((long) numDocs));
|
|
|
assertThat(context.terminateAfter(), equalTo(0));
|
|
@@ -586,6 +579,7 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
dir.close();
|
|
|
}
|
|
|
|
|
|
+
|
|
|
public void testDisableTopScoreCollection() throws Exception {
|
|
|
Directory dir = newDirectory();
|
|
|
IndexWriterConfig iwc = newIndexWriterConfig(new StandardAnalyzer());
|
|
@@ -603,7 +597,8 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
w.close();
|
|
|
|
|
|
IndexReader reader = DirectoryReader.open(dir);
|
|
|
- TestSearchContext context = new TestSearchContext(null, indexShard, newContextSearcher(reader));
|
|
|
+ IndexSearcher contextSearcher = new IndexSearcher(reader);
|
|
|
+ TestSearchContext context = new TestSearchContext(null, indexShard);
|
|
|
context.setTask(new SearchTask(123L, "", "", "", null, Collections.emptyMap()));
|
|
|
Query q = new SpanNearQuery.Builder("title", true)
|
|
|
.addClause(new SpanTermQuery(new Term("title", "foo")))
|
|
@@ -613,19 +608,21 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
context.parsedQuery(new ParsedQuery(q));
|
|
|
context.setSize(3);
|
|
|
context.trackTotalHitsUpTo(3);
|
|
|
- TopDocsCollectorContext topDocsContext = TopDocsCollectorContext.createTopDocsCollectorContext(context, false);
|
|
|
+
|
|
|
+ TopDocsCollectorContext topDocsContext =
|
|
|
+ TopDocsCollectorContext.createTopDocsCollectorContext(context, reader, false);
|
|
|
assertEquals(topDocsContext.create(null).scoreMode(), org.apache.lucene.search.ScoreMode.COMPLETE);
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertEquals(5, context.queryResult().topDocs().topDocs.totalHits.value);
|
|
|
assertEquals(context.queryResult().topDocs().topDocs.totalHits.relation, TotalHits.Relation.EQUAL_TO);
|
|
|
assertThat(context.queryResult().topDocs().topDocs.scoreDocs.length, equalTo(3));
|
|
|
|
|
|
-
|
|
|
context.sort(new SortAndFormats(new Sort(new SortField("other", SortField.Type.INT)),
|
|
|
new DocValueFormat[] { DocValueFormat.RAW }));
|
|
|
- topDocsContext = TopDocsCollectorContext.createTopDocsCollectorContext(context, false);
|
|
|
+ topDocsContext =
|
|
|
+ TopDocsCollectorContext.createTopDocsCollectorContext(context, reader, false);
|
|
|
assertEquals(topDocsContext.create(null).scoreMode(), org.apache.lucene.search.ScoreMode.COMPLETE_NO_SCORES);
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertEquals(5, context.queryResult().topDocs().topDocs.totalHits.value);
|
|
|
assertThat(context.queryResult().topDocs().topDocs.scoreDocs.length, equalTo(3));
|
|
|
assertEquals(context.queryResult().topDocs().topDocs.totalHits.relation, TotalHits.Relation.EQUAL_TO);
|
|
@@ -634,108 +631,13 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
dir.close();
|
|
|
}
|
|
|
|
|
|
- public void testNumericLongOrDateSortOptimization() throws Exception {
|
|
|
- final String fieldNameLong = "long-field";
|
|
|
- final String fieldNameDate = "date-field";
|
|
|
- MappedFieldType fieldTypeLong = new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.LONG);
|
|
|
- MappedFieldType fieldTypeDate = new DateFieldMapper.Builder(fieldNameDate).fieldType();
|
|
|
- MapperService mapperService = mock(MapperService.class);
|
|
|
- when(mapperService.fullName(fieldNameLong)).thenReturn(fieldTypeLong);
|
|
|
- when(mapperService.fullName(fieldNameDate)).thenReturn(fieldTypeDate);
|
|
|
-
|
|
|
- final int numDocs = 7000;
|
|
|
- Directory dir = newDirectory();
|
|
|
- IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(null));
|
|
|
- for (int i = 1; i <= numDocs; ++i) {
|
|
|
- Document doc = new Document();
|
|
|
- long longValue = randomLongBetween(-10000000L, 10000000L);
|
|
|
- doc.add(new LongPoint(fieldNameLong, longValue));
|
|
|
- doc.add(new NumericDocValuesField(fieldNameLong, longValue));
|
|
|
- longValue = randomLongBetween(0, 3000000000000L);
|
|
|
- doc.add(new LongPoint(fieldNameDate, longValue));
|
|
|
- doc.add(new NumericDocValuesField(fieldNameDate, longValue));
|
|
|
- writer.addDocument(doc);
|
|
|
- if (i % 3500 == 0) writer.commit();
|
|
|
- }
|
|
|
- writer.close();
|
|
|
- final IndexReader reader = DirectoryReader.open(dir);
|
|
|
-
|
|
|
- TestSearchContext searchContext =
|
|
|
- spy(new TestSearchContext(null, indexShard, newOptimizedContextSearcher(reader, 0)));
|
|
|
- when(searchContext.mapperService()).thenReturn(mapperService);
|
|
|
-
|
|
|
- // 1. Test a sort on long field
|
|
|
- final SortField sortFieldLong = new SortField(fieldNameLong, SortField.Type.LONG);
|
|
|
- sortFieldLong.setMissingValue(Long.MAX_VALUE);
|
|
|
- final Sort longSort = new Sort(sortFieldLong);
|
|
|
- SortAndFormats sortAndFormats = new SortAndFormats(longSort, new DocValueFormat[]{DocValueFormat.RAW});
|
|
|
- searchContext.sort(sortAndFormats);
|
|
|
- searchContext.parsedQuery(new ParsedQuery(new MatchAllDocsQuery()));
|
|
|
- searchContext.setTask(new SearchTask(123L, "", "", "", null, Collections.emptyMap()));
|
|
|
- searchContext.setSize(10);
|
|
|
- QueryPhase.executeInternal(searchContext);
|
|
|
- assertSortResults(searchContext.queryResult().topDocs().topDocs, (long) numDocs, false);
|
|
|
-
|
|
|
- // 2. Test a sort on long field + date field
|
|
|
- final SortField sortFieldDate = new SortField(fieldNameDate, SortField.Type.LONG);
|
|
|
- DocValueFormat dateFormat = fieldTypeDate.docValueFormat(null, null);
|
|
|
- final Sort longDateSort = new Sort(sortFieldLong, sortFieldDate);
|
|
|
- sortAndFormats = new SortAndFormats(longDateSort, new DocValueFormat[]{DocValueFormat.RAW, dateFormat});
|
|
|
- searchContext.sort(sortAndFormats);
|
|
|
- QueryPhase.executeInternal(searchContext);
|
|
|
- assertSortResults(searchContext.queryResult().topDocs().topDocs, (long) numDocs, true);
|
|
|
-
|
|
|
- // 3. Test a sort on date field
|
|
|
- sortFieldDate.setMissingValue(Long.MAX_VALUE);
|
|
|
- final Sort dateSort = new Sort(sortFieldDate);
|
|
|
- sortAndFormats = new SortAndFormats(dateSort, new DocValueFormat[]{dateFormat});
|
|
|
- searchContext.sort(sortAndFormats);
|
|
|
- QueryPhase.executeInternal(searchContext);
|
|
|
- assertSortResults(searchContext.queryResult().topDocs().topDocs, (long) numDocs, false);
|
|
|
-
|
|
|
- // 4. Test a sort on date field + long field
|
|
|
- final Sort dateLongSort = new Sort(sortFieldDate, sortFieldLong);
|
|
|
- sortAndFormats = new SortAndFormats(dateLongSort, new DocValueFormat[]{dateFormat, DocValueFormat.RAW});
|
|
|
- searchContext.sort(sortAndFormats);
|
|
|
- QueryPhase.executeInternal(searchContext);
|
|
|
- assertSortResults(searchContext.queryResult().topDocs().topDocs, (long) numDocs, true);
|
|
|
- reader.close();
|
|
|
- dir.close();
|
|
|
- }
|
|
|
-
|
|
|
- public void testIndexHasDuplicateData() throws IOException {
|
|
|
- int docsCount = 7000;
|
|
|
- int duplIndex = docsCount * 7 / 10;
|
|
|
- int duplIndex2 = docsCount * 3 / 10;
|
|
|
- long duplicateValue = randomLongBetween(-10000000L, 10000000L);
|
|
|
- Directory dir = newDirectory();
|
|
|
- IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(null));
|
|
|
- for (int docId = 0; docId < docsCount; docId++) {
|
|
|
- Document doc = new Document();
|
|
|
- long rndValue = randomLongBetween(-10000000L, 10000000L);
|
|
|
- long value = (docId < duplIndex) ? duplicateValue : rndValue;
|
|
|
- long value2 = (docId < duplIndex2) ? duplicateValue : rndValue;
|
|
|
- doc.add(new LongPoint("duplicateField", value));
|
|
|
- doc.add(new LongPoint("notDuplicateField", value2));
|
|
|
- writer.addDocument(doc);
|
|
|
- }
|
|
|
- writer.close();
|
|
|
- final IndexReader reader = DirectoryReader.open(dir);
|
|
|
- boolean hasDuplicateData = indexFieldHasDuplicateData(reader, "duplicateField");
|
|
|
- boolean hasDuplicateData2 = indexFieldHasDuplicateData(reader, "notDuplicateField");
|
|
|
- reader.close();
|
|
|
- dir.close();
|
|
|
- assertTrue(hasDuplicateData);
|
|
|
- assertFalse(hasDuplicateData2);
|
|
|
- }
|
|
|
-
|
|
|
public void testMaxScoreQueryVisitor() {
|
|
|
BitSetProducer producer = context -> new FixedBitSet(1);
|
|
|
Query query = new ESToParentBlockJoinQuery(new MatchAllDocsQuery(), producer, ScoreMode.Avg, "nested");
|
|
|
- assertTrue(hasInfMaxScore(query));
|
|
|
+ assertTrue(TopDocsCollectorContext.hasInfMaxScore(query));
|
|
|
|
|
|
query = new ESToParentBlockJoinQuery(new MatchAllDocsQuery(), producer, ScoreMode.None, "nested");
|
|
|
- assertFalse(hasInfMaxScore(query));
|
|
|
+ assertFalse(TopDocsCollectorContext.hasInfMaxScore(query));
|
|
|
|
|
|
|
|
|
for (Occur occur : Occur.values()) {
|
|
@@ -743,9 +645,9 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
.add(new ESToParentBlockJoinQuery(new MatchAllDocsQuery(), producer, ScoreMode.Avg, "nested"), occur)
|
|
|
.build();
|
|
|
if (occur == Occur.MUST) {
|
|
|
- assertTrue(hasInfMaxScore(query));
|
|
|
+ assertTrue(TopDocsCollectorContext.hasInfMaxScore(query));
|
|
|
} else {
|
|
|
- assertFalse(hasInfMaxScore(query));
|
|
|
+ assertFalse(TopDocsCollectorContext.hasInfMaxScore(query));
|
|
|
}
|
|
|
|
|
|
query = new BooleanQuery.Builder()
|
|
@@ -754,9 +656,9 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
.build(), occur)
|
|
|
.build();
|
|
|
if (occur == Occur.MUST) {
|
|
|
- assertTrue(hasInfMaxScore(query));
|
|
|
+ assertTrue(TopDocsCollectorContext.hasInfMaxScore(query));
|
|
|
} else {
|
|
|
- assertFalse(hasInfMaxScore(query));
|
|
|
+ assertFalse(TopDocsCollectorContext.hasInfMaxScore(query));
|
|
|
}
|
|
|
|
|
|
query = new BooleanQuery.Builder()
|
|
@@ -764,7 +666,7 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
.add(new ESToParentBlockJoinQuery(new MatchAllDocsQuery(), producer, ScoreMode.Avg, "nested"), occur)
|
|
|
.build(), Occur.FILTER)
|
|
|
.build();
|
|
|
- assertFalse(hasInfMaxScore(query));
|
|
|
+ assertFalse(TopDocsCollectorContext.hasInfMaxScore(query));
|
|
|
|
|
|
query = new BooleanQuery.Builder()
|
|
|
.add(new BooleanQuery.Builder()
|
|
@@ -773,33 +675,13 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
.build(), occur)
|
|
|
.build();
|
|
|
if (occur == Occur.MUST) {
|
|
|
- assertTrue(hasInfMaxScore(query));
|
|
|
+ assertTrue(TopDocsCollectorContext.hasInfMaxScore(query));
|
|
|
} else {
|
|
|
- assertFalse(hasInfMaxScore(query));
|
|
|
+ assertFalse(TopDocsCollectorContext.hasInfMaxScore(query));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // assert score docs are in order and their number is as expected
|
|
|
- private void assertSortResults(TopDocs topDocs, long expectedNumDocs, boolean isDoubleSort) {
|
|
|
- assertEquals(topDocs.totalHits.value, expectedNumDocs);
|
|
|
- long cur1, cur2;
|
|
|
- long prev1 = Long.MIN_VALUE;
|
|
|
- long prev2 = Long.MIN_VALUE;
|
|
|
- for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
|
|
|
- cur1 = (long) ((FieldDoc) scoreDoc).fields[0];
|
|
|
- assertThat(cur1, greaterThanOrEqualTo(prev1)); // test that docs are properly sorted on the first sort
|
|
|
- if (isDoubleSort) {
|
|
|
- cur2 = (long) ((FieldDoc) scoreDoc).fields[1];
|
|
|
- if (cur1 == prev1) {
|
|
|
- assertThat(cur2, greaterThanOrEqualTo(prev2)); // test that docs are properly sorted on the secondary sort
|
|
|
- }
|
|
|
- prev2 = cur2;
|
|
|
- }
|
|
|
- prev1 = cur1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
public void testMinScore() throws Exception {
|
|
|
Directory dir = newDirectory();
|
|
|
IndexWriterConfig iwc = newIndexWriterConfig();
|
|
@@ -813,7 +695,8 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
w.close();
|
|
|
|
|
|
IndexReader reader = DirectoryReader.open(dir);
|
|
|
- TestSearchContext context = new TestSearchContext(null, indexShard, newContextSearcher(reader));
|
|
|
+ IndexSearcher contextSearcher = new IndexSearcher(reader);
|
|
|
+ TestSearchContext context = new TestSearchContext(null, indexShard);
|
|
|
context.parsedQuery(new ParsedQuery(
|
|
|
new BooleanQuery.Builder()
|
|
|
.add(new TermQuery(new Term("foo", "bar")), Occur.MUST)
|
|
@@ -825,61 +708,23 @@ public class QueryPhaseTests extends IndexShardTestCase {
|
|
|
context.setSize(1);
|
|
|
context.trackTotalHitsUpTo(5);
|
|
|
|
|
|
- QueryPhase.executeInternal(context);
|
|
|
+ QueryPhase.execute(context, contextSearcher, checkCancelled -> {});
|
|
|
assertEquals(10, context.queryResult().topDocs().topDocs.totalHits.value);
|
|
|
|
|
|
reader.close();
|
|
|
dir.close();
|
|
|
-
|
|
|
}
|
|
|
|
|
|
- private static ContextIndexSearcher newContextSearcher(IndexReader reader) {
|
|
|
- return new ContextIndexSearcher(reader, IndexSearcher.getDefaultSimilarity(),
|
|
|
- IndexSearcher.getDefaultQueryCache(), IndexSearcher.getDefaultQueryCachingPolicy());
|
|
|
- }
|
|
|
-
|
|
|
- private static ContextIndexSearcher newEarlyTerminationContextSearcher(IndexReader reader, int size) {
|
|
|
- return new ContextIndexSearcher(reader, IndexSearcher.getDefaultSimilarity(),
|
|
|
- IndexSearcher.getDefaultQueryCache(), IndexSearcher.getDefaultQueryCachingPolicy()) {
|
|
|
-
|
|
|
+ private static IndexSearcher getAssertingEarlyTerminationSearcher(IndexReader reader, int size) {
|
|
|
+ return new IndexSearcher(reader) {
|
|
|
@Override
|
|
|
- public void search(List<LeafReaderContext> leaves, Weight weight, Collector collector) throws IOException {
|
|
|
+ protected void search(List<LeafReaderContext> leaves, Weight weight, Collector collector) throws IOException {
|
|
|
final Collector in = new AssertingEarlyTerminationFilterCollector(collector, size);
|
|
|
super.search(leaves, weight, in);
|
|
|
}
|
|
|
};
|
|
|
}
|
|
|
|
|
|
- // used to check that numeric long or date sort optimization was run
|
|
|
- private static ContextIndexSearcher newOptimizedContextSearcher(IndexReader reader, int queryType) {
|
|
|
- return new ContextIndexSearcher(reader, IndexSearcher.getDefaultSimilarity(),
|
|
|
- IndexSearcher.getDefaultQueryCache(), IndexSearcher.getDefaultQueryCachingPolicy()) {
|
|
|
-
|
|
|
- @Override
|
|
|
- public void search(List<LeafReaderContext> leaves, Weight weight, CollectorManager manager,
|
|
|
- QuerySearchResult result, DocValueFormat[] formats, TotalHits totalHits) throws IOException {
|
|
|
- final Query query = weight.getQuery();
|
|
|
- assertTrue(query instanceof BooleanQuery);
|
|
|
- List<BooleanClause> clauses = ((BooleanQuery) query).clauses();
|
|
|
- assertTrue(clauses.size() == 2);
|
|
|
- assertTrue(clauses.get(0).getOccur() == Occur.FILTER);
|
|
|
- assertTrue(clauses.get(1).getOccur() == Occur.SHOULD);
|
|
|
- if (queryType == 0) {
|
|
|
- assertTrue (clauses.get(1).getQuery().getClass() ==
|
|
|
- LongPoint.newDistanceFeatureQuery("random_field", 1, 1, 1).getClass()
|
|
|
- );
|
|
|
- }
|
|
|
- if (queryType == 1) assertTrue(clauses.get(1).getQuery() instanceof DocValuesFieldExistsQuery);
|
|
|
- super.search(leaves, weight, manager, result, formats, totalHits);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void search(List<LeafReaderContext> leaves, Weight weight, Collector collector) {
|
|
|
- assert(false); // should not be there, expected to search with CollectorManager
|
|
|
- }
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
private static class AssertingEarlyTerminationFilterCollector extends FilterCollector {
|
|
|
private final int size;
|
|
|
|