Adding tests for median sort mode to GeoDistanceSortBuilderIT
Also adding checks for median SortMode on non-numeric field types to FieldSortBuilder, removing some unused code and switching GeoDistanceSortBuilder to using ParseField.
This commit is contained in:
parent
d9de129995
commit
4c3d889de4
|
@ -260,8 +260,8 @@ public class FieldSortBuilder extends SortBuilder<FieldSortBuilder> implements S
|
|||
localSortMode = MultiValueMode.fromString(sortMode.toString());
|
||||
}
|
||||
|
||||
if (fieldType.isNumeric() == false && (sortMode == SortMode.SUM || sortMode == SortMode.AVG)) {
|
||||
throw new QueryShardException(context, "we only support AVG and SUM on number based fields");
|
||||
if (fieldType.isNumeric() == false && (sortMode == SortMode.SUM || sortMode == SortMode.AVG || sortMode == SortMode.MEDIAN)) {
|
||||
throw new QueryShardException(context, "we only support AVG, MEDIAN and SUM on number based fields");
|
||||
}
|
||||
|
||||
boolean reverse = (order == SortOrder.DESC);
|
||||
|
|
|
@ -27,6 +27,8 @@ import org.apache.lucene.search.SortField;
|
|||
import org.apache.lucene.util.BitSet;
|
||||
import org.elasticsearch.ElasticsearchParseException;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.ParseFieldMatcher;
|
||||
import org.elasticsearch.common.geo.GeoDistance;
|
||||
import org.elasticsearch.common.geo.GeoDistance.FixedSourceDistance;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
|
@ -62,6 +64,14 @@ public class GeoDistanceSortBuilder extends SortBuilder<GeoDistanceSortBuilder>
|
|||
public static final String NAME = "_geo_distance";
|
||||
public static final boolean DEFAULT_COERCE = false;
|
||||
public static final boolean DEFAULT_IGNORE_MALFORMED = false;
|
||||
public static final ParseField UNIT_FIELD = new ParseField("unit");
|
||||
public static final ParseField REVERSE_FIELD = new ParseField("reverse");
|
||||
public static final ParseField DISTANCE_TYPE_FIELD = new ParseField("distance_type");
|
||||
public static final ParseField COERCE_FIELD = new ParseField("coerce", "normalize");
|
||||
public static final ParseField IGNORE_MALFORMED_FIELD = new ParseField("ignore_malformed");
|
||||
public static final ParseField SORTMODE_FIELD = new ParseField("mode", "sort_mode");
|
||||
public static final ParseField NESTED_PATH_FIELD = new ParseField("nested_path");
|
||||
public static final ParseField NESTED_FILTER_FIELD = new ParseField("nested_filter");
|
||||
|
||||
static final GeoDistanceSortBuilder PROTOTYPE = new GeoDistanceSortBuilder("", -1, -1);
|
||||
|
||||
|
@ -297,22 +307,22 @@ public class GeoDistanceSortBuilder extends SortBuilder<GeoDistanceSortBuilder>
|
|||
}
|
||||
builder.endArray();
|
||||
|
||||
builder.field("unit", unit);
|
||||
builder.field("distance_type", geoDistance.name().toLowerCase(Locale.ROOT));
|
||||
builder.field(UNIT_FIELD.getPreferredName(), unit);
|
||||
builder.field(DISTANCE_TYPE_FIELD.getPreferredName(), geoDistance.name().toLowerCase(Locale.ROOT));
|
||||
builder.field(ORDER_FIELD.getPreferredName(), order);
|
||||
|
||||
if (sortMode != null) {
|
||||
builder.field("mode", sortMode);
|
||||
builder.field(SORTMODE_FIELD.getPreferredName(), sortMode);
|
||||
}
|
||||
|
||||
if (nestedPath != null) {
|
||||
builder.field("nested_path", nestedPath);
|
||||
builder.field(NESTED_PATH_FIELD.getPreferredName(), nestedPath);
|
||||
}
|
||||
if (nestedFilter != null) {
|
||||
builder.field("nested_filter", nestedFilter, params);
|
||||
builder.field(NESTED_FILTER_FIELD.getPreferredName(), nestedFilter, params);
|
||||
}
|
||||
builder.field("coerce", coerce);
|
||||
builder.field("ignore_malformed", ignoreMalformed);
|
||||
builder.field(COERCE_FIELD.getPreferredName(), coerce);
|
||||
builder.field(IGNORE_MALFORMED_FIELD.getPreferredName(), ignoreMalformed);
|
||||
|
||||
builder.endObject();
|
||||
return builder;
|
||||
|
@ -400,6 +410,7 @@ public class GeoDistanceSortBuilder extends SortBuilder<GeoDistanceSortBuilder>
|
|||
@Override
|
||||
public GeoDistanceSortBuilder fromXContent(QueryParseContext context, String elementName) throws IOException {
|
||||
XContentParser parser = context.parser();
|
||||
ParseFieldMatcher parseFieldMatcher = context.parseFieldMatcher();
|
||||
String fieldName = null;
|
||||
List<GeoPoint> geoPoints = new ArrayList<>();
|
||||
DistanceUnit unit = DistanceUnit.DEFAULT;
|
||||
|
@ -422,7 +433,7 @@ public class GeoDistanceSortBuilder extends SortBuilder<GeoDistanceSortBuilder>
|
|||
|
||||
fieldName = currentName;
|
||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
if ("nested_filter".equals(currentName) || "nestedFilter".equals(currentName)) {
|
||||
if (parseFieldMatcher.match(currentName, NESTED_FILTER_FIELD)) {
|
||||
nestedFilter = context.parseInnerQueryBuilder();
|
||||
} else {
|
||||
// the json in the format of -> field : { lat : 30, lon : 12 }
|
||||
|
@ -432,27 +443,27 @@ public class GeoDistanceSortBuilder extends SortBuilder<GeoDistanceSortBuilder>
|
|||
geoPoints.add(point);
|
||||
}
|
||||
} else if (token.isValue()) {
|
||||
if ("reverse".equals(currentName)) {
|
||||
if (parseFieldMatcher.match(currentName, REVERSE_FIELD)) {
|
||||
order = parser.booleanValue() ? SortOrder.DESC : SortOrder.ASC;
|
||||
} else if ("order".equals(currentName)) {
|
||||
} else if (parseFieldMatcher.match(currentName, ORDER_FIELD)) {
|
||||
order = SortOrder.fromString(parser.text());
|
||||
} else if ("unit".equals(currentName)) {
|
||||
} else if (parseFieldMatcher.match(currentName, UNIT_FIELD)) {
|
||||
unit = DistanceUnit.fromString(parser.text());
|
||||
} else if ("distance_type".equals(currentName) || "distanceType".equals(currentName)) {
|
||||
} else if (parseFieldMatcher.match(currentName, DISTANCE_TYPE_FIELD)) {
|
||||
geoDistance = GeoDistance.fromString(parser.text());
|
||||
} else if ("coerce".equals(currentName) || "normalize".equals(currentName)) {
|
||||
} else if (parseFieldMatcher.match(currentName, COERCE_FIELD)) {
|
||||
coerce = parser.booleanValue();
|
||||
if (coerce == true) {
|
||||
ignoreMalformed = true;
|
||||
}
|
||||
} else if ("ignore_malformed".equals(currentName)) {
|
||||
} else if (parseFieldMatcher.match(currentName, IGNORE_MALFORMED_FIELD)) {
|
||||
boolean ignore_malformed_value = parser.booleanValue();
|
||||
if (coerce == false) {
|
||||
ignoreMalformed = ignore_malformed_value;
|
||||
}
|
||||
} else if ("sort_mode".equals(currentName) || "sortMode".equals(currentName) || "mode".equals(currentName)) {
|
||||
} else if (parseFieldMatcher.match(currentName, SORTMODE_FIELD)) {
|
||||
sortMode = SortMode.fromString(parser.text());
|
||||
} else if ("nested_path".equals(currentName) || "nestedPath".equals(currentName)) {
|
||||
} else if (parseFieldMatcher.match(currentName, NESTED_PATH_FIELD)) {
|
||||
nestedPath = parser.text();
|
||||
} else {
|
||||
GeoPoint point = new GeoPoint();
|
||||
|
@ -511,10 +522,6 @@ public class GeoDistanceSortBuilder extends SortBuilder<GeoDistanceSortBuilder>
|
|||
finalSortMode = MultiValueMode.fromString(sortMode.toString());
|
||||
}
|
||||
|
||||
if (sortMode == SortMode.SUM) {
|
||||
throw new IllegalArgumentException("sort_mode [sum] isn't supported for sorting by geo distance");
|
||||
}
|
||||
|
||||
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
||||
if (fieldType == null) {
|
||||
throw new IllegalArgumentException("failed to find mapper for [" + fieldName + "] for geo distance based sort");
|
||||
|
|
|
@ -77,7 +77,7 @@ public class ScriptSortBuilder extends SortBuilder<ScriptSortBuilder> implements
|
|||
|
||||
private final Script script;
|
||||
|
||||
private ScriptSortType type;
|
||||
private final ScriptSortType type;
|
||||
|
||||
private SortMode sortMode;
|
||||
|
||||
|
@ -125,11 +125,15 @@ public class ScriptSortBuilder extends SortBuilder<ScriptSortBuilder> implements
|
|||
}
|
||||
|
||||
/**
|
||||
* Defines which distance to use for sorting in the case a document contains multiple geo points.
|
||||
* Possible values: min and max
|
||||
* Defines which distance to use for sorting in the case a document contains multiple values.<br>
|
||||
* For {@link ScriptSortType#STRING}, the set of possible values is restricted to {@link SortMode#MIN} and {@link SortMode#MAX}
|
||||
*/
|
||||
public ScriptSortBuilder sortMode(SortMode sortMode) {
|
||||
Objects.requireNonNull(sortMode, "sort mode cannot be null.");
|
||||
if (ScriptSortType.STRING.equals(type) && (sortMode == SortMode.SUM || sortMode == SortMode.AVG ||
|
||||
sortMode == SortMode.MEDIAN)) {
|
||||
throw new IllegalArgumentException("script sort of type [string] doesn't support mode [" + sortMode + "]");
|
||||
}
|
||||
this.sortMode = sortMode;
|
||||
return this;
|
||||
}
|
||||
|
@ -271,10 +275,6 @@ public class ScriptSortBuilder extends SortBuilder<ScriptSortBuilder> implements
|
|||
final SearchScript searchScript = context.getScriptService().search(
|
||||
context.lookup(), script, ScriptContext.Standard.SEARCH, Collections.emptyMap());
|
||||
|
||||
if (ScriptSortType.STRING.equals(type) && (sortMode == SortMode.SUM || sortMode == SortMode.AVG)) {
|
||||
throw new QueryShardException(context, "type [string] doesn't support mode [" + sortMode + "]");
|
||||
}
|
||||
|
||||
MultiValueMode valueMode = null;
|
||||
if (sortMode != null) {
|
||||
valueMode = MultiValueMode.fromString(sortMode.toString());
|
||||
|
@ -311,7 +311,6 @@ public class ScriptSortBuilder extends SortBuilder<ScriptSortBuilder> implements
|
|||
};
|
||||
break;
|
||||
case NUMBER:
|
||||
// TODO: should we rather sort missing values last?
|
||||
fieldComparatorSource = new DoubleValuesComparatorSource(null, Double.MAX_VALUE, valueMode, nested) {
|
||||
LeafSearchScript leafScript;
|
||||
@Override
|
||||
|
|
|
@ -181,7 +181,6 @@ public class ScriptSortParser implements SortParser {
|
|||
};
|
||||
break;
|
||||
case NUMBER:
|
||||
// TODO: should we rather sort missing values last?
|
||||
fieldComparatorSource = new DoubleValuesComparatorSource(null, Double.MAX_VALUE, sortMode, nested) {
|
||||
LeafSearchScript leafScript;
|
||||
@Override
|
||||
|
|
|
@ -76,7 +76,7 @@ public abstract class AbstractSortTestCase<T extends SortBuilder<T> & SortBuilde
|
|||
|
||||
protected static NamedWriteableRegistry namedWriteableRegistry;
|
||||
|
||||
private static final int NUMBER_OF_TESTBUILDERS = 500;
|
||||
private static final int NUMBER_OF_TESTBUILDERS = 20;
|
||||
static IndicesQueriesRegistry indicesQueriesRegistry;
|
||||
private static SortParseElement parseElement = new SortParseElement();
|
||||
private static ScriptService scriptService;
|
||||
|
|
|
@ -999,6 +999,42 @@ public class FieldSortIT extends ESIntegTestCase {
|
|||
assertThat(searchResponse.getHits().getAt(2).id(), equalTo(Integer.toString(3)));
|
||||
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).longValue(), equalTo(2L));
|
||||
|
||||
searchResponse = client().prepareSearch()
|
||||
.setQuery(matchAllQuery())
|
||||
.setSize(10)
|
||||
.addSort(SortBuilders.fieldSort("long_values").order(SortOrder.DESC).sortMode(SortMode.AVG))
|
||||
.execute().actionGet();
|
||||
|
||||
assertThat(searchResponse.getHits().getTotalHits(), equalTo(3L));
|
||||
assertThat(searchResponse.getHits().hits().length, equalTo(3));
|
||||
|
||||
assertThat(searchResponse.getHits().getAt(0).id(), equalTo(Integer.toString(2)));
|
||||
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).longValue(), equalTo(13L));
|
||||
|
||||
assertThat(searchResponse.getHits().getAt(1).id(), equalTo(Integer.toString(1)));
|
||||
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).longValue(), equalTo(6L));
|
||||
|
||||
assertThat(searchResponse.getHits().getAt(2).id(), equalTo(Integer.toString(3)));
|
||||
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).longValue(), equalTo(1L));
|
||||
|
||||
searchResponse = client().prepareSearch()
|
||||
.setQuery(matchAllQuery())
|
||||
.setSize(10)
|
||||
.addSort(SortBuilders.fieldSort("long_values").order(SortOrder.DESC).sortMode(SortMode.MEDIAN))
|
||||
.execute().actionGet();
|
||||
|
||||
assertThat(searchResponse.getHits().getTotalHits(), equalTo(3L));
|
||||
assertThat(searchResponse.getHits().hits().length, equalTo(3));
|
||||
|
||||
assertThat(searchResponse.getHits().getAt(0).id(), equalTo(Integer.toString(2)));
|
||||
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).longValue(), equalTo(13L));
|
||||
|
||||
assertThat(searchResponse.getHits().getAt(1).id(), equalTo(Integer.toString(1)));
|
||||
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).longValue(), equalTo(7L));
|
||||
|
||||
assertThat(searchResponse.getHits().getAt(2).id(), equalTo(Integer.toString(3)));
|
||||
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).longValue(), equalTo(2L));
|
||||
|
||||
searchResponse = client().prepareSearch()
|
||||
.setQuery(matchAllQuery())
|
||||
.setSize(10)
|
||||
|
|
|
@ -50,6 +50,8 @@ import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSort
|
|||
import static org.hamcrest.Matchers.closeTo;
|
||||
|
||||
public class GeoDistanceSortBuilderIT extends ESIntegTestCase {
|
||||
private static final String LOCATION_FIELD = "location";
|
||||
|
||||
@Override
|
||||
protected Collection<Class<? extends Plugin>> nodePlugins() {
|
||||
return pluginList(InternalSettingsPlugin.class);
|
||||
|
@ -69,7 +71,7 @@ public class GeoDistanceSortBuilderIT extends ESIntegTestCase {
|
|||
*/
|
||||
Version version = VersionUtils.randomVersionBetween(random(), Version.V_2_0_0, Version.CURRENT);
|
||||
Settings settings = Settings.settingsBuilder().put(IndexMetaData.SETTING_VERSION_CREATED, version).build();
|
||||
assertAcked(prepareCreate("index").setSettings(settings).addMapping("type", "location", "type=geo_point"));
|
||||
assertAcked(prepareCreate("index").setSettings(settings).addMapping("type", LOCATION_FIELD, "type=geo_point"));
|
||||
XContentBuilder d1Builder = jsonBuilder();
|
||||
GeoPoint[] d1Points = {new GeoPoint(3, 2), new GeoPoint(4, 1)};
|
||||
createShuffeldJSONArray(d1Builder, d1Points);
|
||||
|
@ -95,7 +97,7 @@ public class GeoDistanceSortBuilderIT extends ESIntegTestCase {
|
|||
|
||||
SearchResponse searchResponse = client().prepareSearch()
|
||||
.setQuery(matchAllQuery())
|
||||
.addSort(new GeoDistanceSortBuilder("location", q).sortMode(SortMode.MIN).order(SortOrder.ASC).geoDistance(GeoDistance.PLANE).unit(DistanceUnit.KILOMETERS))
|
||||
.addSort(new GeoDistanceSortBuilder(LOCATION_FIELD, q).sortMode(SortMode.MIN).order(SortOrder.ASC).geoDistance(GeoDistance.PLANE).unit(DistanceUnit.KILOMETERS))
|
||||
.execute().actionGet();
|
||||
assertOrderedSearchHits(searchResponse, "d1", "d2");
|
||||
assertThat((Double)searchResponse.getHits().getAt(0).getSortValues()[0], closeTo(GeoDistance.PLANE.calculate(2, 2, 3, 2, DistanceUnit.KILOMETERS), 0.01d));
|
||||
|
@ -103,7 +105,7 @@ public class GeoDistanceSortBuilderIT extends ESIntegTestCase {
|
|||
|
||||
searchResponse = client().prepareSearch()
|
||||
.setQuery(matchAllQuery())
|
||||
.addSort(new GeoDistanceSortBuilder("location", q).sortMode(SortMode.MIN).order(SortOrder.DESC).geoDistance(GeoDistance.PLANE).unit(DistanceUnit.KILOMETERS))
|
||||
.addSort(new GeoDistanceSortBuilder(LOCATION_FIELD, q).sortMode(SortMode.MIN).order(SortOrder.DESC).geoDistance(GeoDistance.PLANE).unit(DistanceUnit.KILOMETERS))
|
||||
.execute().actionGet();
|
||||
assertOrderedSearchHits(searchResponse, "d2", "d1");
|
||||
assertThat((Double)searchResponse.getHits().getAt(0).getSortValues()[0], closeTo(GeoDistance.PLANE.calculate(2, 1, 5, 1, DistanceUnit.KILOMETERS), 0.01d));
|
||||
|
@ -111,7 +113,7 @@ public class GeoDistanceSortBuilderIT extends ESIntegTestCase {
|
|||
|
||||
searchResponse = client().prepareSearch()
|
||||
.setQuery(matchAllQuery())
|
||||
.addSort(new GeoDistanceSortBuilder("location", q).sortMode(SortMode.MAX).order(SortOrder.ASC).geoDistance(GeoDistance.PLANE).unit(DistanceUnit.KILOMETERS))
|
||||
.addSort(new GeoDistanceSortBuilder(LOCATION_FIELD, q).sortMode(SortMode.MAX).order(SortOrder.ASC).geoDistance(GeoDistance.PLANE).unit(DistanceUnit.KILOMETERS))
|
||||
.execute().actionGet();
|
||||
assertOrderedSearchHits(searchResponse, "d1", "d2");
|
||||
assertThat((Double)searchResponse.getHits().getAt(0).getSortValues()[0], closeTo(GeoDistance.PLANE.calculate(2, 2, 4, 1, DistanceUnit.KILOMETERS), 0.01d));
|
||||
|
@ -119,18 +121,61 @@ public class GeoDistanceSortBuilderIT extends ESIntegTestCase {
|
|||
|
||||
searchResponse = client().prepareSearch()
|
||||
.setQuery(matchAllQuery())
|
||||
.addSort(new GeoDistanceSortBuilder("location", q).sortMode(SortMode.MAX).order(SortOrder.DESC).geoDistance(GeoDistance.PLANE).unit(DistanceUnit.KILOMETERS))
|
||||
.addSort(new GeoDistanceSortBuilder(LOCATION_FIELD, q).sortMode(SortMode.MAX).order(SortOrder.DESC).geoDistance(GeoDistance.PLANE).unit(DistanceUnit.KILOMETERS))
|
||||
.execute().actionGet();
|
||||
assertOrderedSearchHits(searchResponse, "d2", "d1");
|
||||
assertThat((Double)searchResponse.getHits().getAt(0).getSortValues()[0], closeTo(GeoDistance.PLANE.calculate(2, 1, 6, 2, DistanceUnit.KILOMETERS), 0.01d));
|
||||
assertThat((Double)searchResponse.getHits().getAt(1).getSortValues()[0], closeTo(GeoDistance.PLANE.calculate(2, 2, 4, 1, DistanceUnit.KILOMETERS), 0.01d));
|
||||
}
|
||||
|
||||
public void testSingeToManyAvgMedian() throws ExecutionException, InterruptedException, IOException {
|
||||
/**
|
||||
* q = (0, 0)
|
||||
*
|
||||
* d1 = (0, 1), (0, 4), (0, 10); so avg. distance is 5, median distance is 4
|
||||
* d2 = (0, 1), (0, 5), (0, 6); so avg. distance is 4, median distance is 5
|
||||
*/
|
||||
Version version = VersionUtils.randomVersionBetween(random(), Version.V_2_0_0, Version.CURRENT);
|
||||
Settings settings = Settings.settingsBuilder().put(IndexMetaData.SETTING_VERSION_CREATED, version).build();
|
||||
assertAcked(prepareCreate("index").setSettings(settings).addMapping("type", LOCATION_FIELD, "type=geo_point"));
|
||||
XContentBuilder d1Builder = jsonBuilder();
|
||||
GeoPoint[] d1Points = {new GeoPoint(0, 1), new GeoPoint(0, 4), new GeoPoint(0, 10)};
|
||||
createShuffeldJSONArray(d1Builder, d1Points);
|
||||
|
||||
XContentBuilder d2Builder = jsonBuilder();
|
||||
GeoPoint[] d2Points = {new GeoPoint(0, 1), new GeoPoint(0, 5), new GeoPoint(0, 6)};
|
||||
createShuffeldJSONArray(d2Builder, d2Points);
|
||||
|
||||
logger.info("d1: {}", d1Builder);
|
||||
logger.info("d2: {}", d2Builder);
|
||||
indexRandom(true,
|
||||
client().prepareIndex("index", "type", "d1").setSource(d1Builder),
|
||||
client().prepareIndex("index", "type", "d2").setSource(d2Builder));
|
||||
ensureYellow();
|
||||
GeoPoint q = new GeoPoint(0,0);
|
||||
|
||||
SearchResponse searchResponse = client().prepareSearch()
|
||||
.setQuery(matchAllQuery())
|
||||
.addSort(new GeoDistanceSortBuilder(LOCATION_FIELD, q).sortMode(SortMode.AVG).order(SortOrder.ASC).geoDistance(GeoDistance.PLANE).unit(DistanceUnit.KILOMETERS))
|
||||
.execute().actionGet();
|
||||
assertOrderedSearchHits(searchResponse, "d2", "d1");
|
||||
assertThat((Double)searchResponse.getHits().getAt(0).getSortValues()[0], closeTo(GeoDistance.PLANE.calculate(0, 0, 0, 4, DistanceUnit.KILOMETERS), 0.01d));
|
||||
assertThat((Double)searchResponse.getHits().getAt(1).getSortValues()[0], closeTo(GeoDistance.PLANE.calculate(0, 0, 0, 5, DistanceUnit.KILOMETERS), 0.01d));
|
||||
|
||||
searchResponse = client().prepareSearch()
|
||||
.setQuery(matchAllQuery())
|
||||
.addSort(new GeoDistanceSortBuilder(LOCATION_FIELD, q).sortMode(SortMode.MEDIAN).order(SortOrder.ASC).geoDistance(GeoDistance.PLANE).unit(DistanceUnit.KILOMETERS))
|
||||
.execute().actionGet();
|
||||
assertOrderedSearchHits(searchResponse, "d1", "d2");
|
||||
assertThat((Double)searchResponse.getHits().getAt(0).getSortValues()[0], closeTo(GeoDistance.PLANE.calculate(0, 0, 0, 4, DistanceUnit.KILOMETERS), 0.01d));
|
||||
assertThat((Double)searchResponse.getHits().getAt(1).getSortValues()[0], closeTo(GeoDistance.PLANE.calculate(0, 0, 0, 5, DistanceUnit.KILOMETERS), 0.01d));
|
||||
}
|
||||
|
||||
protected void createShuffeldJSONArray(XContentBuilder builder, GeoPoint[] pointsArray) throws IOException {
|
||||
List<GeoPoint> points = new ArrayList<>();
|
||||
points.addAll(Arrays.asList(pointsArray));
|
||||
builder.startObject();
|
||||
builder.startArray("location");
|
||||
builder.startArray(LOCATION_FIELD);
|
||||
int numPoints = points.size();
|
||||
for (int i = 0; i < numPoints; i++) {
|
||||
builder.value(points.remove(randomInt(points.size() - 1)));
|
||||
|
@ -154,7 +199,7 @@ public class GeoDistanceSortBuilderIT extends ESIntegTestCase {
|
|||
*/
|
||||
Version version = VersionUtils.randomVersionBetween(random(), Version.V_2_0_0, Version.CURRENT);
|
||||
Settings settings = Settings.settingsBuilder().put(IndexMetaData.SETTING_VERSION_CREATED, version).build();
|
||||
assertAcked(prepareCreate("index").setSettings(settings).addMapping("type", "location", "type=geo_point"));
|
||||
assertAcked(prepareCreate("index").setSettings(settings).addMapping("type", LOCATION_FIELD, "type=geo_point"));
|
||||
XContentBuilder d1Builder = jsonBuilder();
|
||||
GeoPoint[] d1Points = {new GeoPoint(2.5, 1), new GeoPoint(2.75, 2), new GeoPoint(3, 3), new GeoPoint(3.25, 4)};
|
||||
createShuffeldJSONArray(d1Builder, d1Points);
|
||||
|
@ -177,13 +222,13 @@ public class GeoDistanceSortBuilderIT extends ESIntegTestCase {
|
|||
int at = randomInt(3 - i);
|
||||
if (randomBoolean()) {
|
||||
if (geoDistanceSortBuilder == null) {
|
||||
geoDistanceSortBuilder = new GeoDistanceSortBuilder("location", qHashes.get(at));
|
||||
geoDistanceSortBuilder = new GeoDistanceSortBuilder(LOCATION_FIELD, qHashes.get(at));
|
||||
} else {
|
||||
geoDistanceSortBuilder.geohashes(qHashes.get(at));
|
||||
}
|
||||
} else {
|
||||
if (geoDistanceSortBuilder == null) {
|
||||
geoDistanceSortBuilder = new GeoDistanceSortBuilder("location", qPoints.get(at));
|
||||
geoDistanceSortBuilder = new GeoDistanceSortBuilder(LOCATION_FIELD, qPoints.get(at));
|
||||
} else {
|
||||
geoDistanceSortBuilder.points(qPoints.get(at));
|
||||
}
|
||||
|
@ -211,15 +256,15 @@ public class GeoDistanceSortBuilderIT extends ESIntegTestCase {
|
|||
}
|
||||
|
||||
public void testSinglePointGeoDistanceSort() throws ExecutionException, InterruptedException, IOException {
|
||||
assertAcked(prepareCreate("index").addMapping("type", "location", "type=geo_point"));
|
||||
assertAcked(prepareCreate("index").addMapping("type", LOCATION_FIELD, "type=geo_point"));
|
||||
indexRandom(true,
|
||||
client().prepareIndex("index", "type", "d1").setSource(jsonBuilder().startObject().startObject("location").field("lat", 1).field("lon", 1).endObject().endObject()),
|
||||
client().prepareIndex("index", "type", "d2").setSource(jsonBuilder().startObject().startObject("location").field("lat", 1).field("lon", 2).endObject().endObject()));
|
||||
client().prepareIndex("index", "type", "d1").setSource(jsonBuilder().startObject().startObject(LOCATION_FIELD).field("lat", 1).field("lon", 1).endObject().endObject()),
|
||||
client().prepareIndex("index", "type", "d2").setSource(jsonBuilder().startObject().startObject(LOCATION_FIELD).field("lat", 1).field("lon", 2).endObject().endObject()));
|
||||
ensureYellow();
|
||||
|
||||
String hashPoint = "s037ms06g7h0";
|
||||
|
||||
GeoDistanceSortBuilder geoDistanceSortBuilder = new GeoDistanceSortBuilder("location", hashPoint);
|
||||
GeoDistanceSortBuilder geoDistanceSortBuilder = new GeoDistanceSortBuilder(LOCATION_FIELD, hashPoint);
|
||||
|
||||
SearchResponse searchResponse = client().prepareSearch()
|
||||
.setQuery(matchAllQuery())
|
||||
|
@ -227,7 +272,7 @@ public class GeoDistanceSortBuilderIT extends ESIntegTestCase {
|
|||
.execute().actionGet();
|
||||
checkCorrectSortOrderForGeoSort(searchResponse);
|
||||
|
||||
geoDistanceSortBuilder = new GeoDistanceSortBuilder("location", new GeoPoint(2, 2));
|
||||
geoDistanceSortBuilder = new GeoDistanceSortBuilder(LOCATION_FIELD, new GeoPoint(2, 2));
|
||||
|
||||
searchResponse = client().prepareSearch()
|
||||
.setQuery(matchAllQuery())
|
||||
|
@ -235,7 +280,7 @@ public class GeoDistanceSortBuilderIT extends ESIntegTestCase {
|
|||
.execute().actionGet();
|
||||
checkCorrectSortOrderForGeoSort(searchResponse);
|
||||
|
||||
geoDistanceSortBuilder = new GeoDistanceSortBuilder("location", 2, 2);
|
||||
geoDistanceSortBuilder = new GeoDistanceSortBuilder(LOCATION_FIELD, 2, 2);
|
||||
|
||||
searchResponse = client().prepareSearch()
|
||||
.setQuery(matchAllQuery())
|
||||
|
@ -246,28 +291,28 @@ public class GeoDistanceSortBuilderIT extends ESIntegTestCase {
|
|||
searchResponse = client()
|
||||
.prepareSearch()
|
||||
.setSource(
|
||||
new SearchSourceBuilder().sort(SortBuilders.geoDistanceSort("location", 2.0, 2.0)
|
||||
new SearchSourceBuilder().sort(SortBuilders.geoDistanceSort(LOCATION_FIELD, 2.0, 2.0)
|
||||
.unit(DistanceUnit.KILOMETERS).geoDistance(GeoDistance.PLANE))).execute().actionGet();
|
||||
checkCorrectSortOrderForGeoSort(searchResponse);
|
||||
|
||||
searchResponse = client()
|
||||
.prepareSearch()
|
||||
.setSource(
|
||||
new SearchSourceBuilder().sort(SortBuilders.geoDistanceSort("location", "s037ms06g7h0")
|
||||
new SearchSourceBuilder().sort(SortBuilders.geoDistanceSort(LOCATION_FIELD, "s037ms06g7h0")
|
||||
.unit(DistanceUnit.KILOMETERS).geoDistance(GeoDistance.PLANE))).execute().actionGet();
|
||||
checkCorrectSortOrderForGeoSort(searchResponse);
|
||||
|
||||
searchResponse = client()
|
||||
.prepareSearch()
|
||||
.setSource(
|
||||
new SearchSourceBuilder().sort(SortBuilders.geoDistanceSort("location", 2.0, 2.0)
|
||||
new SearchSourceBuilder().sort(SortBuilders.geoDistanceSort(LOCATION_FIELD, 2.0, 2.0)
|
||||
.unit(DistanceUnit.KILOMETERS).geoDistance(GeoDistance.PLANE))).execute().actionGet();
|
||||
checkCorrectSortOrderForGeoSort(searchResponse);
|
||||
|
||||
searchResponse = client()
|
||||
.prepareSearch()
|
||||
.setSource(
|
||||
new SearchSourceBuilder().sort(SortBuilders.geoDistanceSort("location", 2.0, 2.0)
|
||||
new SearchSourceBuilder().sort(SortBuilders.geoDistanceSort(LOCATION_FIELD, 2.0, 2.0)
|
||||
.unit(DistanceUnit.KILOMETERS).geoDistance(GeoDistance.PLANE)
|
||||
.ignoreMalformed(true).coerce(true))).execute().actionGet();
|
||||
checkCorrectSortOrderForGeoSort(searchResponse);
|
||||
|
|
|
@ -53,6 +53,7 @@ public class ScriptSortBuilderTests extends AbstractSortTestCase<ScriptSortBuild
|
|||
Set<SortMode> exceptThis = new HashSet<>();
|
||||
exceptThis.add(SortMode.SUM);
|
||||
exceptThis.add(SortMode.AVG);
|
||||
exceptThis.add(SortMode.MEDIAN);
|
||||
builder.sortMode(RandomSortDataGenerator.mode(exceptThis));
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +79,7 @@ public class ScriptSortBuilderTests extends AbstractSortTestCase<ScriptSortBuild
|
|||
result = new ScriptSortBuilder(script, type.equals(ScriptSortType.NUMBER) ? ScriptSortType.STRING : ScriptSortType.NUMBER);
|
||||
}
|
||||
result.order(original.order());
|
||||
if (original.sortMode() != null) {
|
||||
if (original.sortMode() != null && result.type() == ScriptSortType.NUMBER) {
|
||||
result.sortMode(original.sortMode());
|
||||
}
|
||||
result.setNestedFilter(original.getNestedFilter());
|
||||
|
@ -95,7 +96,16 @@ public class ScriptSortBuilderTests extends AbstractSortTestCase<ScriptSortBuild
|
|||
}
|
||||
break;
|
||||
case 1:
|
||||
result.sortMode(RandomSortDataGenerator.mode(original.sortMode()));
|
||||
if (original.type() == ScriptSortType.NUMBER) {
|
||||
result.sortMode(RandomSortDataGenerator.mode(original.sortMode()));
|
||||
} else {
|
||||
// script sort type String only allows MIN and MAX, so we only switch
|
||||
if (original.sortMode() == SortMode.MIN) {
|
||||
result.sortMode(SortMode.MAX);
|
||||
} else {
|
||||
result.sortMode(SortMode.MIN);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
result.setNestedFilter(RandomSortDataGenerator.nestedFilter(original.getNestedFilter()));
|
||||
|
@ -248,4 +258,14 @@ public class ScriptSortBuilderTests extends AbstractSortTestCase<ScriptSortBuild
|
|||
exceptionRule.expectMessage("unexpected token [START_ARRAY]");
|
||||
ScriptSortBuilder.PROTOTYPE.fromXContent(context, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* script sort of type {@link ScriptSortType} does not work with {@link SortMode#AVG}, {@link SortMode#MEDIAN} or {@link SortMode#SUM}
|
||||
*/
|
||||
public void testBadSortMode() throws IOException {
|
||||
ScriptSortBuilder builder = new ScriptSortBuilder(new Script("something"), ScriptSortType.STRING);
|
||||
exceptionRule.expect(IllegalArgumentException.class);
|
||||
exceptionRule.expectMessage("script sort of type [string] doesn't support mode");
|
||||
builder.sortMode(SortMode.fromString(randomFrom(new String[]{"avg", "median", "sum"})));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue