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 {
|
public static class GeoPointFieldType extends MappedFieldType {
|
||||||
GeoPointFieldType() {
|
public GeoPointFieldType() {
|
||||||
}
|
}
|
||||||
|
|
||||||
GeoPointFieldType(GeoPointFieldType ref) {
|
GeoPointFieldType(GeoPointFieldType ref) {
|
||||||
|
|
|
@ -30,19 +30,20 @@ import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class InternalGeoBounds extends InternalMetricsAggregation implements GeoBounds {
|
public class InternalGeoBounds extends InternalMetricsAggregation implements GeoBounds {
|
||||||
private final double top;
|
final double top;
|
||||||
private final double bottom;
|
final double bottom;
|
||||||
private final double posLeft;
|
final double posLeft;
|
||||||
private final double posRight;
|
final double posRight;
|
||||||
private final double negLeft;
|
final double negLeft;
|
||||||
private final double negRight;
|
final double negRight;
|
||||||
private final boolean wrapLongitude;
|
final boolean wrapLongitude;
|
||||||
|
|
||||||
InternalGeoBounds(String name, double top, double bottom, double posLeft, double posRight,
|
InternalGeoBounds(String name, double top, double bottom, double posLeft, double posRight,
|
||||||
double negLeft, double negRight, boolean wrapLongitude,
|
double negLeft, double negRight, boolean wrapLongitude,
|
||||||
List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData) {
|
List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData) {
|
||||||
super(name, pipelineAggregators, metaData);
|
super(name, pipelineAggregators, metaData);
|
||||||
this.top = top;
|
this.top = top;
|
||||||
this.bottom = bottom;
|
this.bottom = bottom;
|
||||||
|
@ -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