Add unit tests for GeoBoundsAggregator/InternalGeoBounds (#23259)
* Add unit tests for GeoBoundsAggregator/InternalGeoBounds Relates #22278
This commit is contained in:
parent
69b1463f7c
commit
76d6b872dd
|
@ -162,7 +162,7 @@ public class GeoPointFieldMapper extends FieldMapper implements ArrayValueMapper
|
|||
}
|
||||
|
||||
public static class GeoPointFieldType extends MappedFieldType {
|
||||
GeoPointFieldType() {
|
||||
public GeoPointFieldType() {
|
||||
}
|
||||
|
||||
GeoPointFieldType(GeoPointFieldType ref) {
|
||||
|
|
|
@ -30,19 +30,20 @@ import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
|||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class InternalGeoBounds extends InternalMetricsAggregation implements GeoBounds {
|
||||
private final double top;
|
||||
private final double bottom;
|
||||
private final double posLeft;
|
||||
private final double posRight;
|
||||
private final double negLeft;
|
||||
private final double negRight;
|
||||
private final boolean wrapLongitude;
|
||||
final double top;
|
||||
final double bottom;
|
||||
final double posLeft;
|
||||
final double posRight;
|
||||
final double negLeft;
|
||||
final double negRight;
|
||||
final boolean wrapLongitude;
|
||||
|
||||
InternalGeoBounds(String name, double top, double bottom, double posLeft, double posRight,
|
||||
double negLeft, double negRight, boolean wrapLongitude,
|
||||
List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData) {
|
||||
double negLeft, double negRight, boolean wrapLongitude,
|
||||
List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData) {
|
||||
super(name, pipelineAggregators, metaData);
|
||||
this.top = top;
|
||||
this.bottom = bottom;
|
||||
|
@ -82,7 +83,7 @@ public class InternalGeoBounds extends InternalMetricsAggregation implements Geo
|
|||
public String getWriteableName() {
|
||||
return GeoBoundsAggregationBuilder.NAME;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public InternalAggregation doReduce(List<InternalAggregation> aggregations, ReduceContext reduceContext) {
|
||||
double top = Double.NEGATIVE_INFINITY;
|
||||
|
@ -187,21 +188,21 @@ public class InternalGeoBounds extends InternalMetricsAggregation implements Geo
|
|||
private static class BoundingBox {
|
||||
private final GeoPoint topLeft;
|
||||
private final GeoPoint bottomRight;
|
||||
|
||||
|
||||
BoundingBox(GeoPoint topLeft, GeoPoint bottomRight) {
|
||||
this.topLeft = topLeft;
|
||||
this.bottomRight = bottomRight;
|
||||
}
|
||||
|
||||
|
||||
public GeoPoint topLeft() {
|
||||
return topLeft;
|
||||
}
|
||||
|
||||
|
||||
public GeoPoint bottomRight() {
|
||||
return bottomRight;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private BoundingBox resolveBoundingBox() {
|
||||
if (Double.isInfinite(top)) {
|
||||
return null;
|
||||
|
@ -242,4 +243,19 @@ public class InternalGeoBounds extends InternalMetricsAggregation implements Geo
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doEquals(Object obj) {
|
||||
InternalGeoBounds other = (InternalGeoBounds) obj;
|
||||
return bottom == other.bottom &&
|
||||
posLeft == other.posLeft &&
|
||||
posRight == other.posRight &&
|
||||
negLeft == other.negLeft &&
|
||||
negRight == other.negRight &&
|
||||
wrapLongitude == other.wrapLongitude;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int doHashCode() {
|
||||
return Objects.hash(bottom, posLeft, posRight, negLeft, negRight, wrapLongitude);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.search.aggregations.metrics.geobounds;
|
||||
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.LatLonDocValuesField;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.RandomIndexWriter;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.index.mapper.GeoPointFieldMapper;
|
||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||
import org.elasticsearch.search.aggregations.AggregatorTestCase;
|
||||
import org.elasticsearch.test.geo.RandomGeoGenerator;
|
||||
|
||||
import static org.elasticsearch.search.aggregations.metrics.geobounds.InternalGeoBoundsTests.GEOHASH_TOLERANCE;
|
||||
import static org.hamcrest.Matchers.closeTo;
|
||||
|
||||
public class GeoBoundsAggregatorTests extends AggregatorTestCase {
|
||||
public void testEmpty() throws Exception {
|
||||
try (Directory dir = newDirectory();
|
||||
RandomIndexWriter w = new RandomIndexWriter(random(), dir)) {
|
||||
GeoBoundsAggregationBuilder aggBuilder = new GeoBoundsAggregationBuilder("my_agg")
|
||||
.field("field")
|
||||
.wrapLongitude(false);
|
||||
|
||||
MappedFieldType fieldType = new GeoPointFieldMapper.GeoPointFieldType();
|
||||
fieldType.setHasDocValues(true);
|
||||
fieldType.setName("field");
|
||||
try (IndexReader reader = w.getReader()) {
|
||||
IndexSearcher searcher = new IndexSearcher(reader);
|
||||
InternalGeoBounds bounds = search(searcher, new MatchAllDocsQuery(), aggBuilder, fieldType);
|
||||
assertTrue(Double.isInfinite(bounds.top));
|
||||
assertTrue(Double.isInfinite(bounds.bottom));
|
||||
assertTrue(Double.isInfinite(bounds.posLeft));
|
||||
assertTrue(Double.isInfinite(bounds.posRight));
|
||||
assertTrue(Double.isInfinite(bounds.negLeft));
|
||||
assertTrue(Double.isInfinite(bounds.negRight));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testRandom() throws Exception {
|
||||
double top = Double.NEGATIVE_INFINITY;
|
||||
double bottom = Double.POSITIVE_INFINITY;
|
||||
double posLeft = Double.POSITIVE_INFINITY;
|
||||
double posRight = Double.NEGATIVE_INFINITY;
|
||||
double negLeft = Double.POSITIVE_INFINITY;
|
||||
double negRight = Double.NEGATIVE_INFINITY;
|
||||
int numDocs = randomIntBetween(50, 100);
|
||||
try (Directory dir = newDirectory();
|
||||
RandomIndexWriter w = new RandomIndexWriter(random(), dir)) {
|
||||
for (int i = 0; i < numDocs; i++) {
|
||||
Document doc = new Document();
|
||||
int numValues = randomIntBetween(1, 5);
|
||||
for (int j = 0; j < numValues; j++) {
|
||||
GeoPoint point = RandomGeoGenerator.randomPoint(random());
|
||||
if (point.getLat() > top) {
|
||||
top = point.getLat();
|
||||
}
|
||||
if (point.getLat() < bottom) {
|
||||
bottom = point.getLat();
|
||||
}
|
||||
if (point.getLon() >= 0 && point.getLon() < posLeft) {
|
||||
posLeft = point.getLon();
|
||||
}
|
||||
if (point.getLon() >= 0 && point.getLon() > posRight) {
|
||||
posRight = point.getLon();
|
||||
}
|
||||
if (point.getLon() < 0 && point.getLon() < negLeft) {
|
||||
negLeft = point.getLon();
|
||||
}
|
||||
if (point.getLon() < 0 && point.getLon() > negRight) {
|
||||
negRight = point.getLon();
|
||||
}
|
||||
doc.add(new LatLonDocValuesField("field", point.getLat(), point.getLon()));
|
||||
}
|
||||
w.addDocument(doc);
|
||||
}
|
||||
GeoBoundsAggregationBuilder aggBuilder = new GeoBoundsAggregationBuilder("my_agg")
|
||||
.field("field")
|
||||
.wrapLongitude(false);
|
||||
|
||||
MappedFieldType fieldType = new GeoPointFieldMapper.GeoPointFieldType();
|
||||
fieldType.setHasDocValues(true);
|
||||
fieldType.setName("field");
|
||||
try (IndexReader reader = w.getReader()) {
|
||||
IndexSearcher searcher = new IndexSearcher(reader);
|
||||
InternalGeoBounds bounds = search(searcher, new MatchAllDocsQuery(), aggBuilder, fieldType);
|
||||
assertThat(bounds.top, closeTo(top, GEOHASH_TOLERANCE));
|
||||
assertThat(bounds.bottom, closeTo(bottom, GEOHASH_TOLERANCE));
|
||||
assertThat(bounds.posLeft, closeTo(posLeft, GEOHASH_TOLERANCE));
|
||||
assertThat(bounds.posRight, closeTo(posRight, GEOHASH_TOLERANCE));
|
||||
assertThat(bounds.negRight, closeTo(negRight, GEOHASH_TOLERANCE));
|
||||
assertThat(bounds.negLeft, closeTo(negLeft, GEOHASH_TOLERANCE));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.search.aggregations.metrics.geobounds;
|
||||
|
||||
import org.elasticsearch.common.io.stream.Writeable;
|
||||
import org.elasticsearch.search.aggregations.InternalAggregationTestCase;
|
||||
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.Matchers.closeTo;
|
||||
|
||||
public class InternalGeoBoundsTests extends InternalAggregationTestCase<InternalGeoBounds> {
|
||||
static final double GEOHASH_TOLERANCE = 1E-5D;
|
||||
|
||||
@Override
|
||||
protected InternalGeoBounds createTestInstance(String name, List<PipelineAggregator> pipelineAggregators,
|
||||
Map<String, Object> metaData) {
|
||||
InternalGeoBounds geo = new InternalGeoBounds(name,
|
||||
randomDouble(), randomDouble(), randomDouble(), randomDouble(),
|
||||
randomDouble(), randomDouble(), randomBoolean(),
|
||||
pipelineAggregators, Collections.emptyMap());
|
||||
return geo;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertReduced(InternalGeoBounds reduced, List<InternalGeoBounds> inputs) {
|
||||
double top = Double.NEGATIVE_INFINITY;
|
||||
double bottom = Double.POSITIVE_INFINITY;
|
||||
double posLeft = Double.POSITIVE_INFINITY;
|
||||
double posRight = Double.NEGATIVE_INFINITY;
|
||||
double negLeft = Double.POSITIVE_INFINITY;
|
||||
double negRight = Double.NEGATIVE_INFINITY;
|
||||
for (InternalGeoBounds bounds : inputs) {
|
||||
if (bounds.top > top) {
|
||||
top = bounds.top;
|
||||
}
|
||||
if (bounds.bottom < bottom) {
|
||||
bottom = bounds.bottom;
|
||||
}
|
||||
if (bounds.posLeft < posLeft) {
|
||||
posLeft = bounds.posLeft;
|
||||
}
|
||||
if (bounds.posRight > posRight) {
|
||||
posRight = bounds.posRight;
|
||||
}
|
||||
if (bounds.negLeft < negLeft) {
|
||||
negLeft = bounds.negLeft;
|
||||
}
|
||||
if (bounds.negRight > negRight) {
|
||||
negRight = bounds.negRight;
|
||||
}
|
||||
}
|
||||
assertThat(reduced.top, closeTo(top, GEOHASH_TOLERANCE));
|
||||
assertThat(reduced.bottom, closeTo(bottom, GEOHASH_TOLERANCE));
|
||||
assertThat(reduced.posLeft, closeTo(posLeft, GEOHASH_TOLERANCE));
|
||||
assertThat(reduced.posRight, closeTo(posRight, GEOHASH_TOLERANCE));
|
||||
assertThat(reduced.negLeft, closeTo(negLeft, GEOHASH_TOLERANCE));
|
||||
assertThat(reduced.negRight, closeTo(negRight, GEOHASH_TOLERANCE));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Writeable.Reader<InternalGeoBounds> instanceReader() {
|
||||
return InternalGeoBounds::new;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue