Skip to content

Commit 2251a7a

Browse files
authored
Add hard_bounds support for histogram field-based histograms (#64246)
hard_bounds should now support histogram fields, previously hard bounds on histogram fields were ignored. Closes #62124
1 parent d2043a4 commit 2251a7a

File tree

3 files changed

+57
-9
lines changed

3 files changed

+57
-9
lines changed

server/src/test/java/org/elasticsearch/search/aggregations/bucket/histogram/NumericHistogramAggregatorTests.java

+23
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,29 @@ public void testExtendedBounds() throws Exception {
428428
}
429429
}
430430

431+
public void testHardBounds() throws Exception {
432+
try (Directory dir = newDirectory(); RandomIndexWriter w = new RandomIndexWriter(random(), dir)) {
433+
for (double value : new double[] { 3.2, -5, -4.5, 4.3 }) {
434+
Document doc = new Document();
435+
doc.add(new SortedNumericDocValuesField("field", NumericUtils.doubleToSortableLong(value)));
436+
w.addDocument(doc);
437+
}
438+
439+
HistogramAggregationBuilder aggBuilder = new HistogramAggregationBuilder("my_agg").field("field")
440+
.interval(5)
441+
.hardBounds(new DoubleBounds(0.0, 10.0));
442+
MappedFieldType fieldType = new NumberFieldMapper.NumberFieldType("field", NumberFieldMapper.NumberType.DOUBLE);
443+
try (IndexReader reader = w.getReader()) {
444+
IndexSearcher searcher = new IndexSearcher(reader);
445+
InternalHistogram histogram = searchAndReduce(searcher, new MatchAllDocsQuery(), aggBuilder, fieldType);
446+
assertEquals(1, histogram.getBuckets().size());
447+
assertEquals(0d, histogram.getBuckets().get(0).getKey());
448+
assertEquals(2, histogram.getBuckets().get(0).getDocCount());
449+
assertTrue(AggregationInspectionHelper.hasValue(histogram));
450+
}
451+
}
452+
}
453+
431454
public void testAsSubAgg() throws IOException {
432455
AggregationBuilder request = new HistogramAggregationBuilder("outer").field("outer").interval(5).subAggregation(
433456
new HistogramAggregationBuilder("inner").field("inner").interval(5).subAggregation(

x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/aggregations/bucket/histogram/HistoBackedHistogramAggregator.java

+11-9
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,18 @@ public void collect(int doc, long owningBucketOrd) throws IOException {
7676

7777
double key = Math.floor((value - offset) / interval);
7878
assert key >= previousKey;
79-
long bucketOrd = bucketOrds.add(owningBucketOrd, Double.doubleToLongBits(key));
80-
if (bucketOrd < 0) { // already seen
81-
bucketOrd = -1 - bucketOrd;
82-
collectExistingBucket(sub, doc, bucketOrd);
83-
} else {
84-
collectBucket(sub, doc, bucketOrd);
79+
if (hardBounds == null || hardBounds.contain(key * interval)) {
80+
long bucketOrd = bucketOrds.add(owningBucketOrd, Double.doubleToLongBits(key));
81+
if (bucketOrd < 0) { // already seen
82+
bucketOrd = -1 - bucketOrd;
83+
collectExistingBucket(sub, doc, bucketOrd);
84+
} else {
85+
collectBucket(sub, doc, bucketOrd);
86+
}
87+
// We have added the document already. We should increment doc_count by count - 1
88+
// so that we have added it count times.
89+
incrementBucketDocCount(bucketOrd, count - 1);
8590
}
86-
// We have added the document already. We should increment doc_count by count - 1
87-
// so that we have added it count times.
88-
incrementBucketDocCount(bucketOrd, count - 1);
8991
previousKey = key;
9092
}
9193
}

x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/aggregations/bucket/histogram/HistoBackedHistogramAggregatorTests.java

+23
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.elasticsearch.plugins.SearchPlugin;
2222
import org.elasticsearch.search.aggregations.AggregationBuilder;
2323
import org.elasticsearch.search.aggregations.AggregatorTestCase;
24+
import org.elasticsearch.search.aggregations.bucket.histogram.DoubleBounds;
2425
import org.elasticsearch.search.aggregations.bucket.histogram.HistogramAggregationBuilder;
2526
import org.elasticsearch.search.aggregations.bucket.histogram.InternalHistogram;
2627
import org.elasticsearch.search.aggregations.metrics.TopHitsAggregationBuilder;
@@ -163,6 +164,28 @@ public void testExtendedBounds() throws Exception {
163164
}
164165
}
165166

167+
public void testHardBounds() throws Exception {
168+
try (Directory dir = newDirectory(); RandomIndexWriter w = new RandomIndexWriter(random(), dir)) {
169+
170+
w.addDocument(singleton(histogramFieldDocValues(FIELD_NAME, new double[] { -4.5, 4.3 })));
171+
w.addDocument(singleton(histogramFieldDocValues(FIELD_NAME, new double[] { -5, 3.2 })));
172+
w.addDocument(singleton(histogramFieldDocValues(FIELD_NAME, new double[] { 1.0, 2.2 })));
173+
w.addDocument(singleton(histogramFieldDocValues(FIELD_NAME, new double[] { -6.0, 12.2 })));
174+
175+
HistogramAggregationBuilder aggBuilder = new HistogramAggregationBuilder("my_agg").field(FIELD_NAME)
176+
.interval(5)
177+
.hardBounds(new DoubleBounds(0.0, 5.0));
178+
try (IndexReader reader = w.getReader()) {
179+
IndexSearcher searcher = new IndexSearcher(reader);
180+
InternalHistogram histogram = searchAndReduce(searcher, new MatchAllDocsQuery(), aggBuilder, defaultFieldType(FIELD_NAME));
181+
assertEquals(1, histogram.getBuckets().size());
182+
assertEquals(0d, histogram.getBuckets().get(0).getKey());
183+
assertEquals(4, histogram.getBuckets().get(0).getDocCount());
184+
assertTrue(AggregationInspectionHelper.hasValue(histogram));
185+
}
186+
}
187+
}
188+
166189
/**
167190
* Test that sub-aggregations are not supported
168191
*/

0 commit comments

Comments
 (0)