|
26 | 26 | import org.elasticsearch.script.ScriptType; |
27 | 27 | import org.elasticsearch.search.SearchHit; |
28 | 28 | import org.elasticsearch.search.SearchHits; |
| 29 | +import org.elasticsearch.search.aggregations.AggregationBuilder; |
| 30 | +import org.elasticsearch.search.aggregations.metrics.TopHits; |
29 | 31 | import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; |
30 | 32 | import org.elasticsearch.search.fetch.subphase.highlight.HighlightField; |
31 | 33 | import org.elasticsearch.search.sort.FieldSortBuilder; |
|
51 | 53 | import static org.elasticsearch.index.seqno.SequenceNumbers.UNASSIGNED_SEQ_NO; |
52 | 54 | import static org.elasticsearch.join.query.JoinQueryBuilders.hasChildQuery; |
53 | 55 | import static org.elasticsearch.join.query.JoinQueryBuilders.hasParentQuery; |
| 56 | +import static org.elasticsearch.search.aggregations.AggregationBuilders.topHits; |
54 | 57 | import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; |
55 | 58 | import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; |
56 | 59 | import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCountAndNoFailures; |
|
64 | 67 | import static org.hamcrest.Matchers.containsString; |
65 | 68 | import static org.hamcrest.Matchers.equalTo; |
66 | 69 | import static org.hamcrest.Matchers.greaterThanOrEqualTo; |
| 70 | +import static org.hamcrest.Matchers.lessThanOrEqualTo; |
67 | 71 | import static org.hamcrest.Matchers.notNullValue; |
68 | 72 | import static org.hamcrest.Matchers.nullValue; |
69 | 73 |
|
@@ -698,4 +702,68 @@ public void testTooHighResultWindow() { |
698 | 702 | ) |
699 | 703 | ); |
700 | 704 | } |
| 705 | + |
| 706 | + public void testTopHitsOnParentChild() throws Exception { |
| 707 | + assertAcked( |
| 708 | + prepareCreate("idx").setMapping( |
| 709 | + jsonBuilder().startObject() |
| 710 | + .startObject("_doc") |
| 711 | + .startObject("properties") |
| 712 | + .startObject("id") |
| 713 | + .field("type", "keyword") |
| 714 | + .endObject() |
| 715 | + .startObject("join_field") |
| 716 | + .field("type", "join") |
| 717 | + .startObject("relations") |
| 718 | + .field("parent", new String[] { "child1", "child2" }) |
| 719 | + .endObject() |
| 720 | + .endObject() |
| 721 | + .endObject() |
| 722 | + .endObject() |
| 723 | + .endObject() |
| 724 | + ) |
| 725 | + ); |
| 726 | + ensureGreen("idx"); |
| 727 | + |
| 728 | + List<IndexRequestBuilder> requestBuilders = new ArrayList<>(); |
| 729 | + int numDocs = scaledRandomIntBetween(10, 100); |
| 730 | + int child1 = 0; |
| 731 | + int child2 = 0; |
| 732 | + int[] child1InnerObjects = new int[numDocs]; |
| 733 | + int[] child2InnerObjects = new int[numDocs]; |
| 734 | + for (int parent = 0; parent < numDocs; parent++) { |
| 735 | + String parentId = String.format(Locale.ENGLISH, "p_%03d", parent); |
| 736 | + requestBuilders.add(createIndexRequest("idx", "parent", parentId, null)); |
| 737 | + |
| 738 | + int numChildDocs = child1InnerObjects[parent] = scaledRandomIntBetween(1, numDocs); |
| 739 | + int limit = child1 + numChildDocs; |
| 740 | + for (; child1 < limit; child1++) { |
| 741 | + requestBuilders.add(createIndexRequest("idx", "child1", String.format(Locale.ENGLISH, "c1_%04d", child1), parentId)); |
| 742 | + } |
| 743 | + numChildDocs = child2InnerObjects[parent] = scaledRandomIntBetween(1, numDocs); |
| 744 | + limit = child2 + numChildDocs; |
| 745 | + for (; child2 < limit; child2++) { |
| 746 | + requestBuilders.add(createIndexRequest("idx", "child2", String.format(Locale.ENGLISH, "c2_%04d", child2), parentId)); |
| 747 | + } |
| 748 | + } |
| 749 | + |
| 750 | + indexRandom(true, requestBuilders); |
| 751 | + ensureSearchable(); |
| 752 | + |
| 753 | + QueryBuilder hasChildQuery = hasChildQuery("child2", matchAllQuery(), ScoreMode.None).innerHit(new InnerHitBuilder().setSize(2)); |
| 754 | + AggregationBuilder topHitsAgg = topHits("top-children").size(3); |
| 755 | + |
| 756 | + assertNoFailuresAndResponse(prepareSearch("idx").setQuery(hasChildQuery).addAggregation(topHitsAgg), response -> { |
| 757 | + assertHitCount(response, numDocs); |
| 758 | + |
| 759 | + TopHits topHits = response.getAggregations().get("top-children"); |
| 760 | + SearchHits hits = topHits.getHits(); |
| 761 | + assertThat(hits.getHits().length, equalTo(3)); |
| 762 | + |
| 763 | + for (SearchHit hit : hits) { |
| 764 | + SearchHits innerHits = hit.getInnerHits().get("child2"); |
| 765 | + assertThat(innerHits.getHits().length, lessThanOrEqualTo(2)); |
| 766 | + } |
| 767 | + }); |
| 768 | + } |
701 | 769 | } |
0 commit comments