|
86 | 86 | import org.elasticsearch.search.aggregations.bucket.nested.InternalNested;
|
87 | 87 | import org.elasticsearch.search.aggregations.bucket.nested.NestedAggregationBuilder;
|
88 | 88 | import org.elasticsearch.search.aggregations.bucket.nested.NestedAggregatorTests;
|
| 89 | +import org.elasticsearch.search.aggregations.metrics.CardinalityAggregationBuilder; |
89 | 90 | import org.elasticsearch.search.aggregations.metrics.InternalTopHits;
|
90 | 91 | import org.elasticsearch.search.aggregations.metrics.TopHitsAggregationBuilder;
|
91 | 92 | import org.elasticsearch.search.aggregations.pipeline.BucketScriptPipelineAggregationBuilder;
|
|
113 | 114 | import java.util.function.Function;
|
114 | 115 |
|
115 | 116 | import static java.util.Collections.singleton;
|
| 117 | +import static java.util.stream.Collectors.toList; |
116 | 118 | import static org.elasticsearch.index.mapper.SeqNoFieldMapper.PRIMARY_TERM_NAME;
|
117 | 119 | import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
|
118 | 120 | import static org.elasticsearch.search.aggregations.PipelineAggregatorBuilders.bucketScript;
|
@@ -1419,6 +1421,71 @@ public void testOrderByPipelineAggregation() throws Exception {
|
1419 | 1421 | }
|
1420 | 1422 | }
|
1421 | 1423 |
|
| 1424 | + public void testOrderByCardinality() throws IOException { |
| 1425 | + boolean bIsString = randomBoolean(); |
| 1426 | + TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("a").field("a") |
| 1427 | + .size(3) |
| 1428 | + .shardSize(3) |
| 1429 | + .subAggregation(new CardinalityAggregationBuilder("b").field("b")) |
| 1430 | + .order(BucketOrder.aggregation("b", false)); |
| 1431 | + |
| 1432 | + /* |
| 1433 | + * Build documents where larger "a"s obviously have more distinct "b"s |
| 1434 | + * associated with them. But insert them into Lucene in a random |
| 1435 | + * order using Lucene's randomizeWriter so we'll bump into situations |
| 1436 | + * where documents in the last segment change the outcome of the |
| 1437 | + * cardinality agg. At least, right now the bug has to do with |
| 1438 | + * documents in the last segment. But randomize so we can catch |
| 1439 | + * new and strange bugs in the future. Finally, its important that |
| 1440 | + * we have few enough values that cardinality can be exact. |
| 1441 | + */ |
| 1442 | + List<List<IndexableField>> docs = new ArrayList<>(); |
| 1443 | + for (int a = 0; a < 10; a++) { |
| 1444 | + for (int b = 0; b <= a; b++) { |
| 1445 | + docs.add( |
| 1446 | + List.of( |
| 1447 | + new NumericDocValuesField("a", a), |
| 1448 | + bIsString ? new SortedSetDocValuesField("b", new BytesRef(Integer.toString(b))) : new NumericDocValuesField("b", b) |
| 1449 | + ) |
| 1450 | + ); |
| 1451 | + } |
| 1452 | + } |
| 1453 | + Collections.shuffle(docs, random()); |
| 1454 | + try (Directory directory = newDirectory()) { |
| 1455 | + RandomIndexWriter iw = new RandomIndexWriter(random(), directory); |
| 1456 | + for (List<IndexableField> doc : docs) { |
| 1457 | + iw.addDocument(doc); |
| 1458 | + } |
| 1459 | + iw.close(); |
| 1460 | + |
| 1461 | + try (DirectoryReader unwrapped = DirectoryReader.open(directory); |
| 1462 | + IndexReader indexReader = wrapDirectoryReader(unwrapped)) { |
| 1463 | + IndexSearcher indexSearcher = newIndexSearcher(indexReader); |
| 1464 | + |
| 1465 | + LongTerms terms = searchAndReduce( |
| 1466 | + createIndexSettings(), |
| 1467 | + indexSearcher, |
| 1468 | + new MatchAllDocsQuery(), |
| 1469 | + aggregationBuilder, |
| 1470 | + Integer.MAX_VALUE, |
| 1471 | + false, |
| 1472 | + new NumberFieldMapper.NumberFieldType("a", NumberFieldMapper.NumberType.INTEGER), |
| 1473 | + bIsString |
| 1474 | + ? new KeywordFieldMapper.KeywordFieldType("b") |
| 1475 | + : new NumberFieldMapper.NumberFieldType("b", NumberFieldMapper.NumberType.INTEGER) |
| 1476 | + ); |
| 1477 | + assertThat( |
| 1478 | + terms.getBuckets().stream().map(MultiBucketsAggregation.Bucket::getKey).collect(toList()), |
| 1479 | + equalTo(List.of(9L, 8L, 7L)) |
| 1480 | + ); |
| 1481 | + assertThat( |
| 1482 | + terms.getBuckets().stream().map(MultiBucketsAggregation.Bucket::getDocCount).collect(toList()), |
| 1483 | + equalTo(List.of(10L, 9L, 8L)) |
| 1484 | + ); |
| 1485 | + } |
| 1486 | + } |
| 1487 | + } |
| 1488 | + |
1422 | 1489 | private final SeqNoFieldMapper.SequenceIDFields sequenceIDFields = SeqNoFieldMapper.SequenceIDFields.emptySeqID();
|
1423 | 1490 | private List<Document> generateDocsWithNested(String id, int value, int[] nestedValues) {
|
1424 | 1491 | List<Document> documents = new ArrayList<>();
|
|
0 commit comments