diff --git a/CHANGELOG.md b/CHANGELOG.md index 88af9996fb2a6..d0397412e876b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Changed - Migrate BC libs to their FIPS counterparts ([#14912](https://github.com/opensearch-project/OpenSearch/pull/14912)) - Increase the floor segment size to 16MB ([#17699](https://github.com/opensearch-project/OpenSearch/pull/17699)) +- Unwrap singleton DocValues in date histogram aggregation. ([#17643](https://github.com/opensearch-project/OpenSearch/pull/17643)) - Introduce 512 byte limit to search and ingest pipeline IDs ([#17786](https://github.com/opensearch-project/OpenSearch/pull/17786)) ### Dependencies diff --git a/server/src/main/java/org/opensearch/search/aggregations/bucket/histogram/DateHistogramAggregator.java b/server/src/main/java/org/opensearch/search/aggregations/bucket/histogram/DateHistogramAggregator.java index d825b33a0f150..3d935100fd0d1 100644 --- a/server/src/main/java/org/opensearch/search/aggregations/bucket/histogram/DateHistogramAggregator.java +++ b/server/src/main/java/org/opensearch/search/aggregations/bucket/histogram/DateHistogramAggregator.java @@ -31,7 +31,9 @@ package org.opensearch.search.aggregations.bucket.histogram; +import org.apache.lucene.index.DocValues; import org.apache.lucene.index.LeafReaderContext; +import org.apache.lucene.index.NumericDocValues; import org.apache.lucene.index.SortedNumericDocValues; import org.apache.lucene.search.ScoreMode; import org.apache.lucene.util.CollectionUtil; @@ -201,13 +203,28 @@ public LeafBucketCollector getLeafCollector(LeafReaderContext ctx, LeafBucketCol return LeafBucketCollector.NO_OP_COLLECTOR; } - SortedNumericDocValues values = valuesSource.longValues(ctx); + final SortedNumericDocValues values = valuesSource.longValues(ctx); + final NumericDocValues singleton = DocValues.unwrapSingleton(values); + + if (singleton != null) { + // Optimized path for single-valued fields + return new LeafBucketCollectorBase(sub, values) { + @Override + public void collect(int doc, long owningBucketOrd) throws IOException { + if (singleton.advanceExact(doc)) { + long value = singleton.longValue(); + collectValue(sub, doc, owningBucketOrd, preparedRounding.round(value)); + } + } + }; + } + + // Original path for multi-valued fields return new LeafBucketCollectorBase(sub, values) { @Override public void collect(int doc, long owningBucketOrd) throws IOException { if (values.advanceExact(doc)) { int valuesCount = values.docValueCount(); - long previousRounded = Long.MIN_VALUE; for (int i = 0; i < valuesCount; ++i) { long value = values.nextValue(); @@ -216,15 +233,7 @@ public void collect(int doc, long owningBucketOrd) throws IOException { if (rounded == previousRounded) { continue; } - if (hardBounds == null || hardBounds.contain(rounded)) { - long bucketOrd = bucketOrds.add(owningBucketOrd, rounded); - if (bucketOrd < 0) { // already seen - bucketOrd = -1 - bucketOrd; - collectExistingBucket(sub, doc, bucketOrd); - } else { - collectBucket(sub, doc, bucketOrd); - } - } + collectValue(sub, doc, owningBucketOrd, rounded); previousRounded = rounded; } } @@ -232,6 +241,18 @@ public void collect(int doc, long owningBucketOrd) throws IOException { }; } + private void collectValue(LeafBucketCollector sub, int doc, long owningBucketOrd, long rounded) throws IOException { + if (hardBounds == null || hardBounds.contain(rounded)) { + long bucketOrd = bucketOrds.add(owningBucketOrd, rounded); + if (bucketOrd < 0) { // already seen + bucketOrd = -1 - bucketOrd; + collectExistingBucket(sub, doc, bucketOrd); + } else { + collectBucket(sub, doc, bucketOrd); + } + } + } + private String fetchStarTreeCalendarUnit() { if (this.rounding.unit() == null) { return null;