Handles exists query in composite aggs (#35758)
This commit adds the support for exists query in the sorted execution mode of the `composite` aggregation. We'll execute the aggregation from the sorted points and use early termination if the main query is an `exists` query over the first source of the `composite` aggregation.
This commit is contained in:
parent
3f7cae3f0d
commit
900caa20ef
|
@ -25,6 +25,8 @@ import org.apache.lucene.index.IndexReader;
|
||||||
import org.apache.lucene.index.LeafReaderContext;
|
import org.apache.lucene.index.LeafReaderContext;
|
||||||
import org.apache.lucene.index.SortedNumericDocValues;
|
import org.apache.lucene.index.SortedNumericDocValues;
|
||||||
import org.apache.lucene.search.BoostQuery;
|
import org.apache.lucene.search.BoostQuery;
|
||||||
|
import org.apache.lucene.search.ConstantScoreQuery;
|
||||||
|
import org.apache.lucene.search.DocValuesFieldExistsQuery;
|
||||||
import org.apache.lucene.search.IndexOrDocValuesQuery;
|
import org.apache.lucene.search.IndexOrDocValuesQuery;
|
||||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||||
import org.apache.lucene.search.PointRangeQuery;
|
import org.apache.lucene.search.PointRangeQuery;
|
||||||
|
@ -180,24 +182,42 @@ class LongValuesSource extends SingleDimensionValuesSource<Long> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static Query extractQuery(Query query) {
|
private static Query extractQuery(Query query) {
|
||||||
if (query instanceof BoostQuery) {
|
if (query instanceof BoostQuery) {
|
||||||
return extractQuery(((BoostQuery) query).getQuery());
|
return extractQuery(((BoostQuery) query).getQuery());
|
||||||
} else if (query instanceof IndexOrDocValuesQuery) {
|
} else if (query instanceof IndexOrDocValuesQuery) {
|
||||||
return extractQuery(((IndexOrDocValuesQuery) query).getIndexQuery());
|
return extractQuery(((IndexOrDocValuesQuery) query).getIndexQuery());
|
||||||
|
} else if (query instanceof ConstantScoreQuery){
|
||||||
|
return extractQuery(((ConstantScoreQuery) query).getQuery());
|
||||||
} else {
|
} else {
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if we can use <code>query</code> with a {@link SortedDocsProducer} on <code>fieldName</code>.
|
||||||
|
*/
|
||||||
|
private static boolean checkMatchAllOrRangeQuery(Query query, String fieldName) {
|
||||||
|
if (query == null) {
|
||||||
|
return true;
|
||||||
|
} else if (query.getClass() == MatchAllDocsQuery.class) {
|
||||||
|
return true;
|
||||||
|
} else if (query instanceof PointRangeQuery) {
|
||||||
|
PointRangeQuery pointQuery = (PointRangeQuery) query;
|
||||||
|
return fieldName.equals(pointQuery.getField());
|
||||||
|
} else if (query instanceof DocValuesFieldExistsQuery) {
|
||||||
|
DocValuesFieldExistsQuery existsQuery = (DocValuesFieldExistsQuery) query;
|
||||||
|
return fieldName.equals(existsQuery.getField());
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
SortedDocsProducer createSortedDocsProducerOrNull(IndexReader reader, Query query) {
|
SortedDocsProducer createSortedDocsProducerOrNull(IndexReader reader, Query query) {
|
||||||
query = extractQuery(query);
|
query = extractQuery(query);
|
||||||
if (checkIfSortedDocsIsApplicable(reader, fieldType) == false ||
|
if (checkIfSortedDocsIsApplicable(reader, fieldType) == false ||
|
||||||
(query != null &&
|
checkMatchAllOrRangeQuery(query, fieldType.name()) == false) {
|
||||||
query.getClass() != MatchAllDocsQuery.class &&
|
|
||||||
// if the query is a range query over the same field
|
|
||||||
(query instanceof PointRangeQuery && fieldType.name().equals((((PointRangeQuery) query).getField()))) == false)) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final byte[] lowerPoint;
|
final byte[] lowerPoint;
|
||||||
|
|
|
@ -23,6 +23,8 @@ import org.apache.lucene.document.LongPoint;
|
||||||
import org.apache.lucene.index.IndexReader;
|
import org.apache.lucene.index.IndexReader;
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
import org.apache.lucene.search.BoostQuery;
|
import org.apache.lucene.search.BoostQuery;
|
||||||
|
import org.apache.lucene.search.ConstantScoreQuery;
|
||||||
|
import org.apache.lucene.search.DocValuesFieldExistsQuery;
|
||||||
import org.apache.lucene.search.IndexOrDocValuesQuery;
|
import org.apache.lucene.search.IndexOrDocValuesQuery;
|
||||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||||
import org.apache.lucene.search.TermQuery;
|
import org.apache.lucene.search.TermQuery;
|
||||||
|
@ -55,6 +57,7 @@ public class SingleDimensionValuesSourceTests extends ESTestCase {
|
||||||
IndexReader reader = mockIndexReader(1, 1);
|
IndexReader reader = mockIndexReader(1, 1);
|
||||||
assertNotNull(source.createSortedDocsProducerOrNull(reader, new MatchAllDocsQuery()));
|
assertNotNull(source.createSortedDocsProducerOrNull(reader, new MatchAllDocsQuery()));
|
||||||
assertNotNull(source.createSortedDocsProducerOrNull(reader, null));
|
assertNotNull(source.createSortedDocsProducerOrNull(reader, null));
|
||||||
|
assertNull(source.createSortedDocsProducerOrNull(reader, new TermQuery(new Term("foo", "bar"))));
|
||||||
assertNull(source.createSortedDocsProducerOrNull(reader,
|
assertNull(source.createSortedDocsProducerOrNull(reader,
|
||||||
new TermQuery(new Term("keyword", "toto)"))));
|
new TermQuery(new Term("keyword", "toto)"))));
|
||||||
|
|
||||||
|
@ -112,6 +115,7 @@ public class SingleDimensionValuesSourceTests extends ESTestCase {
|
||||||
IndexReader reader = mockIndexReader(1, 1);
|
IndexReader reader = mockIndexReader(1, 1);
|
||||||
assertNotNull(source.createSortedDocsProducerOrNull(reader, new MatchAllDocsQuery()));
|
assertNotNull(source.createSortedDocsProducerOrNull(reader, new MatchAllDocsQuery()));
|
||||||
assertNotNull(source.createSortedDocsProducerOrNull(reader, null));
|
assertNotNull(source.createSortedDocsProducerOrNull(reader, null));
|
||||||
|
assertNull(source.createSortedDocsProducerOrNull(reader, new TermQuery(new Term("foo", "bar"))));
|
||||||
assertNull(source.createSortedDocsProducerOrNull(reader,
|
assertNull(source.createSortedDocsProducerOrNull(reader,
|
||||||
new TermQuery(new Term("keyword", "toto)"))));
|
new TermQuery(new Term("keyword", "toto)"))));
|
||||||
|
|
||||||
|
@ -126,6 +130,7 @@ public class SingleDimensionValuesSourceTests extends ESTestCase {
|
||||||
);
|
);
|
||||||
assertNull(source.createSortedDocsProducerOrNull(reader, new MatchAllDocsQuery()));
|
assertNull(source.createSortedDocsProducerOrNull(reader, new MatchAllDocsQuery()));
|
||||||
assertNull(source.createSortedDocsProducerOrNull(reader, null));
|
assertNull(source.createSortedDocsProducerOrNull(reader, null));
|
||||||
|
assertNull(source.createSortedDocsProducerOrNull(reader, new TermQuery(new Term("foo", "bar"))));
|
||||||
|
|
||||||
source = new GlobalOrdinalValuesSource(
|
source = new GlobalOrdinalValuesSource(
|
||||||
BigArrays.NON_RECYCLING_INSTANCE,
|
BigArrays.NON_RECYCLING_INSTANCE,
|
||||||
|
@ -137,6 +142,7 @@ public class SingleDimensionValuesSourceTests extends ESTestCase {
|
||||||
-1
|
-1
|
||||||
);
|
);
|
||||||
assertNull(source.createSortedDocsProducerOrNull(reader, null));
|
assertNull(source.createSortedDocsProducerOrNull(reader, null));
|
||||||
|
assertNull(source.createSortedDocsProducerOrNull(reader, new TermQuery(new Term("foo", "bar"))));
|
||||||
|
|
||||||
final MappedFieldType ip = new IpFieldMapper.IpFieldType();
|
final MappedFieldType ip = new IpFieldMapper.IpFieldType();
|
||||||
ip.setName("ip");
|
ip.setName("ip");
|
||||||
|
@ -150,6 +156,7 @@ public class SingleDimensionValuesSourceTests extends ESTestCase {
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
assertNull(source.createSortedDocsProducerOrNull(reader, null));
|
assertNull(source.createSortedDocsProducerOrNull(reader, null));
|
||||||
|
assertNull(source.createSortedDocsProducerOrNull(reader, new TermQuery(new Term("foo", "bar"))));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testNumericSorted() {
|
public void testNumericSorted() {
|
||||||
|
@ -179,6 +186,9 @@ public class SingleDimensionValuesSourceTests extends ESTestCase {
|
||||||
assertNotNull(source.createSortedDocsProducerOrNull(reader, LongPoint.newRangeQuery("number", 0, 1)));
|
assertNotNull(source.createSortedDocsProducerOrNull(reader, LongPoint.newRangeQuery("number", 0, 1)));
|
||||||
assertNotNull(source.createSortedDocsProducerOrNull(reader, new IndexOrDocValuesQuery(
|
assertNotNull(source.createSortedDocsProducerOrNull(reader, new IndexOrDocValuesQuery(
|
||||||
LongPoint.newRangeQuery("number", 0, 1), new MatchAllDocsQuery())));
|
LongPoint.newRangeQuery("number", 0, 1), new MatchAllDocsQuery())));
|
||||||
|
assertNotNull(source.createSortedDocsProducerOrNull(reader, new DocValuesFieldExistsQuery("number")));
|
||||||
|
assertNotNull(source.createSortedDocsProducerOrNull(reader,
|
||||||
|
new ConstantScoreQuery(new DocValuesFieldExistsQuery("number"))));
|
||||||
assertNotNull(source.createSortedDocsProducerOrNull(reader, new BoostQuery(new IndexOrDocValuesQuery(
|
assertNotNull(source.createSortedDocsProducerOrNull(reader, new BoostQuery(new IndexOrDocValuesQuery(
|
||||||
LongPoint.newRangeQuery("number", 0, 1), new MatchAllDocsQuery()), 2.0f)));
|
LongPoint.newRangeQuery("number", 0, 1), new MatchAllDocsQuery()), 2.0f)));
|
||||||
assertNull(source.createSortedDocsProducerOrNull(reader, new TermQuery(new Term("keyword", "toto)"))));
|
assertNull(source.createSortedDocsProducerOrNull(reader, new TermQuery(new Term("keyword", "toto)"))));
|
||||||
|
@ -195,6 +205,9 @@ public class SingleDimensionValuesSourceTests extends ESTestCase {
|
||||||
assertNull(sourceWithMissing.createSortedDocsProducerOrNull(reader, new MatchAllDocsQuery()));
|
assertNull(sourceWithMissing.createSortedDocsProducerOrNull(reader, new MatchAllDocsQuery()));
|
||||||
assertNull(sourceWithMissing.createSortedDocsProducerOrNull(reader, null));
|
assertNull(sourceWithMissing.createSortedDocsProducerOrNull(reader, null));
|
||||||
assertNull(sourceWithMissing.createSortedDocsProducerOrNull(reader, new TermQuery(new Term("keyword", "toto)"))));
|
assertNull(sourceWithMissing.createSortedDocsProducerOrNull(reader, new TermQuery(new Term("keyword", "toto)"))));
|
||||||
|
assertNull(sourceWithMissing.createSortedDocsProducerOrNull(reader, new DocValuesFieldExistsQuery("number")));
|
||||||
|
assertNull(sourceWithMissing.createSortedDocsProducerOrNull(reader,
|
||||||
|
new ConstantScoreQuery(new DocValuesFieldExistsQuery("number"))));
|
||||||
|
|
||||||
LongValuesSource sourceRev = new LongValuesSource(
|
LongValuesSource sourceRev = new LongValuesSource(
|
||||||
BigArrays.NON_RECYCLING_INSTANCE,
|
BigArrays.NON_RECYCLING_INSTANCE,
|
||||||
|
@ -207,6 +220,10 @@ public class SingleDimensionValuesSourceTests extends ESTestCase {
|
||||||
-1
|
-1
|
||||||
);
|
);
|
||||||
assertNull(sourceRev.createSortedDocsProducerOrNull(reader, null));
|
assertNull(sourceRev.createSortedDocsProducerOrNull(reader, null));
|
||||||
|
assertNull(sourceRev.createSortedDocsProducerOrNull(reader, new DocValuesFieldExistsQuery("number")));
|
||||||
|
assertNull(sourceRev.createSortedDocsProducerOrNull(reader,
|
||||||
|
new ConstantScoreQuery(new DocValuesFieldExistsQuery("number"))));
|
||||||
|
assertNull(sourceWithMissing.createSortedDocsProducerOrNull(reader, new TermQuery(new Term("keyword", "toto)"))));
|
||||||
} else if (numberType == NumberFieldMapper.NumberType.HALF_FLOAT ||
|
} else if (numberType == NumberFieldMapper.NumberType.HALF_FLOAT ||
|
||||||
numberType == NumberFieldMapper.NumberType.FLOAT ||
|
numberType == NumberFieldMapper.NumberType.FLOAT ||
|
||||||
numberType == NumberFieldMapper.NumberType.DOUBLE) {
|
numberType == NumberFieldMapper.NumberType.DOUBLE) {
|
||||||
|
@ -221,6 +238,10 @@ public class SingleDimensionValuesSourceTests extends ESTestCase {
|
||||||
);
|
);
|
||||||
IndexReader reader = mockIndexReader(1, 1);
|
IndexReader reader = mockIndexReader(1, 1);
|
||||||
assertNull(source.createSortedDocsProducerOrNull(reader, null));
|
assertNull(source.createSortedDocsProducerOrNull(reader, null));
|
||||||
|
assertNull(source.createSortedDocsProducerOrNull(reader, new DocValuesFieldExistsQuery("number")));
|
||||||
|
assertNull(source.createSortedDocsProducerOrNull(reader, new TermQuery(new Term("keyword", "toto)"))));
|
||||||
|
assertNull(source.createSortedDocsProducerOrNull(reader,
|
||||||
|
new ConstantScoreQuery(new DocValuesFieldExistsQuery("number"))));
|
||||||
} else{
|
} else{
|
||||||
throw new AssertionError ("missing type:" + numberType.typeName());
|
throw new AssertionError ("missing type:" + numberType.typeName());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue