-
Notifications
You must be signed in to change notification settings - Fork 25k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optimize lone single bucket date_histogram
#71180
Changes from 14 commits
6056afa
29d21b1
6676f0d
acbe5ad
13797f7
ce26ba3
144e0f2
1a270e4
d10b042
1d89bdc
7a3cf4c
9b48cff
d81d3e1
2f76f22
7139c71
db298be
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,12 +8,15 @@ | |
|
||
package org.elasticsearch.search.aggregations.bucket.filter; | ||
|
||
import org.apache.lucene.index.FieldInfo; | ||
import org.apache.lucene.index.IndexReader; | ||
import org.apache.lucene.index.LeafReaderContext; | ||
import org.apache.lucene.index.PointValues; | ||
import org.apache.lucene.search.BooleanClause; | ||
import org.apache.lucene.search.BooleanQuery; | ||
import org.apache.lucene.search.BulkScorer; | ||
import org.apache.lucene.search.ConstantScoreQuery; | ||
import org.apache.lucene.search.DocValuesFieldExistsQuery; | ||
import org.apache.lucene.search.IndexOrDocValuesQuery; | ||
import org.apache.lucene.search.IndexSearcher; | ||
import org.apache.lucene.search.IndexSortSortedNumericDocValuesRangeQuery; | ||
|
@@ -52,6 +55,15 @@ public static QueryToFilterAdapter<?> build(IndexSearcher searcher, String key, | |
if (query instanceof TermQuery) { | ||
return new TermQueryToFilterAdapter(searcher, key, (TermQuery) query); | ||
} | ||
if (query instanceof ConstantScoreQuery) { | ||
Query wrapped = ((ConstantScoreQuery) query).getQuery(); | ||
if (wrapped instanceof DocValuesFieldExistsQuery) { | ||
return new DocValuesFieldExistsAdapter(searcher, key, (DocValuesFieldExistsQuery) wrapped); | ||
} | ||
} | ||
if (query instanceof DocValuesFieldExistsQuery) { | ||
return new DocValuesFieldExistsAdapter(searcher, key, (DocValuesFieldExistsQuery) query); | ||
} | ||
if (query instanceof MatchAllDocsQuery) { | ||
return new MatchAllQueryToFilterAdapter(searcher, key, (MatchAllDocsQuery) query); | ||
} | ||
|
@@ -386,4 +398,50 @@ void collectDebugInfo(BiConsumer<String, Object> add) { | |
add.accept("results_from_metadata", resultsFromMetadata); | ||
} | ||
} | ||
|
||
private static class DocValuesFieldExistsAdapter extends QueryToFilterAdapter<DocValuesFieldExistsQuery> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At some point, keeping all the implementations as static inner classes is going to get unwieldy. Do you think we should refactor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah.... I'll see about breaking them out in a mechanical follow up PR. |
||
private int resultsFromMetadata; | ||
|
||
private DocValuesFieldExistsAdapter(IndexSearcher searcher, String key, DocValuesFieldExistsQuery query) { | ||
super(searcher, key, query); | ||
} | ||
|
||
@Override | ||
long count(LeafReaderContext ctx, FiltersAggregator.Counter counter, Bits live) throws IOException { | ||
if (countCanUseMetadata(counter, live) && canCountFromMetadata(ctx)) { | ||
resultsFromMetadata++; | ||
PointValues points = ctx.reader().getPointValues(query().getField()); | ||
if (points == null) { | ||
return 0; | ||
} | ||
return points.getDocCount(); | ||
|
||
} | ||
return super.count(ctx, counter, live); | ||
} | ||
|
||
@Override | ||
long estimateCountCost(LeafReaderContext ctx, CheckedSupplier<Boolean, IOException> canUseMetadata) throws IOException { | ||
if (canUseMetadata.get() && canCountFromMetadata(ctx)) { | ||
return 0; | ||
} | ||
return super.estimateCountCost(ctx, canUseMetadata); | ||
} | ||
|
||
private boolean canCountFromMetadata(LeafReaderContext ctx) throws IOException { | ||
FieldInfo info = ctx.reader().getFieldInfos().fieldInfo(query().getField()); | ||
if (info == null) { | ||
// If we don't have any info then there aren't any values anyway. | ||
return true; | ||
} | ||
return info.getPointDimensionCount() > 0; | ||
} | ||
|
||
@Override | ||
void collectDebugInfo(BiConsumer<String, Object> add) { | ||
super.collectDebugInfo(add); | ||
add.accept("specialized_for", "docvalues_field_exists"); | ||
add.accept("results_from_metadata", resultsFromMetadata); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like an obvious question "Why don't we check for a wrapped
TermsQuery
orMatchAllDocsQuery
?" Would be good to have a comment to answer that.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because I've not seen it come up. But, looking at it with fresh eyes now, I think the safest thing is to always unwrap.