Skip to content

Commit 1fa763b

Browse files
committed
separate test to assert on early termination and update docs
1 parent ee0b122 commit 1fa763b

File tree

4 files changed

+428
-309
lines changed

4 files changed

+428
-309
lines changed

docs/reference/aggregations/bucket/composite-aggregation.asciidoc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -500,13 +500,9 @@ GET /_search
500500

501501
==== Early termination
502502

503-
The `composite` aggregation can early terminate the collection under some circumstances:
504-
505-
* If the primary source extracts values from a numeric or a keyword field and the query matches all documents (`match_all` query).
506-
* If the value sources are a prefix or match entirely the <<index-modules-index-sorting,index sort>> specification.
507-
508503
For optimal performance the <<index-modules-index-sorting,index sort>> should be set on the index so that it matches
509-
parts or fully the source order in the composite aggregation. For instance the following index sort:
504+
parts or fully the source order in the composite aggregation.
505+
For instance the following index sort:
510506

511507
[source,console]
512508
--------------------------------------------------
@@ -608,6 +604,10 @@ If the order of sources do not matter for your use case you can follow these sim
608604
* Make sure that the order of the field matches the order of the index sort.
609605
* Put multi-valued fields last since they cannot be used for early termination.
610606

607+
WARNING: <<index-modules-index-sorting,index sort>> can slowdown indexing, it is very important to test index sorting
608+
with your specific use case and dataset to ensure that it matches your requirement. If it doesn't note that `composite`
609+
aggregations will also try to early terminate on non-sorted indices if the query matches all document (`match_all` query).
610+
611611
==== Sub-aggregations
612612

613613
Like any `multi-bucket` aggregations the `composite` aggregation can hold sub-aggregations.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.search.aggregations.bucket.composite;
21+
22+
import org.apache.lucene.index.DocValues;
23+
import org.apache.lucene.index.Term;
24+
import org.apache.lucene.search.TermQuery;
25+
import org.apache.lucene.util.LuceneTestCase;
26+
import org.elasticsearch.search.sort.SortOrder;
27+
28+
29+
import java.util.ArrayList;
30+
import java.util.Arrays;
31+
import java.util.List;
32+
import java.util.Map;
33+
34+
/** Suppress AssertingCodec because it doesn't work with {@link DocValues#unwrapSingleton} that is used in this test. */
35+
@LuceneTestCase.SuppressCodecs("*")
36+
public class CompositeAggregatorEarlyTerminationTests extends CompositeAggregatorTestCase {
37+
public void testEarlyTermination() throws Exception {
38+
final List<Map<String, List<Object>>> dataset = new ArrayList<>();
39+
dataset.addAll(
40+
Arrays.asList(
41+
createDocument("keyword", "a", "long", 100L, "foo", "bar"),
42+
createDocument("keyword", "c", "long", 100L, "foo", "bar"),
43+
createDocument("keyword", "a", "long", 0L, "foo", "bar"),
44+
createDocument("keyword", "d", "long", 10L, "foo", "bar"),
45+
createDocument("keyword", "b", "long", 10L, "foo", "bar"),
46+
createDocument("keyword", "c", "long", 10L, "foo", "bar"),
47+
createDocument("keyword", "e", "long", 100L, "foo", "bar"),
48+
createDocument("keyword", "e", "long", 10L, "foo", "bar")
49+
)
50+
);
51+
52+
executeTestCase(true, false, new TermQuery(new Term("foo", "bar")),
53+
dataset,
54+
() ->
55+
new CompositeAggregationBuilder("name",
56+
Arrays.asList(
57+
new TermsValuesSourceBuilder("keyword").field("keyword"),
58+
new TermsValuesSourceBuilder("long").field("long")
59+
)).aggregateAfter(createAfterKey("keyword", "b", "long", 10L)).size(2),
60+
(result) -> {
61+
assertEquals(2, result.getBuckets().size());
62+
assertEquals("{keyword=c, long=100}", result.afterKey().toString());
63+
assertEquals("{keyword=c, long=10}", result.getBuckets().get(0).getKeyAsString());
64+
assertEquals(1L, result.getBuckets().get(0).getDocCount());
65+
assertEquals("{keyword=c, long=100}", result.getBuckets().get(1).getKeyAsString());
66+
assertEquals(1L, result.getBuckets().get(1).getDocCount());
67+
assertTrue(result.isTerminatedEarly());
68+
}
69+
);
70+
71+
// source field and index sorting config have different order
72+
executeTestCase(true, false, new TermQuery(new Term("foo", "bar")),
73+
dataset,
74+
() ->
75+
new CompositeAggregationBuilder("name",
76+
Arrays.asList(
77+
// reverse source order
78+
new TermsValuesSourceBuilder("keyword").field("keyword").order(SortOrder.DESC),
79+
new TermsValuesSourceBuilder("long").field("long").order(SortOrder.DESC)
80+
)
81+
).aggregateAfter(createAfterKey("keyword", "c", "long", 10L)).size(2),
82+
(result) -> {
83+
assertEquals(2, result.getBuckets().size());
84+
assertEquals("{keyword=a, long=100}", result.afterKey().toString());
85+
assertEquals("{keyword=b, long=10}", result.getBuckets().get(0).getKeyAsString());
86+
assertEquals(1L, result.getBuckets().get(0).getDocCount());
87+
assertEquals("{keyword=a, long=100}", result.getBuckets().get(1).getKeyAsString());
88+
assertEquals(1L, result.getBuckets().get(1).getDocCount());
89+
assertTrue(result.isTerminatedEarly());
90+
}
91+
);
92+
}
93+
}

0 commit comments

Comments
 (0)