From 4eaf2b543278783fc2393f6aebd59b3ef23e6a45 Mon Sep 17 00:00:00 2001 From: fabiankopatschek <34305396+fabiankopatschek@users.noreply.github.com> Date: Mon, 25 Sep 2023 17:55:49 +0200 Subject: [PATCH] Added size attribute to MultiTermsAggregation (#627) * Added size attribute to MultiTermsAggregation Signed-off-by: Fabian Kopatschek * Added integrationTest check if MultiTermsAggregation is supported Signed-off-by: Fabian Kopatschek --------- Signed-off-by: Fabian Kopatschek Signed-off-by: Vacha Shah --- CHANGELOG.md | 1 + .../aggregations/MultiTermsAggregation.java | 33 ++++++- .../AbstractAggregationRequestIT.java | 90 +++++++++++++++++++ 3 files changed, 122 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index deaab93a56..155f0234f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - Added support for "cjk" analyzer ([#604](https://github.com/opensearch-project/opensearch-java/pull/604)) - Added support for wrapper queries ([#630](https://github.com/opensearch-project/opensearch-java/pull/630)) - Added support for "script_fields" in multi search request ([#632](https://github.com/opensearch-project/opensearch-java/pull/632)) +- Added size attribute to MultiTermsAggregation ([#627](https://github.com/opensearch-project/opensearch-java/pull/627)) ### Dependencies - Bumps `org.ajoberstar.grgit:grgit-gradle` from 5.0.0 to 5.2.0 diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/_types/aggregations/MultiTermsAggregation.java b/java-client/src/main/java/org/opensearch/client/opensearch/_types/aggregations/MultiTermsAggregation.java index 7470809839..a4b58fe966 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/_types/aggregations/MultiTermsAggregation.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/_types/aggregations/MultiTermsAggregation.java @@ -43,19 +43,24 @@ import java.util.List; import java.util.function.Function; +import javax.annotation.Nullable; + // typedef: _types.aggregations.MultiTermsAggregation @JsonpDeserializable public class MultiTermsAggregation extends BucketAggregationBase implements AggregationVariant { private final List terms; + @Nullable + private final Integer size; + // --------------------------------------------------------------------------------------------- private MultiTermsAggregation(Builder builder) { super(builder); this.terms = ApiTypeHelper.unmodifiableRequired(builder.terms, this, "terms"); - + this.size = builder.size; } public static MultiTermsAggregation of(Function> fn) { @@ -77,9 +82,22 @@ public final List terms() { return this.terms; } + /** + * API name: {@code size} + */ + @Nullable + public final Integer size() { + return this.size; + } + protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { super.serializeInternal(generator, mapper); + if (this.size != null) { + generator.writeKey("size"); + generator.write(this.size); + + } if (ApiTypeHelper.isDefined(this.terms)) { generator.writeKey("terms"); generator.writeStartArray(); @@ -104,6 +122,9 @@ public static class Builder extends BucketAggregationBase.AbstractBuilder { private List terms; + @Nullable + private Integer size; + /** * Required - API name: {@code terms} *

@@ -133,6 +154,14 @@ public final Builder terms(Function op) { BucketAggregationBase.setupBucketAggregationBaseDeserializer(op); + op.add(Builder::size, JsonpDeserializer.integerDeserializer(), "size"); op.add(Builder::terms, JsonpDeserializer.arrayDeserializer(MultiTermLookup._DESERIALIZER), "terms"); - } } diff --git a/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractAggregationRequestIT.java b/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractAggregationRequestIT.java index 1530024c6a..402792f90f 100644 --- a/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractAggregationRequestIT.java +++ b/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractAggregationRequestIT.java @@ -9,14 +9,18 @@ package org.opensearch.client.opensearch.integTest; import org.junit.Test; +import org.opensearch.Version; import org.opensearch.client.opensearch._types.Refresh; import org.opensearch.client.opensearch._types.aggregations.Aggregation; import org.opensearch.client.opensearch._types.aggregations.AggregationRange; import org.opensearch.client.opensearch._types.aggregations.DateRangeAggregation; import org.opensearch.client.opensearch._types.aggregations.DateRangeExpression; import org.opensearch.client.opensearch._types.aggregations.FieldDateMath; +import org.opensearch.client.opensearch._types.aggregations.MultiTermLookup; +import org.opensearch.client.opensearch._types.aggregations.MultiTermsAggregation; import org.opensearch.client.opensearch._types.aggregations.RangeAggregation; import org.opensearch.client.opensearch._types.mapping.Property; +import org.opensearch.client.opensearch.core.InfoResponse; import org.opensearch.client.opensearch.core.SearchResponse; import java.io.IOException; @@ -63,6 +67,70 @@ public void testDateRangeAggregation() throws Exception { assertEquals(2, buckets.get(2).docCount()); } + @Test + public void testMultiTermsAggregation() throws Exception { + checkIfOpenSearchSupportsMultiTermsAggregation(); + + var index = "test-multiterms-aggregation-no-size"; + createMultiTermsDocuments(index); + var searchResponse = sendAggregateRequest(index, "multiterms", getMultiTermsAggregation(null)); + var multitermsAggregations = searchResponse.aggregations().get("multiterms"); + var buckets = multitermsAggregations._get() + ._toAggregate() + .multiTerms() + .buckets() + .array(); + + assertEquals(3, buckets.size()); + assertEquals(1, buckets.get(0).docCount()); + } + + @Test + public void testMultiTermsAggregationWithSizeFewerThenBucketsSize() throws Exception { + checkIfOpenSearchSupportsMultiTermsAggregation(); + + var index = "test-multiterms-aggregation-fewer-size"; + createMultiTermsDocuments(index); + var searchResponse = sendAggregateRequest(index, "multiterms", getMultiTermsAggregation(1)); + var multitermsAggregations = searchResponse.aggregations().get("multiterms"); + var buckets = multitermsAggregations._get() + ._toAggregate() + .multiTerms() + .buckets() + .array(); + + assertEquals(1, buckets.size()); + assertEquals(1, buckets.get(0).docCount()); + } + + @Test + public void testMultiTermsAggregationWithSizeBiggerThenBucketsSize() throws Exception { + checkIfOpenSearchSupportsMultiTermsAggregation(); + + var index = "test-multiterms-aggregation-bigger-size"; + createMultiTermsDocuments(index); + var searchResponse = sendAggregateRequest(index, "multiterms", getMultiTermsAggregation(50)); + var multitermsAggregations = searchResponse.aggregations().get("multiterms"); + var buckets = multitermsAggregations._get() + ._toAggregate() + .multiTerms() + .buckets() + .array(); + + assertEquals(3, buckets.size()); + assertEquals(1, buckets.get(0).docCount()); + } + + private void checkIfOpenSearchSupportsMultiTermsAggregation() throws Exception { + InfoResponse info = javaClient().info(); + String version = info.version().number(); + if (version.contains("SNAPSHOT")) { + version = version.split("-")[0]; + } + assumeTrue("multi_terms is supported in OpenSearch 2.1.0 and later", + Version.fromString(version).onOrAfter(Version.fromString("2.1.0"))); + } + private Aggregation getExpiryDateRangeAggregation() { DateRangeAggregation expiryDateRangeAggregation = new DateRangeAggregation.Builder() .field("expDate") @@ -79,6 +147,21 @@ private Aggregation getCostValueRangeAggregation() { return new Aggregation.Builder().range(costValueRangeAggregation).build(); } + private Aggregation getMultiTermsAggregation(Integer size) { + MultiTermsAggregation.Builder multiTermsAggregationBuilder = new MultiTermsAggregation.Builder() + .terms(List.of( + MultiTermLookup.of(multiTermLookup -> multiTermLookup.field("cost")), + MultiTermLookup.of(multiTermLookup -> multiTermLookup.field("expDate")) + )); + + if(size != null) { + multiTermsAggregationBuilder = multiTermsAggregationBuilder.size(size); + } + + MultiTermsAggregation multiTermsAggregation = multiTermsAggregationBuilder.build(); + return new Aggregation.Builder().multiTerms(multiTermsAggregation).build(); + } + private SearchResponse sendAggregateRequest(String index, String key, Aggregation value) throws IOException { return javaClient().search( request -> request.index(index) @@ -131,6 +214,13 @@ private void createDateRangeDocuments(String index) throws IOException { javaClient().create(_1 -> _1.index(index).id("6").document(createProduct("oil", 50, 6)).refresh(Refresh.True)); } + private void createMultiTermsDocuments(String index) throws IOException { + createIndex(index); + javaClient().create(_1 -> _1.index(index).id("1").document(createProduct("appleA", 2, 1)).refresh(Refresh.True)); + javaClient().create(_1 -> _1.index(index).id("2").document(createProduct("appleB", 2, 2)).refresh(Refresh.True)); + javaClient().create(_1 -> _1.index(index).id("3").document(createProduct("appleC", 2, 3)).refresh(Refresh.True)); + } + private void createIndex(String index) throws IOException { Property nameValueProp = new Property.Builder() .text(v -> v)