diff --git a/client/rest-high-level/src/test/java/org/opensearch/client/SearchIT.java b/client/rest-high-level/src/test/java/org/opensearch/client/SearchIT.java index 974aa7fcc990c..e2287eb53db60 100644 --- a/client/rest-high-level/src/test/java/org/opensearch/client/SearchIT.java +++ b/client/rest-high-level/src/test/java/org/opensearch/client/SearchIT.java @@ -84,6 +84,9 @@ import org.opensearch.search.aggregations.bucket.composite.CompositeAggregation; import org.opensearch.search.aggregations.bucket.composite.CompositeValuesSourceBuilder; import org.opensearch.search.aggregations.bucket.composite.TermsValuesSourceBuilder; +import org.opensearch.search.aggregations.bucket.histogram.DateHistogramAggregationBuilder; +import org.opensearch.search.aggregations.bucket.histogram.DateHistogramInterval; +import org.opensearch.search.aggregations.bucket.histogram.ParsedDateHistogram; import org.opensearch.search.aggregations.bucket.range.Range; import org.opensearch.search.aggregations.bucket.range.RangeAggregationBuilder; import org.opensearch.search.aggregations.bucket.terms.MultiTermsAggregationBuilder; @@ -237,6 +240,32 @@ public void indexDocuments() throws IOException { client().performRequest(createFilteredAlias); } + { + Request create = new Request(HttpPut.METHOD_NAME, "/index5"); + create.setJsonEntity( + "{" + + " \"mappings\": {" + + " \"properties\": {" + + " \"date_created\": {" + + " \"type\": \"date\"" + + " }," + + " \"distribution\": {" + + " \"properties\": {" + + " \"number_events\": {" + + " \"type\": \"unsigned_long\"" + + " }" + + " }" + + " }" + + " }" + + " }" + + "}" + ); + client().performRequest(create); + Request doc1 = new Request(HttpPut.METHOD_NAME, "/index5/_doc/1"); + doc1.setJsonEntity("{\"date_created\":\"2024\", \"distribution\":{\"number_events\": 1000000}}"); + client().performRequest(doc1); + } + client().performRequest(new Request(HttpPost.METHOD_NAME, "/_refresh")); } @@ -514,6 +543,38 @@ public void testSearchWithTermsAndRangeAgg() throws IOException { } } + public void testSearchWithDateAndRangeAgg() throws IOException { + SearchRequest searchRequest = new SearchRequest("index5"); + SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); + DateHistogramAggregationBuilder yearAgg = new DateHistogramAggregationBuilder("year").field("date_created") + .calendarInterval(DateHistogramInterval.YEAR) + .format("yyyy"); + + RangeAggregationBuilder rangeAgg = new RangeAggregationBuilder("number_events").field("distribution.number_events") + .addRange("0--999", 0.0, 1000.0) + .addRange("999--", 1000.0, 10_000_000_000_00L); + searchSourceBuilder.aggregation(yearAgg).aggregation(rangeAgg); + searchSourceBuilder.size(0); + searchRequest.source(searchSourceBuilder); + SearchResponse searchResponse = execute(searchRequest, highLevelClient()::search, highLevelClient()::searchAsync); + assertSearchHeader(searchResponse); + ParsedDateHistogram yearHistogram = searchResponse.getAggregations().get("year"); + assertEquals(1, yearHistogram.getBuckets().size()); + assertEquals("2024", yearHistogram.getBuckets().get(0).getKeyAsString()); + Range rangeAggregation = searchResponse.getAggregations().get("number_events"); + assertEquals(2, rangeAggregation.getBuckets().size()); + { + Range.Bucket bucket = rangeAggregation.getBuckets().get(0); + assertEquals("0--999", bucket.getKeyAsString()); + assertEquals(0, bucket.getDocCount()); + } + { + Range.Bucket bucket = rangeAggregation.getBuckets().get(1); + assertEquals("999--", bucket.getKeyAsString()); + assertEquals(1, bucket.getDocCount()); + } + } + public void testSearchWithTermsAndWeightedAvg() throws IOException { SearchRequest searchRequest = new SearchRequest("index"); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); @@ -1786,7 +1847,7 @@ public void testCountAllIndicesNoQuery() throws IOException { CountRequest countRequest = new CountRequest(); CountResponse countResponse = execute(countRequest, highLevelClient()::count, highLevelClient()::countAsync); assertCountHeader(countResponse); - assertEquals(12, countResponse.getCount()); + assertEquals(13, countResponse.getCount()); } public void testCountOneIndexMatchQuery() throws IOException { diff --git a/release-notes/opensearch.release-notes-3.4.0.md b/release-notes/opensearch.release-notes-3.4.0.md index 7cabfed577988..627f97d74fb16 100644 --- a/release-notes/opensearch.release-notes-3.4.0.md +++ b/release-notes/opensearch.release-notes-3.4.0.md @@ -6,11 +6,11 @@ Compatible with OpenSearch and OpenSearch Dashboards version 3.4.0 - Allow setting index.creation_date on index creation and restore for plugin compatibility and migrations ([#19931](https://github.com/opensearch-project/OpenSearch/pull/19931)) - Add support for a ForkJoinPool type ([#19008](https://github.com/opensearch-project/OpenSearch/pull/19008)) - Add seperate shard limit validation for local and remote indices ([#19532](https://github.com/opensearch-project/OpenSearch/pull/19532)) -- Use Lucene `pack` method for `half_float` and `usigned_long` when using `ApproximatePointRangeQuery`. +- Use Lucene `pack` method for `half_float` and `unsigned_long` when using `ApproximatePointRangeQuery` ([#19553](https://github.com/opensearch-project/OpenSearch/pull/19553)) - New cluster setting search.query.max_query_string_length_monitor_only ([#19539](https://github.com/opensearch-project/OpenSearch/pull/19539)) - Add a mapper for context aware segments grouping criteria ([#19233](https://github.com/opensearch-project/OpenSearch/pull/19233)) - Return full error for GRPC error response ([#19568](https://github.com/opensearch-project/OpenSearch/pull/19568)) -- Add support for repository with Server side encryption enabled and client side encryption as well based on a flag. ([#19630](https://github.com/opensearch-project/OpenSearch/pull/19630)) +- Add support for repository with Server side encryption enabled and client side encryption as well based on a flag ([#19630](https://github.com/opensearch-project/OpenSearch/pull/19630)) - Add pluggable gRPC interceptors with explicit ordering([#19005](https://github.com/opensearch-project/OpenSearch/pull/19005)) - Add BindableServices extension point to transport-grpc-spi ([#19304](https://github.com/opensearch-project/OpenSearch/pull/19304)) - Add metrics for the merged segment warmer feature ([#18929](https://github.com/opensearch-project/OpenSearch/pull/18929)) @@ -19,7 +19,7 @@ Compatible with OpenSearch and OpenSearch Dashboards version 3.4.0 - Allow collectors take advantage of preaggregated data using collectRange API ([#20009](https://github.com/opensearch-project/OpenSearch/pull/20009)) - Bulk collection logic for metrics and cardinality aggregations ([#20067](https://github.com/opensearch-project/OpenSearch/pull/20067)) - Add pointer based lag metric in pull-based ingestion ([#19635](https://github.com/opensearch-project/OpenSearch/pull/19635)) -- Introduced internal API for retrieving metadata about requested indices from transport actions ([#18523](https://github.com/opensearch-project/OpenSearch/pull/18523)) +- Introduced internal API for retrieving metadata about requested indices from transport actions ([#18523](https://github.com/opensearch-project/OpenSearch/pull/18523)) - Add cluster defaults for merge autoThrottle, maxMergeThreads, and maxMergeCount; Add segment size filter to the merged segment warmer ([#19629](https://github.com/opensearch-project/OpenSearch/pull/19629)) - Add build-tooling to run in FIPS environment ([#18921](https://github.com/opensearch-project/OpenSearch/pull/18921)) - Add SMILE/CBOR/YAML document format support to Bulk GRPC endpoint ([#19744](https://github.com/opensearch-project/OpenSearch/pull/19744)) @@ -83,9 +83,9 @@ Compatible with OpenSearch and OpenSearch Dashboards version 3.4.0 - Fix pull-based ingestion out-of-bounds offset scenarios and remove persisted offsets ([#19607](https://github.com/opensearch-project/OpenSearch/pull/19607)) - Fix issue with updating core with a patch number other than 0 ([#19377](https://github.com/opensearch-project/OpenSearch/pull/19377)) - [Java Agent] Allow JRT protocol URLs in protection domain extraction ([#19683](https://github.com/opensearch-project/OpenSearch/pull/19683)) -- Fix potential concurrent modification exception when updating allocation filters ([#19701])(https://github.com/opensearch-project/OpenSearch/pull/19701)) +- Fix potential concurrent modification exception when updating allocation filters ([#19701](https://github.com/opensearch-project/OpenSearch/pull/19701)) - Fix wildcard query with escaped backslash followed by wildcard character ([#19719](https://github.com/opensearch-project/OpenSearch/pull/19719)) -- Fix file-based ingestion consumer to handle start point beyond max line number([#19757])(https://github.com/opensearch-project/OpenSearch/pull/19757)) +- Fix file-based ingestion consumer to handle start point beyond max line number ([#19757](https://github.com/opensearch-project/OpenSearch/pull/19757)) - Fix IndexOutOfBoundsException when running include/exclude on non-existent prefix in terms aggregations ([#19637](https://github.com/opensearch-project/OpenSearch/pull/19637)) - Fixed assertion unsafe use of ClusterService.state() in ResourceUsageCollectorService ([#19775](https://github.com/opensearch-project/OpenSearch/pull/19775)) - Fix Unified highlighter for nested fields when using matchPhrasePrefixQuery ([#19442](https://github.com/opensearch-project/OpenSearch/pull/19442)) @@ -102,6 +102,7 @@ Compatible with OpenSearch and OpenSearch Dashboards version 3.4.0 - Fixed handling of property index in BulkRequest during deserialization ([#20132](https://github.com/opensearch-project/OpenSearch/pull/20132)) - Fix negative CPU usage values in node stats ([#19120](https://github.com/opensearch-project/OpenSearch/issues/19120)) - Fix duplicate registration of FieldDataCache dynamic setting ([#20140](https://github.com/opensearch-project/OpenSearch/pull/20140)) +- Fix array out of bounds during aggregation ([#20204](https://github.com/opensearch-project/OpenSearch/pull/20204)) ### Dependencies - Bump Apache Lucene from 10.3.1 to 10.3.2 ([#20026](https://github.com/opensearch-project/OpenSearch/pull/20026)) @@ -131,7 +132,7 @@ Compatible with OpenSearch and OpenSearch Dashboards version 3.4.0 - Bump `netty` to 4.2.4 ([#19178](https://github.com/opensearch-project/OpenSearch/pull/19178)) - Bump `actions/github-script` from 7 to 8 ([#19946](https://github.com/opensearch-project/OpenSearch/pull/19946)) - Bump `com.google.api:gax-httpjson` from 2.69.0 to 2.72.1 ([#19943](https://github.com/opensearch-project/OpenSearch/pull/19943)) -- Update Hadoop to 3.4.2 and enable security (Kerberos) integration tests under JDK-24 and above ([#19952](https://github.com/opensearch-project/OpenSearch/pull/19952)) +- Update Hadoop to 3.4.2 and enable security (Kerberos) integration tests under JDK-24 and above ([#19952](https://github.com/opensearch-project/OpenSearch/pull/19952)) - Bump `com.google.cloud:google-cloud-storage` from 2.55.0 to 2.60.0 ([#20023](https://github.com/opensearch-project/OpenSearch/pull/20023)) - Bump `commons-cli:commons-cli` from 1.10.0 to 1.11.0 ([#20022](https://github.com/opensearch-project/OpenSearch/pull/20022)) - Bump `com.squareup.okio:okio` from 3.16.0 to 3.16.3 ([#20025](https://github.com/opensearch-project/OpenSearch/pull/20025)) diff --git a/server/src/main/java/org/opensearch/search/aggregations/bucket/filterrewrite/Ranges.java b/server/src/main/java/org/opensearch/search/aggregations/bucket/filterrewrite/Ranges.java index 44d94ab4a6658..7018d51284204 100644 --- a/server/src/main/java/org/opensearch/search/aggregations/bucket/filterrewrite/Ranges.java +++ b/server/src/main/java/org/opensearch/search/aggregations/bucket/filterrewrite/Ranges.java @@ -18,7 +18,7 @@ public final class Ranges { byte[][] uppers; // exclusive int size; int byteLen; - static ArrayUtil.ByteArrayComparator comparator; + ArrayUtil.ByteArrayComparator comparator; Ranges(byte[][] lowers, byte[][] uppers) { this.lowers = lowers; @@ -55,15 +55,15 @@ public int firstRangeIndex(byte[] globalMin, byte[] globalMax) { return i; } - public static int compareByteValue(byte[] value1, byte[] value2) { + public int compareByteValue(byte[] value1, byte[] value2) { return comparator.compare(value1, 0, value2, 0); } - public static boolean withinLowerBound(byte[] value, byte[] lowerBound) { + public boolean withinLowerBound(byte[] value, byte[] lowerBound) { return compareByteValue(value, lowerBound) >= 0; } - public static boolean withinUpperBound(byte[] value, byte[] upperBound) { + public boolean withinUpperBound(byte[] value, byte[] upperBound) { return compareByteValue(value, upperBound) < 0; } } diff --git a/server/src/main/java/org/opensearch/search/aggregations/bucket/filterrewrite/rangecollector/AbstractRangeCollector.java b/server/src/main/java/org/opensearch/search/aggregations/bucket/filterrewrite/rangecollector/AbstractRangeCollector.java index c5f0824e2967c..92742ec6eface 100644 --- a/server/src/main/java/org/opensearch/search/aggregations/bucket/filterrewrite/rangecollector/AbstractRangeCollector.java +++ b/server/src/main/java/org/opensearch/search/aggregations/bucket/filterrewrite/rangecollector/AbstractRangeCollector.java @@ -52,12 +52,12 @@ public boolean iterateRangeEnd(byte[] value, boolean inLeaf) { @Override public boolean withinLowerBound(byte[] value) { - return Ranges.withinLowerBound(value, ranges.getLowers()[activeIndex]); + return ranges.withinLowerBound(value, ranges.getLowers()[activeIndex]); } @Override public boolean withinUpperBound(byte[] value) { - return Ranges.withinUpperBound(value, ranges.getUppers()[activeIndex]); + return ranges.withinUpperBound(value, ranges.getUppers()[activeIndex]); } @Override