Skip to content

Commit eb26e1a

Browse files
authored
Add unit tests to histogram aggregations. (#22961)
1 parent f09c4e1 commit eb26e1a

File tree

4 files changed

+387
-0
lines changed

4 files changed

+387
-0
lines changed

core/src/main/java/org/elasticsearch/search/aggregations/InternalAggregations.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.util.Iterator;
3434
import java.util.List;
3535
import java.util.Map;
36+
import java.util.Objects;
3637
import java.util.stream.Collectors;
3738

3839
import static java.util.Collections.emptyMap;
@@ -208,4 +209,16 @@ public void writeTo(StreamOutput out) throws IOException {
208209
out.writeNamedWriteableList(aggregations);
209210
}
210211

212+
@Override
213+
public boolean equals(Object obj) {
214+
if (obj == null || getClass() != obj.getClass()) {
215+
return false;
216+
}
217+
return aggregations.equals(((InternalAggregations) obj).aggregations);
218+
}
219+
220+
@Override
221+
public int hashCode() {
222+
return Objects.hash(getClass(), aggregations);
223+
}
211224
}

core/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/InternalHistogram.java

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import java.util.List;
3939
import java.util.ListIterator;
4040
import java.util.Map;
41+
import java.util.Objects;
4142

4243
/**
4344
* Implementation of {@link Histogram}.
@@ -72,6 +73,24 @@ public Bucket(StreamInput in, boolean keyed, DocValueFormat format) throws IOExc
7273
aggregations = InternalAggregations.readAggregations(in);
7374
}
7475

76+
@Override
77+
public boolean equals(Object obj) {
78+
if (obj == null || obj.getClass() != Bucket.class) {
79+
return false;
80+
}
81+
Bucket that = (Bucket) obj;
82+
// No need to take the keyed and format parameters into account,
83+
// they are already stored and tested on the InternalHistogram object
84+
return key == that.key
85+
&& docCount == that.docCount
86+
&& Objects.equals(aggregations, that.aggregations);
87+
}
88+
89+
@Override
90+
public int hashCode() {
91+
return Objects.hash(getClass(), key, docCount, aggregations);
92+
}
93+
7594
@Override
7695
public void writeTo(StreamOutput out) throws IOException {
7796
out.writeDouble(key);
@@ -162,6 +181,23 @@ public void writeTo(StreamOutput out) throws IOException {
162181
subAggregations.writeTo(out);
163182
}
164183

184+
@Override
185+
public boolean equals(Object obj) {
186+
if (obj == null || getClass() != obj.getClass()) {
187+
return false;
188+
}
189+
EmptyBucketInfo that = (EmptyBucketInfo) obj;
190+
return interval == that.interval
191+
&& offset == that.offset
192+
&& minBound == that.minBound
193+
&& maxBound == that.maxBound
194+
&& Objects.equals(subAggregations, that.subAggregations);
195+
}
196+
197+
@Override
198+
public int hashCode() {
199+
return Objects.hash(getClass(), interval, offset, minBound, maxBound, subAggregations);
200+
}
165201
}
166202

167203
private final List<Bucket> buckets;
@@ -429,4 +465,19 @@ public Bucket createBucket(Number key, long docCount, InternalAggregations aggre
429465
return new Bucket(key.doubleValue(), docCount, keyed, format, aggregations);
430466
}
431467

468+
@Override
469+
protected boolean doEquals(Object obj) {
470+
InternalHistogram that = (InternalHistogram) obj;
471+
return Objects.equals(buckets, that.buckets)
472+
&& Objects.equals(emptyBucketInfo, that.emptyBucketInfo)
473+
&& Objects.equals(format, that.format)
474+
&& Objects.equals(keyed, that.keyed)
475+
&& Objects.equals(minDocCount, that.minDocCount)
476+
&& Objects.equals(order, that.order);
477+
}
478+
479+
@Override
480+
protected int doHashCode() {
481+
return Objects.hash(buckets, emptyBucketInfo, format, keyed, minDocCount, order);
482+
}
432483
}
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.search.aggregations.bucket.histogram;
21+
22+
import org.apache.lucene.document.Document;
23+
import org.apache.lucene.document.SortedNumericDocValuesField;
24+
import org.apache.lucene.index.IndexReader;
25+
import org.apache.lucene.index.RandomIndexWriter;
26+
import org.apache.lucene.search.IndexSearcher;
27+
import org.apache.lucene.search.MatchAllDocsQuery;
28+
import org.apache.lucene.store.Directory;
29+
import org.apache.lucene.util.NumericUtils;
30+
import org.elasticsearch.index.mapper.MappedFieldType;
31+
import org.elasticsearch.index.mapper.NumberFieldMapper;
32+
import org.elasticsearch.search.aggregations.AggregatorTestCase;
33+
34+
public class HistogramAggregatorTests extends AggregatorTestCase {
35+
36+
public void testLongs() throws Exception {
37+
try (Directory dir = newDirectory();
38+
RandomIndexWriter w = new RandomIndexWriter(random(), dir)) {
39+
for (long value : new long[] {7, 3, -10, -6, 5, 50}) {
40+
Document doc = new Document();
41+
doc.add(new SortedNumericDocValuesField("field", value));
42+
w.addDocument(doc);
43+
}
44+
45+
HistogramAggregationBuilder aggBuilder = new HistogramAggregationBuilder("my_agg")
46+
.field("field")
47+
.interval(5);
48+
MappedFieldType fieldType = new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.LONG);
49+
fieldType.setName("field");
50+
try (IndexReader reader = w.getReader()) {
51+
IndexSearcher searcher = new IndexSearcher(reader);
52+
Histogram histogram = search(searcher, new MatchAllDocsQuery(), aggBuilder, fieldType);
53+
assertEquals(4, histogram.getBuckets().size());
54+
assertEquals(-10d, histogram.getBuckets().get(0).getKey());
55+
assertEquals(2, histogram.getBuckets().get(0).getDocCount());
56+
assertEquals(0d, histogram.getBuckets().get(1).getKey());
57+
assertEquals(1, histogram.getBuckets().get(1).getDocCount());
58+
assertEquals(5d, histogram.getBuckets().get(2).getKey());
59+
assertEquals(2, histogram.getBuckets().get(2).getDocCount());
60+
assertEquals(50d, histogram.getBuckets().get(3).getKey());
61+
assertEquals(1, histogram.getBuckets().get(3).getDocCount());
62+
}
63+
}
64+
}
65+
66+
public void testDoubles() throws Exception {
67+
try (Directory dir = newDirectory();
68+
RandomIndexWriter w = new RandomIndexWriter(random(), dir)) {
69+
for (double value : new double[] {9.3, 3.2, -10, -6.5, 5.3, 50.1}) {
70+
Document doc = new Document();
71+
doc.add(new SortedNumericDocValuesField("field", NumericUtils.doubleToSortableLong(value)));
72+
w.addDocument(doc);
73+
}
74+
75+
HistogramAggregationBuilder aggBuilder = new HistogramAggregationBuilder("my_agg")
76+
.field("field")
77+
.interval(5);
78+
MappedFieldType fieldType = new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.DOUBLE);
79+
fieldType.setName("field");
80+
try (IndexReader reader = w.getReader()) {
81+
IndexSearcher searcher = new IndexSearcher(reader);
82+
Histogram histogram = search(searcher, new MatchAllDocsQuery(), aggBuilder, fieldType);
83+
assertEquals(4, histogram.getBuckets().size());
84+
assertEquals(-10d, histogram.getBuckets().get(0).getKey());
85+
assertEquals(2, histogram.getBuckets().get(0).getDocCount());
86+
assertEquals(0d, histogram.getBuckets().get(1).getKey());
87+
assertEquals(1, histogram.getBuckets().get(1).getDocCount());
88+
assertEquals(5d, histogram.getBuckets().get(2).getKey());
89+
assertEquals(2, histogram.getBuckets().get(2).getDocCount());
90+
assertEquals(50d, histogram.getBuckets().get(3).getKey());
91+
assertEquals(1, histogram.getBuckets().get(3).getDocCount());
92+
}
93+
}
94+
}
95+
96+
public void testIrrationalInterval() throws Exception {
97+
try (Directory dir = newDirectory();
98+
RandomIndexWriter w = new RandomIndexWriter(random(), dir)) {
99+
for (long value : new long[] {3, 2, -10, 5, -9}) {
100+
Document doc = new Document();
101+
doc.add(new SortedNumericDocValuesField("field", value));
102+
w.addDocument(doc);
103+
}
104+
105+
HistogramAggregationBuilder aggBuilder = new HistogramAggregationBuilder("my_agg")
106+
.field("field")
107+
.interval(Math.PI);
108+
MappedFieldType fieldType = new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.LONG);
109+
fieldType.setName("field");
110+
try (IndexReader reader = w.getReader()) {
111+
IndexSearcher searcher = new IndexSearcher(reader);
112+
Histogram histogram = search(searcher, new MatchAllDocsQuery(), aggBuilder, fieldType);
113+
assertEquals(4, histogram.getBuckets().size());
114+
assertEquals(-4 * Math.PI, histogram.getBuckets().get(0).getKey());
115+
assertEquals(1, histogram.getBuckets().get(0).getDocCount());
116+
assertEquals(-3 * Math.PI, histogram.getBuckets().get(1).getKey());
117+
assertEquals(1, histogram.getBuckets().get(1).getDocCount());
118+
assertEquals(0d, histogram.getBuckets().get(2).getKey());
119+
assertEquals(2, histogram.getBuckets().get(2).getDocCount());
120+
assertEquals(Math.PI, histogram.getBuckets().get(3).getKey());
121+
assertEquals(1, histogram.getBuckets().get(3).getDocCount());
122+
}
123+
}
124+
}
125+
126+
public void testMinDocCount() throws Exception {
127+
try (Directory dir = newDirectory();
128+
RandomIndexWriter w = new RandomIndexWriter(random(), dir)) {
129+
for (long value : new long[] {7, 3, -10, -6, 5, 50}) {
130+
Document doc = new Document();
131+
doc.add(new SortedNumericDocValuesField("field", value));
132+
w.addDocument(doc);
133+
}
134+
135+
HistogramAggregationBuilder aggBuilder = new HistogramAggregationBuilder("my_agg")
136+
.field("field")
137+
.interval(10)
138+
.minDocCount(2);
139+
MappedFieldType fieldType = new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.LONG);
140+
fieldType.setName("field");
141+
try (IndexReader reader = w.getReader()) {
142+
IndexSearcher searcher = new IndexSearcher(reader);
143+
Histogram histogram = searchAndReduce(searcher, new MatchAllDocsQuery(), aggBuilder, fieldType);
144+
assertEquals(2, histogram.getBuckets().size());
145+
assertEquals(-10d, histogram.getBuckets().get(0).getKey());
146+
assertEquals(2, histogram.getBuckets().get(0).getDocCount());
147+
assertEquals(0d, histogram.getBuckets().get(1).getKey());
148+
assertEquals(3, histogram.getBuckets().get(1).getDocCount());
149+
}
150+
}
151+
}
152+
153+
public void testMissing() throws Exception {
154+
try (Directory dir = newDirectory();
155+
RandomIndexWriter w = new RandomIndexWriter(random(), dir)) {
156+
for (long value : new long[] {7, 3, -10, -6, 5, 50}) {
157+
Document doc = new Document();
158+
doc.add(new SortedNumericDocValuesField("field", value));
159+
w.addDocument(doc);
160+
w.addDocument(new Document());
161+
}
162+
163+
HistogramAggregationBuilder aggBuilder = new HistogramAggregationBuilder("my_agg")
164+
.field("field")
165+
.interval(5)
166+
.missing(2d);
167+
MappedFieldType fieldType = new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.LONG);
168+
fieldType.setName("field");
169+
try (IndexReader reader = w.getReader()) {
170+
IndexSearcher searcher = new IndexSearcher(reader);
171+
Histogram histogram = search(searcher, new MatchAllDocsQuery(), aggBuilder, fieldType);
172+
assertEquals(4, histogram.getBuckets().size());
173+
assertEquals(-10d, histogram.getBuckets().get(0).getKey());
174+
assertEquals(2, histogram.getBuckets().get(0).getDocCount());
175+
assertEquals(0d, histogram.getBuckets().get(1).getKey());
176+
assertEquals(7, histogram.getBuckets().get(1).getDocCount());
177+
assertEquals(5d, histogram.getBuckets().get(2).getKey());
178+
assertEquals(2, histogram.getBuckets().get(2).getDocCount());
179+
assertEquals(50d, histogram.getBuckets().get(3).getKey());
180+
assertEquals(1, histogram.getBuckets().get(3).getDocCount());
181+
}
182+
}
183+
}
184+
185+
public void testOffset() throws Exception {
186+
try (Directory dir = newDirectory();
187+
RandomIndexWriter w = new RandomIndexWriter(random(), dir)) {
188+
for (double value : new double[] {9.3, 3.2, -5, -6.5, 5.3}) {
189+
Document doc = new Document();
190+
doc.add(new SortedNumericDocValuesField("field", NumericUtils.doubleToSortableLong(value)));
191+
w.addDocument(doc);
192+
}
193+
194+
HistogramAggregationBuilder aggBuilder = new HistogramAggregationBuilder("my_agg")
195+
.field("field")
196+
.interval(5)
197+
.offset(Math.PI);
198+
MappedFieldType fieldType = new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.DOUBLE);
199+
fieldType.setName("field");
200+
try (IndexReader reader = w.getReader()) {
201+
IndexSearcher searcher = new IndexSearcher(reader);
202+
Histogram histogram = search(searcher, new MatchAllDocsQuery(), aggBuilder, fieldType);
203+
assertEquals(3, histogram.getBuckets().size());
204+
assertEquals(-10 + Math.PI, histogram.getBuckets().get(0).getKey());
205+
assertEquals(2, histogram.getBuckets().get(0).getDocCount());
206+
assertEquals(Math.PI, histogram.getBuckets().get(1).getKey());
207+
assertEquals(2, histogram.getBuckets().get(1).getDocCount());
208+
assertEquals(5 + Math.PI, histogram.getBuckets().get(2).getKey());
209+
assertEquals(1, histogram.getBuckets().get(2).getDocCount());
210+
}
211+
}
212+
}
213+
214+
public void testExtendedBounds() throws Exception {
215+
try (Directory dir = newDirectory();
216+
RandomIndexWriter w = new RandomIndexWriter(random(), dir)) {
217+
for (double value : new double[] {3.2, -5, -4.5, 4.3}) {
218+
Document doc = new Document();
219+
doc.add(new SortedNumericDocValuesField("field", NumericUtils.doubleToSortableLong(value)));
220+
w.addDocument(doc);
221+
}
222+
223+
HistogramAggregationBuilder aggBuilder = new HistogramAggregationBuilder("my_agg")
224+
.field("field")
225+
.interval(5)
226+
.extendedBounds(-12, 13);
227+
MappedFieldType fieldType = new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.DOUBLE);
228+
fieldType.setName("field");
229+
try (IndexReader reader = w.getReader()) {
230+
IndexSearcher searcher = new IndexSearcher(reader);
231+
Histogram histogram = searchAndReduce(searcher, new MatchAllDocsQuery(), aggBuilder, fieldType);
232+
assertEquals(6, histogram.getBuckets().size());
233+
assertEquals(-15d, histogram.getBuckets().get(0).getKey());
234+
assertEquals(0, histogram.getBuckets().get(0).getDocCount());
235+
assertEquals(-10d, histogram.getBuckets().get(1).getKey());
236+
assertEquals(0, histogram.getBuckets().get(1).getDocCount());
237+
assertEquals(-5d, histogram.getBuckets().get(2).getKey());
238+
assertEquals(2, histogram.getBuckets().get(2).getDocCount());
239+
assertEquals(0d, histogram.getBuckets().get(3).getKey());
240+
assertEquals(2, histogram.getBuckets().get(3).getDocCount());
241+
assertEquals(5d, histogram.getBuckets().get(4).getKey());
242+
assertEquals(0, histogram.getBuckets().get(4).getDocCount());
243+
assertEquals(10d, histogram.getBuckets().get(5).getKey());
244+
assertEquals(0, histogram.getBuckets().get(5).getDocCount());
245+
}
246+
}
247+
}
248+
}

0 commit comments

Comments
 (0)