Skip to content

Commit af98730

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

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

Lines changed: 23 additions & 0 deletions
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

Lines changed: 11 additions & 9 deletions
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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.elasticsearch.plugins.SearchPlugin;
2323
import org.elasticsearch.search.aggregations.AggregationBuilder;
2424
import org.elasticsearch.search.aggregations.AggregatorTestCase;
25+
import org.elasticsearch.search.aggregations.bucket.histogram.DoubleBounds;
2526
import org.elasticsearch.search.aggregations.bucket.histogram.HistogramAggregationBuilder;
2627
import org.elasticsearch.search.aggregations.bucket.histogram.InternalHistogram;
2728
import org.elasticsearch.search.aggregations.metrics.TopHitsAggregationBuilder;
@@ -164,6 +165,28 @@ public void testExtendedBounds() throws Exception {
164165
}
165166
}
166167

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

0 commit comments

Comments
 (0)