Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/changelog/98295.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pr: 98295
summary: Skip segment for `MatchNoDocsQuery` filters
area: Aggregations
type: bug
issues:
- 94637
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ private FilterByFilterAggregator(
@Override
protected LeafBucketCollector getLeafCollector(AggregationExecutionContext aggCtx, LeafBucketCollector sub) throws IOException {
assert scoreMode().needsScores() == false;
if (filters().size() == 0) {
if (QueryToFilterAdapter.MatchesNoDocs(filters())) {
return LeafBucketCollector.NO_OP_COLLECTOR;
}
Bits live = aggCtx.getLeafReaderContext().reader().getLiveDocs();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,10 @@ static class Compatible extends FiltersAggregator {

@Override
protected LeafBucketCollector getLeafCollector(AggregationExecutionContext aggCtx, LeafBucketCollector sub) throws IOException {
if (QueryToFilterAdapter.MatchesNoDocs(filters())) {
return LeafBucketCollector.NO_OP_COLLECTOR;
}

IntPredicate[] docFilters = new IntPredicate[filters().size()];
for (int filterOrd = 0; filterOrd < filters().size(); filterOrd++) {
docFilters[filterOrd] = filters().get(filterOrd).matchingDocIds(aggCtx.getLeafReaderContext());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.IndexSortSortedNumericDocValuesRangeQuery;
import org.apache.lucene.search.LeafCollector;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.PointRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreMode;
Expand All @@ -28,6 +29,7 @@
import org.elasticsearch.xcontent.XContentBuilder;

import java.io.IOException;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.IntPredicate;

Expand Down Expand Up @@ -246,4 +248,19 @@ private Weight weight() throws IOException {
}
return weight;
}

/**
* Checks if all passed filters contain MatchNoDocsQuery queries. In this case, filter aggregation produces
* no docs for the given segment.
* @param filters list of filters to check
* @return true if all filters match no docs, otherwise false
*/
static boolean MatchesNoDocs(List<QueryToFilterAdapter> filters) {
for (QueryToFilterAdapter filter : filters) {
if (filter.query() instanceof MatchNoDocsQuery == false) {
return false;
}
}
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -919,14 +919,14 @@ public void testMatchNoneFilter() throws IOException {
matchesMap().entry("segments_with_doc_count_field", 0)
.entry("segments_with_deleted_docs", 0)
.entry("segments_collected", 0)
.entry("segments_counted", greaterThanOrEqualTo(1))
.entry("segments_counted", 0)
.entry(
"filters",
matchesList().item(
matchesMap().entry(
"query",
"MatchNoDocsQuery(\"The \"range\" query was rewritten to a \"match_none\" query.\")"
).entry("segments_counted_in_constant_time", greaterThan(0))
).entry("segments_counted_in_constant_time", 0)
)
)
)
Expand Down Expand Up @@ -958,14 +958,14 @@ public void testMatchNoneTopLevel() throws IOException {
matchesMap().entry("segments_with_doc_count_field", 0)
.entry("segments_with_deleted_docs", 0)
.entry("segments_collected", 0)
.entry("segments_counted", greaterThanOrEqualTo(1))
.entry("segments_counted", 0)
.entry(
"filters",
matchesList().item(
matchesMap().entry(
"query",
"MatchNoDocsQuery(\"The \"range\" query was rewritten to a \"match_none\" query.\")"
).entry("segments_counted_in_constant_time", greaterThan(0))
).entry("segments_counted_in_constant_time", 0)
)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,200 @@ setup:
- match: {hits.hits.0.fields.foo.0: bar }
- match: {hits.hits.1.fields.foo.0: bar }
- match: {hits.hits.2.fields.foo.0: baz }

---
"Simple filter":
- skip:
version: " - 7.6.99"
reason: "constant_keyword was added in 7.7"

- do:
indices.create:
index: bicycles
body:
settings:
number_of_shards: 1
mappings:
properties:
cycle_type:
type: constant_keyword
value: bicycle
id:
type: integer

- do:
bulk:
refresh: true
body:
- index:
_index: bicycles
_id: 1
- id: 1
- index:
_index: bicycles
_id: 2
- id: 2
- index:
_index: bicycles
_id: 3
- id: 3

- do:
search:
index: bicycles
body:
size: 0
aggs:
f:
filter:
term:
cycle_type: bicycle
- match: { hits.total.value: 3 }
- match: { aggregations.f.doc_count: 3 }

- do:
search:
index: bicycles
body:
size: 0
aggs:
f:
filter:
term:
cycle_type: nomatch
- match: { hits.total.value: 3 }
- match: { aggregations.f.doc_count: 0 }


---
"Filter with histogram":
- skip:
version: " - 7.6.99"
reason: "constant_keyword was added in 7.7"

- do:
indices.create:
index: bicycles
body:
settings:
number_of_shards: 1
mappings:
properties:
cycle_type:
type: constant_keyword
value: bicycle
id:
type: integer
status:
type: keyword
price:
type: integer

- do:
bulk:
refresh: true
body:
- index:
_index: bicycles
_id: 1
- id: 1
status: up
price: 100
- index:
_index: bicycles
_id: 2
- id: 2
status: up
price: 150
- index:
_index: bicycles
_id: 3
- id: 3
status: down
price: 200

- do:
search:
index: bicycles
body:
size: 0
aggs:
agg:
histogram:
field: price
interval: 50
aggs:
0-bucket:
filter:
bool:
filter:
- bool:
filter:
- bool:
filter:
- bool:
should:
- term:
id: 1
minimum_should_match: 1
- bool:
should:
- term:
cycle_type: bicycle
minimum_should_match: 1
- bool:
should:
- term:
status: up
minimum_should_match: 1
- match: { hits.total.value: 3 }
- length: { aggregations.agg.buckets: 3 }
- match: { aggregations.agg.buckets.0.key: 100.0 }
- match: { aggregations.agg.buckets.0.0-bucket.doc_count: 1 }
- match: { aggregations.agg.buckets.1.key: 150.0 }
- match: { aggregations.agg.buckets.1.0-bucket.doc_count: 0 }
- match: { aggregations.agg.buckets.2.key: 200.0 }
- match: { aggregations.agg.buckets.2.0-bucket.doc_count: 0 }

- do:
search:
index: bicycles
body:
size: 0
aggs:
agg:
histogram:
field: price
interval: 50
aggs:
0-bucket:
filter:
bool:
filter:
- bool:
filter:
- bool:
filter:
- bool:
should:
- term:
id: 1
minimum_should_match: 1
- bool:
should:
- term:
cycle_type: nomatch
minimum_should_match: 1
- bool:
should:
- term:
status: up
minimum_should_match: 1
- match: { hits.total.value: 3 }
- length: { aggregations.agg.buckets: 3 }
- match: { aggregations.agg.buckets.0.key: 100.0 }
- match: { aggregations.agg.buckets.0.0-bucket.doc_count: 0 }
- match: { aggregations.agg.buckets.1.key: 150.0 }
- match: { aggregations.agg.buckets.1.0-bucket.doc_count: 0 }
- match: { aggregations.agg.buckets.2.key: 200.0 }
- match: { aggregations.agg.buckets.2.0-bucket.doc_count: 0 }