Query Refactoring: moving validation to setters and constructors
Moving validation from validate() to constructors and setters for the following query builders: * GeoDistanceQueryBuilder * GeoDistanceRangeQueryBuilder * GeoPolygonQueryBuilder * GeoShapeQueryBuilder * GeohashCellQuery * TermsQueryBuilder Relates to #10217
This commit is contained in:
parent
cc69de5c5f
commit
03035a28a3
|
@ -114,13 +114,6 @@ public abstract class AbstractQueryBuilder<QB extends AbstractQueryBuilder> exte
|
|||
return context.indexQueryParserService().indicesQueriesRegistry().queryParsers().get(getName()).parse(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryValidationException validate() {
|
||||
// default impl does not validate, subclasses should override.
|
||||
//norelease to be possibly made abstract once all queries support validation
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the query name for the query.
|
||||
*/
|
||||
|
@ -267,27 +260,6 @@ public abstract class AbstractQueryBuilder<QB extends AbstractQueryBuilder> exte
|
|||
return queries;
|
||||
}
|
||||
|
||||
protected QueryValidationException validateInnerQueries(List<QueryBuilder> queryBuilders, QueryValidationException initialValidationException) {
|
||||
QueryValidationException validationException = initialValidationException;
|
||||
for (QueryBuilder queryBuilder : queryBuilders) {
|
||||
validationException = validateInnerQuery(queryBuilder, validationException);
|
||||
}
|
||||
return validationException;
|
||||
}
|
||||
|
||||
protected QueryValidationException validateInnerQuery(QueryBuilder queryBuilder, QueryValidationException initialValidationException) {
|
||||
QueryValidationException validationException = initialValidationException;
|
||||
if (queryBuilder != null) {
|
||||
QueryValidationException queryValidationException = queryBuilder.validate();
|
||||
if (queryValidationException != null) {
|
||||
validationException = QueryValidationException.addValidationErrors(queryValidationException.validationErrors(), validationException);
|
||||
}
|
||||
} else {
|
||||
validationException = addValidationError("inner query cannot be null", validationException);
|
||||
}
|
||||
return validationException;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
//default impl returns the same as writeable name, but we keep the distinction between the two just to make sure
|
||||
|
|
|
@ -78,13 +78,6 @@ public class EmptyQueryBuilder extends ToXContentToBytes implements QueryBuilder
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public QueryValidationException validate() {
|
||||
// nothing to validate
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ package org.elasticsearch.index.query;
|
|||
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.Numbers;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.geo.GeoDistance;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
|
@ -76,12 +75,7 @@ public class GeoDistanceQueryBuilder extends AbstractQueryBuilder<GeoDistanceQue
|
|||
/** Whether or not to accept geo points with invalid latitude or longitude */
|
||||
private boolean ignoreMalformed = DEFAULT_IGNORE_MALFORMED;
|
||||
|
||||
static final GeoDistanceQueryBuilder PROTOTYPE = new GeoDistanceQueryBuilder();
|
||||
|
||||
/** For serialization purposes only. */
|
||||
private GeoDistanceQueryBuilder() {
|
||||
this.fieldName = null;
|
||||
}
|
||||
static final GeoDistanceQueryBuilder PROTOTYPE = new GeoDistanceQueryBuilder("_na_");
|
||||
|
||||
/**
|
||||
* Construct new GeoDistanceQueryBuilder.
|
||||
|
@ -127,10 +121,7 @@ public class GeoDistanceQueryBuilder extends AbstractQueryBuilder<GeoDistanceQue
|
|||
|
||||
/** Sets the distance from the center using the default distance unit.*/
|
||||
public GeoDistanceQueryBuilder distance(String distance) {
|
||||
if (Strings.isEmpty(distance)) {
|
||||
throw new IllegalArgumentException("distance must not be null or empty");
|
||||
}
|
||||
return this.distance(distance, DistanceUnit.DEFAULT);
|
||||
return distance(distance, DistanceUnit.DEFAULT);
|
||||
}
|
||||
|
||||
/** Sets the distance from the center for this query. */
|
||||
|
@ -147,11 +138,7 @@ public class GeoDistanceQueryBuilder extends AbstractQueryBuilder<GeoDistanceQue
|
|||
|
||||
/** Sets the distance from the center for this query. */
|
||||
public GeoDistanceQueryBuilder distance(double distance, DistanceUnit unit) {
|
||||
if (unit == null) {
|
||||
throw new IllegalArgumentException("distance unit must not be null");
|
||||
}
|
||||
this.distance = DistanceUnit.DEFAULT.convert(distance, unit);
|
||||
return this;
|
||||
return distance(Double.toString(distance), unit);
|
||||
}
|
||||
|
||||
/** Returns the distance configured as radius. */
|
||||
|
@ -188,8 +175,16 @@ public class GeoDistanceQueryBuilder extends AbstractQueryBuilder<GeoDistanceQue
|
|||
* enclosing bounding box.
|
||||
**/
|
||||
public GeoDistanceQueryBuilder optimizeBbox(String optimizeBbox) {
|
||||
if (Strings.isEmpty(optimizeBbox)) {
|
||||
throw new IllegalArgumentException("optimizeBbox must not be null or empty");
|
||||
if (optimizeBbox == null) {
|
||||
throw new IllegalArgumentException("optimizeBox must not be null");
|
||||
}
|
||||
switch (optimizeBbox) {
|
||||
case "none":
|
||||
case "memory":
|
||||
case "indexed":
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("optimizeBbox must be one of [none, memory, indexed]");
|
||||
}
|
||||
this.optimizeBbox = optimizeBbox;
|
||||
return this;
|
||||
|
@ -249,9 +244,7 @@ public class GeoDistanceQueryBuilder extends AbstractQueryBuilder<GeoDistanceQue
|
|||
builder.startObject(NAME);
|
||||
builder.startArray(fieldName).value(center.lon()).value(center.lat()).endArray();
|
||||
builder.field("distance", distance);
|
||||
if (geoDistance != null) {
|
||||
builder.field("distance_type", geoDistance.name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
builder.field("distance_type", geoDistance.name().toLowerCase(Locale.ROOT));
|
||||
builder.field("optimize_bbox", optimizeBbox);
|
||||
builder.field("coerce", coerce);
|
||||
builder.field("ignore_malformed", ignoreMalformed);
|
||||
|
@ -299,29 +292,6 @@ public class GeoDistanceQueryBuilder extends AbstractQueryBuilder<GeoDistanceQue
|
|||
geoDistance.writeTo(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryValidationException validate() {
|
||||
QueryValidationException validationException = null;
|
||||
if (!ignoreMalformed) {
|
||||
if (Numbers.isValidDouble(center.getLat()) == false) {
|
||||
validationException = addValidationError("center point latitude is invalid number: " + center.getLat(), validationException);
|
||||
}
|
||||
if (Numbers.isValidDouble(center.getLon()) == false) {
|
||||
validationException = addValidationError("center point longitude is invalid number: " + center.getLon(),
|
||||
validationException);
|
||||
}
|
||||
}
|
||||
|
||||
if (Strings.isEmpty(fieldName)) {
|
||||
validationException = addValidationError("field name must be non-null and non-empty", validationException);
|
||||
}
|
||||
if (optimizeBbox != null && !(optimizeBbox.equals("none") || optimizeBbox.equals("memory") || optimizeBbox.equals("indexed"))) {
|
||||
validationException = QueryValidationException.addValidationError(NAME, "optimizeBbox must be one of [none, memory, indexed]",
|
||||
validationException);
|
||||
}
|
||||
return validationException;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param indexCreatedBeforeV2_0
|
||||
* @return
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.elasticsearch.index.query;
|
|||
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.geo.GeoDistance;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.common.geo.GeoUtils;
|
||||
|
@ -55,7 +56,7 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
|||
private boolean includeLower = DEFAULT_INCLUDE_LOWER;
|
||||
private boolean includeUpper = DEFAULT_INCLUDE_UPPER;
|
||||
|
||||
private GeoPoint point;
|
||||
private final GeoPoint point;
|
||||
|
||||
private GeoDistance geoDistance = DEFAULT_GEO_DISTANCE;
|
||||
|
||||
|
@ -67,31 +68,47 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
|||
|
||||
private boolean ignoreMalformed = DEFAULT_IGNORE_MALFORMED;
|
||||
|
||||
static final GeoDistanceRangeQueryBuilder PROTOTYPE = new GeoDistanceRangeQueryBuilder(null);
|
||||
static final GeoDistanceRangeQueryBuilder PROTOTYPE = new GeoDistanceRangeQueryBuilder("_na_", new GeoPoint());
|
||||
|
||||
public GeoDistanceRangeQueryBuilder(String fieldName) {
|
||||
public GeoDistanceRangeQueryBuilder(String fieldName, GeoPoint point) {
|
||||
if (Strings.isEmpty(fieldName)) {
|
||||
throw new IllegalArgumentException("fieldName must not be null");
|
||||
}
|
||||
if (point == null) {
|
||||
throw new IllegalArgumentException("point must not be null");
|
||||
}
|
||||
this.fieldName = fieldName;
|
||||
this.point = point;
|
||||
}
|
||||
|
||||
public GeoDistanceRangeQueryBuilder(String fieldName, double lat, double lon) {
|
||||
this(fieldName, new GeoPoint(lat, lon));
|
||||
}
|
||||
|
||||
public GeoDistanceRangeQueryBuilder(String fieldName, String geohash) {
|
||||
this(fieldName, geohash == null ? null : new GeoPoint().resetFromGeoHash(geohash));
|
||||
}
|
||||
|
||||
public String fieldName() {
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
public GeoDistanceRangeQueryBuilder point(double lat, double lon) {
|
||||
this.point = new GeoPoint(lat, lon);
|
||||
return this;
|
||||
}
|
||||
|
||||
public GeoDistanceRangeQueryBuilder point(GeoPoint point) {
|
||||
this.point = point;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GeoPoint point() {
|
||||
return point;
|
||||
}
|
||||
|
||||
public GeoDistanceRangeQueryBuilder from(Object from) {
|
||||
public GeoDistanceRangeQueryBuilder from(String from) {
|
||||
if (from == null) {
|
||||
throw new IllegalArgumentException("[from] must not be null");
|
||||
}
|
||||
this.from = from;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GeoDistanceRangeQueryBuilder from(Number from) {
|
||||
if (from == null) {
|
||||
throw new IllegalArgumentException("[from] must not be null");
|
||||
}
|
||||
this.from = from;
|
||||
return this;
|
||||
}
|
||||
|
@ -100,7 +117,18 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
|||
return from;
|
||||
}
|
||||
|
||||
public GeoDistanceRangeQueryBuilder to(Object to) {
|
||||
public GeoDistanceRangeQueryBuilder to(String to) {
|
||||
if (to == null) {
|
||||
throw new IllegalArgumentException("[to] must not be null");
|
||||
}
|
||||
this.to = to;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GeoDistanceRangeQueryBuilder to(Number to) {
|
||||
if (to == null) {
|
||||
throw new IllegalArgumentException("[to] must not be null");
|
||||
}
|
||||
this.to = to;
|
||||
return this;
|
||||
}
|
||||
|
@ -109,30 +137,6 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
|||
return to;
|
||||
}
|
||||
|
||||
public GeoDistanceRangeQueryBuilder gt(Object from) {
|
||||
this.from = from;
|
||||
this.includeLower = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GeoDistanceRangeQueryBuilder gte(Object from) {
|
||||
this.from = from;
|
||||
this.includeLower = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GeoDistanceRangeQueryBuilder lt(Object to) {
|
||||
this.to = to;
|
||||
this.includeUpper = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GeoDistanceRangeQueryBuilder lte(Object to) {
|
||||
this.to = to;
|
||||
this.includeUpper = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GeoDistanceRangeQueryBuilder includeLower(boolean includeLower) {
|
||||
this.includeLower = includeLower;
|
||||
return this;
|
||||
|
@ -151,12 +155,10 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
|||
return includeUpper;
|
||||
}
|
||||
|
||||
public GeoDistanceRangeQueryBuilder geohash(String geohash) {
|
||||
this.point = new GeoPoint().resetFromGeoHash(geohash);
|
||||
return this;
|
||||
}
|
||||
|
||||
public GeoDistanceRangeQueryBuilder geoDistance(GeoDistance geoDistance) {
|
||||
if (geoDistance == null) {
|
||||
throw new IllegalArgumentException("geoDistance calculation mode must not be null");
|
||||
}
|
||||
this.geoDistance = geoDistance;
|
||||
return this;
|
||||
}
|
||||
|
@ -166,6 +168,9 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
|||
}
|
||||
|
||||
public GeoDistanceRangeQueryBuilder unit(DistanceUnit unit) {
|
||||
if (unit == null) {
|
||||
throw new IllegalArgumentException("distance unit must not be null");
|
||||
}
|
||||
this.unit = unit;
|
||||
return this;
|
||||
}
|
||||
|
@ -175,6 +180,17 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
|||
}
|
||||
|
||||
public GeoDistanceRangeQueryBuilder optimizeBbox(String optimizeBbox) {
|
||||
if (optimizeBbox == null) {
|
||||
throw new IllegalArgumentException("optimizeBox must not be null");
|
||||
}
|
||||
switch (optimizeBbox) {
|
||||
case "none":
|
||||
case "memory":
|
||||
case "indexed":
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("optimizeBbox must be one of [none, memory, indexed]");
|
||||
}
|
||||
this.optimizeBbox = optimizeBbox;
|
||||
return this;
|
||||
}
|
||||
|
@ -206,32 +222,6 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
|||
return ignoreMalformed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryValidationException validate() {
|
||||
QueryValidationException errors = null;
|
||||
if (fieldName == null) {
|
||||
errors = QueryValidationException.addValidationError(NAME, "fieldName must not be null", errors);
|
||||
}
|
||||
if (point == null) {
|
||||
errors = QueryValidationException.addValidationError(NAME, "point must not be null", errors);
|
||||
}
|
||||
if (from == null && to == null) {
|
||||
errors = QueryValidationException.addValidationError(NAME, "Must define at least one parameter from [from, to]", errors);
|
||||
}
|
||||
if (from != null && !(from instanceof Number || from instanceof String)) {
|
||||
errors = QueryValidationException.addValidationError(NAME, "from must either be a number or a string. Found ["
|
||||
+ from.getClass().getName() + "]", errors);
|
||||
}
|
||||
if (to != null && !(to instanceof Number || to instanceof String)) {
|
||||
errors = QueryValidationException.addValidationError(NAME, "to must either be a number or a string. Found ["
|
||||
+ to.getClass().getName() + "]", errors);
|
||||
}
|
||||
if (optimizeBbox != null && !(optimizeBbox.equals("none") || optimizeBbox.equals("memory") || optimizeBbox.equals("indexed"))) {
|
||||
errors = QueryValidationException.addValidationError(NAME, "optimizeBbox must be one of [none, memory, indexed]", errors);
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Query doToQuery(QueryShardContext context) throws IOException {
|
||||
|
||||
|
@ -292,15 +282,9 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
|||
builder.field(GeoDistanceRangeQueryParser.TO_FIELD.getPreferredName(), to);
|
||||
builder.field(GeoDistanceRangeQueryParser.INCLUDE_LOWER_FIELD.getPreferredName(), includeLower);
|
||||
builder.field(GeoDistanceRangeQueryParser.INCLUDE_UPPER_FIELD.getPreferredName(), includeUpper);
|
||||
if (unit != null) {
|
||||
builder.field(GeoDistanceRangeQueryParser.UNIT_FIELD.getPreferredName(), unit);
|
||||
}
|
||||
if (geoDistance != null) {
|
||||
builder.field(GeoDistanceRangeQueryParser.DISTANCE_TYPE_FIELD.getPreferredName(), geoDistance.name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
if (optimizeBbox != null) {
|
||||
builder.field(GeoDistanceRangeQueryParser.OPTIMIZE_BBOX_FIELD.getPreferredName(), optimizeBbox);
|
||||
}
|
||||
builder.field(GeoDistanceRangeQueryParser.UNIT_FIELD.getPreferredName(), unit);
|
||||
builder.field(GeoDistanceRangeQueryParser.DISTANCE_TYPE_FIELD.getPreferredName(), geoDistance.name().toLowerCase(Locale.ROOT));
|
||||
builder.field(GeoDistanceRangeQueryParser.OPTIMIZE_BBOX_FIELD.getPreferredName(), optimizeBbox);
|
||||
builder.field(GeoDistanceRangeQueryParser.COERCE_FIELD.getPreferredName(), coerce);
|
||||
builder.field(GeoDistanceRangeQueryParser.IGNORE_MALFORMED_FIELD.getPreferredName(), ignoreMalformed);
|
||||
printBoostAndQueryName(builder);
|
||||
|
@ -309,21 +293,14 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
|||
|
||||
@Override
|
||||
protected GeoDistanceRangeQueryBuilder doReadFrom(StreamInput in) throws IOException {
|
||||
GeoDistanceRangeQueryBuilder queryBuilder = new GeoDistanceRangeQueryBuilder(in.readString());
|
||||
queryBuilder.point = GeoPoint.readGeoPointFrom(in);
|
||||
GeoDistanceRangeQueryBuilder queryBuilder = new GeoDistanceRangeQueryBuilder(in.readString(), GeoPoint.readGeoPointFrom(in));
|
||||
queryBuilder.from = in.readGenericValue();
|
||||
queryBuilder.to = in.readGenericValue();
|
||||
queryBuilder.includeLower = in.readBoolean();
|
||||
queryBuilder.includeUpper = in.readBoolean();
|
||||
String unit = in.readOptionalString();
|
||||
if (unit != null) {
|
||||
queryBuilder.unit = DistanceUnit.valueOf(unit);
|
||||
}
|
||||
String geoDistance = in.readOptionalString();
|
||||
if (geoDistance != null) {
|
||||
queryBuilder.geoDistance = GeoDistance.fromString(geoDistance);
|
||||
}
|
||||
queryBuilder.optimizeBbox = in.readOptionalString();
|
||||
queryBuilder.unit = DistanceUnit.valueOf(in.readString());
|
||||
queryBuilder.geoDistance = GeoDistance.readGeoDistanceFrom(in);
|
||||
queryBuilder.optimizeBbox = in.readString();
|
||||
queryBuilder.coerce = in.readBoolean();
|
||||
queryBuilder.ignoreMalformed = in.readBoolean();
|
||||
return queryBuilder;
|
||||
|
@ -337,9 +314,9 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
|||
out.writeGenericValue(to);
|
||||
out.writeBoolean(includeLower);
|
||||
out.writeBoolean(includeUpper);
|
||||
out.writeOptionalString(unit.name());
|
||||
out.writeOptionalString(geoDistance.name());
|
||||
out.writeOptionalString(optimizeBbox);
|
||||
out.writeString(unit.name());
|
||||
geoDistance.writeTo(out);;
|
||||
out.writeString(optimizeBbox);
|
||||
out.writeBoolean(coerce);
|
||||
out.writeBoolean(ignoreMalformed);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ import org.elasticsearch.common.ParseField;
|
|||
import org.elasticsearch.common.geo.GeoDistance;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.common.geo.GeoUtils;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.unit.DistanceUnit;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
||||
|
@ -76,7 +75,6 @@ public class GeoDistanceRangeQueryParser extends BaseQueryParser<GeoDistanceRang
|
|||
String queryName = null;
|
||||
String currentFieldName = null;
|
||||
GeoPoint point = null;
|
||||
String geohash = null;
|
||||
String fieldName = null;
|
||||
Object vFrom = null;
|
||||
Object vTo = null;
|
||||
|
@ -173,7 +171,7 @@ public class GeoDistanceRangeQueryParser extends BaseQueryParser<GeoDistanceRang
|
|||
point.resetLon(parser.doubleValue());
|
||||
fieldName = currentFieldName.substring(0, currentFieldName.length() - GeoPointFieldMapper.Names.LON_SUFFIX.length());
|
||||
} else if (currentFieldName.endsWith(GeoPointFieldMapper.Names.GEOHASH_SUFFIX)) {
|
||||
geohash = parser.text();
|
||||
point = GeoPoint.fromGeohash(parser.text());
|
||||
fieldName = currentFieldName.substring(0, currentFieldName.length() - GeoPointFieldMapper.Names.GEOHASH_SUFFIX.length());
|
||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, NAME_FIELD)) {
|
||||
queryName = parser.text();
|
||||
|
@ -195,8 +193,7 @@ public class GeoDistanceRangeQueryParser extends BaseQueryParser<GeoDistanceRang
|
|||
}
|
||||
}
|
||||
|
||||
GeoDistanceRangeQueryBuilder queryBuilder = new GeoDistanceRangeQueryBuilder(fieldName);
|
||||
|
||||
GeoDistanceRangeQueryBuilder queryBuilder = new GeoDistanceRangeQueryBuilder(fieldName, point);
|
||||
if (boost != null) {
|
||||
queryBuilder.boost(boost);
|
||||
}
|
||||
|
@ -205,20 +202,12 @@ public class GeoDistanceRangeQueryParser extends BaseQueryParser<GeoDistanceRang
|
|||
queryBuilder.queryName(queryName);
|
||||
}
|
||||
|
||||
if (point != null) {
|
||||
queryBuilder.point(point.lat(), point.lon());
|
||||
}
|
||||
|
||||
if (geohash != null) {
|
||||
queryBuilder.geohash(geohash);
|
||||
}
|
||||
|
||||
if (vFrom != null) {
|
||||
queryBuilder.from(vFrom);
|
||||
queryBuilder.from(vFrom.toString());
|
||||
}
|
||||
|
||||
if (vTo != null) {
|
||||
queryBuilder.to(vTo);
|
||||
queryBuilder.to(vTo.toString());
|
||||
}
|
||||
|
||||
if (includeUpper != null) {
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.elasticsearch.index.query;
|
|||
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.common.geo.GeoUtils;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
|
@ -33,6 +34,7 @@ import org.elasticsearch.index.search.geo.GeoPolygonQuery;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
|
@ -40,7 +42,10 @@ public class GeoPolygonQueryBuilder extends AbstractQueryBuilder<GeoPolygonQuery
|
|||
|
||||
public static final String NAME = "geo_polygon";
|
||||
|
||||
static final GeoPolygonQueryBuilder PROTOTYPE = new GeoPolygonQueryBuilder("");
|
||||
private static final List<GeoPoint> PROTO_SHAPE = Arrays.asList(new GeoPoint[] { new GeoPoint(1.0, 1.0), new GeoPoint(1.0, 2.0),
|
||||
new GeoPoint(2.0, 1.0) });
|
||||
|
||||
static final GeoPolygonQueryBuilder PROTOTYPE = new GeoPolygonQueryBuilder("field", PROTO_SHAPE);
|
||||
|
||||
private final String fieldName;
|
||||
|
||||
|
@ -50,16 +55,23 @@ public class GeoPolygonQueryBuilder extends AbstractQueryBuilder<GeoPolygonQuery
|
|||
|
||||
private boolean ignoreMalformed = false;
|
||||
|
||||
public GeoPolygonQueryBuilder(String fieldName) {
|
||||
this(fieldName, new ArrayList<>());
|
||||
}
|
||||
|
||||
public GeoPolygonQueryBuilder(String fieldName, List<GeoPoint> points) {
|
||||
if (fieldName == null) {
|
||||
if (Strings.isEmpty(fieldName)) {
|
||||
throw new IllegalArgumentException("fieldName must not be null");
|
||||
}
|
||||
if (points == null) {
|
||||
throw new IllegalArgumentException("polygon must not be null");
|
||||
if (points == null || points.isEmpty()) {
|
||||
throw new IllegalArgumentException("polygon must not be null or empty");
|
||||
} else {
|
||||
GeoPoint start = points.get(0);
|
||||
if (start.equals(points.get(points.size() - 1))) {
|
||||
if (points.size() < 4) {
|
||||
throw new IllegalArgumentException("too few points defined for geo_polygon query");
|
||||
}
|
||||
} else {
|
||||
if (points.size() < 3) {
|
||||
throw new IllegalArgumentException("too few points defined for geo_polygon query");
|
||||
}
|
||||
}
|
||||
}
|
||||
this.fieldName = fieldName;
|
||||
this.shell = points;
|
||||
|
@ -69,26 +81,6 @@ public class GeoPolygonQueryBuilder extends AbstractQueryBuilder<GeoPolygonQuery
|
|||
return fieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a point with lat and lon
|
||||
*
|
||||
* @param lat The latitude
|
||||
* @param lon The longitude
|
||||
* @return the current builder
|
||||
*/
|
||||
public GeoPolygonQueryBuilder addPoint(double lat, double lon) {
|
||||
return addPoint(new GeoPoint(lat, lon));
|
||||
}
|
||||
|
||||
public GeoPolygonQueryBuilder addPoint(String geohash) {
|
||||
return addPoint(GeoPoint.fromGeohash(geohash));
|
||||
}
|
||||
|
||||
public GeoPolygonQueryBuilder addPoint(GeoPoint point) {
|
||||
shell.add(point);
|
||||
return this;
|
||||
}
|
||||
|
||||
public List<GeoPoint> points() {
|
||||
return shell;
|
||||
}
|
||||
|
@ -116,29 +108,6 @@ public class GeoPolygonQueryBuilder extends AbstractQueryBuilder<GeoPolygonQuery
|
|||
return ignoreMalformed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryValidationException validate() {
|
||||
QueryValidationException errors = null;
|
||||
if (fieldName == null) {
|
||||
errors = QueryValidationException.addValidationError(NAME, "field must not be null", errors);
|
||||
}
|
||||
if (shell.isEmpty()) {
|
||||
errors = QueryValidationException.addValidationError(NAME, "no points defined for geo_polygon query", errors);
|
||||
} else {
|
||||
GeoPoint start = shell.get(0);
|
||||
if (start.equals(shell.get(shell.size() - 1))) {
|
||||
if (shell.size() < 4) {
|
||||
errors = QueryValidationException.addValidationError(NAME, "too few points defined for geo_polygon query", errors);
|
||||
}
|
||||
} else {
|
||||
if (shell.size() < 3) {
|
||||
errors = QueryValidationException.addValidationError(NAME, "too few points defined for geo_polygon query", errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Query doToQuery(QueryShardContext context) throws IOException {
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
|
|||
public static final String DEFAULT_SHAPE_FIELD_NAME = "shape";
|
||||
public static final ShapeRelation DEFAULT_SHAPE_RELATION = ShapeRelation.INTERSECTS;
|
||||
|
||||
static final GeoShapeQueryBuilder PROTOTYPE = new GeoShapeQueryBuilder("", new BytesArray(new byte[0]));
|
||||
static final GeoShapeQueryBuilder PROTOTYPE = new GeoShapeQueryBuilder("field", new BytesArray(new byte[1]));
|
||||
|
||||
private final String fieldName;
|
||||
|
||||
|
@ -114,11 +114,17 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
|
|||
}
|
||||
|
||||
private GeoShapeQueryBuilder(String fieldName, ShapeBuilder shape, String indexedShapeId, String indexedShapeType) throws IOException {
|
||||
this(fieldName, new BytesArray(new byte[0]), indexedShapeId, indexedShapeType);
|
||||
this(fieldName, new BytesArray(new byte[1]), indexedShapeId, indexedShapeType);
|
||||
if (shape != null) {
|
||||
XContentBuilder builder = XContentFactory.jsonBuilder();
|
||||
shape.toXContent(builder, EMPTY_PARAMS);
|
||||
this.shapeBytes = builder.bytes();
|
||||
BytesReference bytes = builder.bytes();
|
||||
if (bytes.length() == 0) {
|
||||
throw new IllegalArgumentException("shape must not be empty");
|
||||
}
|
||||
this.shapeBytes = bytes;
|
||||
} else {
|
||||
throw new IllegalArgumentException("shape must not be null");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,7 +132,7 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
|
|||
if (fieldName == null) {
|
||||
throw new IllegalArgumentException("fieldName is required");
|
||||
}
|
||||
if (shapeBytes == null && indexedShapeId == null) {
|
||||
if ((shapeBytes == null || shapeBytes.length() == 0) && indexedShapeId == null) {
|
||||
throw new IllegalArgumentException("either shapeBytes or indexedShapeId and indexedShapeType are required");
|
||||
}
|
||||
if (indexedShapeId != null && indexedShapeType == null) {
|
||||
|
@ -232,6 +238,9 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
|
|||
* @return this
|
||||
*/
|
||||
public GeoShapeQueryBuilder relation(ShapeRelation relation) {
|
||||
if (relation == null) {
|
||||
throw new IllegalArgumentException("No Shape Relation defined");
|
||||
}
|
||||
this.relation = relation;
|
||||
return this;
|
||||
}
|
||||
|
@ -243,21 +252,9 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
|
|||
return relation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryValidationException validate() {
|
||||
QueryValidationException errors = null;
|
||||
if (fieldName == null) {
|
||||
errors = QueryValidationException.addValidationError(NAME, "No field defined", errors);
|
||||
}
|
||||
if ((shapeBytes == null || shapeBytes.length() == 0) && indexedShapeId == null) {
|
||||
errors = QueryValidationException.addValidationError(NAME, "No Shape defined", errors);
|
||||
}
|
||||
if (relation == null) {
|
||||
errors = QueryValidationException.addValidationError(NAME, "No Shape Relation defined", errors);
|
||||
}
|
||||
if (indexedShapeId != null && indexedShapeType == null) {
|
||||
errors = QueryValidationException.addValidationError(NAME, "Type for indexed shape not provided", errors);
|
||||
}
|
||||
// TODO did we validate this before the refactoring and can we do this in setters at all?
|
||||
if (strategy != null && strategy == SpatialStrategy.TERM && relation != ShapeRelation.INTERSECTS) {
|
||||
errors = QueryValidationException.addValidationError(NAME,
|
||||
"strategy [" + strategy.getStrategyName() + "] only supports relation ["
|
||||
|
|
|
@ -102,15 +102,11 @@ public class GeohashCellQuery {
|
|||
private String geohash;
|
||||
private Integer levels = null;
|
||||
private boolean neighbors = DEFAULT_NEIGHBORS;
|
||||
private static final Builder PROTOTYPE = new Builder(null);
|
||||
private static final Builder PROTOTYPE = new Builder("field", new GeoPoint());
|
||||
|
||||
|
||||
public Builder(String field) {
|
||||
this(field, null, false);
|
||||
}
|
||||
|
||||
public Builder(String field, GeoPoint point) {
|
||||
this(field, point.geohash(), false);
|
||||
this(field, point == null ? null : point.geohash(), false);
|
||||
}
|
||||
|
||||
public Builder(String field, String geohash) {
|
||||
|
@ -118,7 +114,12 @@ public class GeohashCellQuery {
|
|||
}
|
||||
|
||||
public Builder(String field, String geohash, boolean neighbors) {
|
||||
super();
|
||||
if (Strings.isEmpty(field)) {
|
||||
throw new IllegalArgumentException("fieldName must not be null");
|
||||
}
|
||||
if (Strings.isEmpty(geohash)) {
|
||||
throw new IllegalArgumentException("geohash or point must be defined");
|
||||
}
|
||||
this.fieldName = field;
|
||||
this.geohash = geohash;
|
||||
this.neighbors = neighbors;
|
||||
|
@ -144,6 +145,9 @@ public class GeohashCellQuery {
|
|||
}
|
||||
|
||||
public Builder precision(int levels) {
|
||||
if (levels <= 0) {
|
||||
throw new IllegalArgumentException("precision must be greater than 0. Found [" + levels + "]");
|
||||
}
|
||||
this.levels = levels;
|
||||
return this;
|
||||
}
|
||||
|
@ -175,22 +179,6 @@ public class GeohashCellQuery {
|
|||
return fieldName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryValidationException validate() {
|
||||
QueryValidationException errors = null;
|
||||
if (fieldName == null) {
|
||||
errors = QueryValidationException.addValidationError(NAME, "fieldName must not be null", errors);
|
||||
}
|
||||
if (geohash == null) {
|
||||
errors = QueryValidationException.addValidationError(NAME, "geohash or point must be defined", errors);
|
||||
}
|
||||
if (levels != null && levels <= 0) {
|
||||
errors = QueryValidationException.addValidationError(NAME, "precision must be greater than 0. Found [" + levels + "]",
|
||||
errors);
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Query doToQuery(QueryShardContext context) throws IOException {
|
||||
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
||||
|
@ -348,8 +336,7 @@ public class GeohashCellQuery {
|
|||
throw new ElasticsearchParseException("failed to parse [{}] query. unexpected token [{}]", NAME, token);
|
||||
}
|
||||
}
|
||||
Builder builder = new Builder(fieldName);
|
||||
builder.geohash(geohash);
|
||||
Builder builder = new Builder(fieldName, geohash);
|
||||
if (levels != null) {
|
||||
builder.precision(levels);
|
||||
}
|
||||
|
|
|
@ -943,7 +943,6 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryValidationException validate() {
|
||||
QueryValidationException validationException = null;
|
||||
if (likeTexts.isEmpty() && likeItems.isEmpty()) {
|
||||
|
|
|
@ -30,13 +30,6 @@ import java.io.IOException;
|
|||
|
||||
public interface QueryBuilder<QB extends QueryBuilder> extends NamedWriteable<QB>, ToXContent {
|
||||
|
||||
/**
|
||||
* Validate the query.
|
||||
* @return a {@link QueryValidationException} containing error messages, {@code null} if query is valid.
|
||||
* e.g. if fields that are needed to create the lucene query are missing.
|
||||
*/
|
||||
QueryValidationException validate();
|
||||
|
||||
/**
|
||||
* Converts this QueryBuilder to a lucene {@link Query}.
|
||||
* Returns <tt>null</tt> if this query should be ignored in the context of
|
||||
|
|
|
@ -27,12 +27,14 @@ import org.elasticsearch.common.geo.builders.ShapeBuilder;
|
|||
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
|
||||
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilder;
|
||||
import org.elasticsearch.index.search.MatchQuery;
|
||||
import org.elasticsearch.indices.cache.query.terms.TermsLookup;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.script.Template;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
|
@ -579,8 +581,8 @@ public abstract class QueryBuilders {
|
|||
/**
|
||||
* A terms query that can extract the terms from another doc in an index.
|
||||
*/
|
||||
public static TermsQueryBuilder termsLookupQuery(String name) {
|
||||
return new TermsQueryBuilder(name);
|
||||
public static TermsQueryBuilder termsLookupQuery(String name, TermsLookup termsLookup) {
|
||||
return new TermsQueryBuilder(name, termsLookup);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -606,9 +608,31 @@ public abstract class QueryBuilders {
|
|||
* A filter to filter based on a specific range from a specific geo location / point.
|
||||
*
|
||||
* @param name The location field name.
|
||||
* @param point The point
|
||||
*/
|
||||
public static GeoDistanceRangeQueryBuilder geoDistanceRangeQuery(String name) {
|
||||
return new GeoDistanceRangeQueryBuilder(name);
|
||||
public static GeoDistanceRangeQueryBuilder geoDistanceRangeQuery(String name, GeoPoint point) {
|
||||
return new GeoDistanceRangeQueryBuilder(name, point);
|
||||
}
|
||||
|
||||
/**
|
||||
* A filter to filter based on a specific range from a specific geo location / point.
|
||||
*
|
||||
* @param name The location field name.
|
||||
* @param point The point as geohash
|
||||
*/
|
||||
public static GeoDistanceRangeQueryBuilder geoDistanceRangeQuery(String name, String geohash) {
|
||||
return new GeoDistanceRangeQueryBuilder(name, geohash);
|
||||
}
|
||||
|
||||
/**
|
||||
* A filter to filter based on a specific range from a specific geo location / point.
|
||||
*
|
||||
* @param name The location field name.
|
||||
* @param lat The points latitude
|
||||
* @param lon The points longitude
|
||||
*/
|
||||
public static GeoDistanceRangeQueryBuilder geoDistanceRangeQuery(String name, double lat, double lon) {
|
||||
return new GeoDistanceRangeQueryBuilder(name, lat, lon);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -620,17 +644,6 @@ public abstract class QueryBuilders {
|
|||
return new GeoBoundingBoxQueryBuilder(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* A filter based on a bounding box defined by geohash. The field this filter is applied to
|
||||
* must have <code>{"type":"geo_point", "geohash":true}</code>
|
||||
* to work.
|
||||
*
|
||||
* @param name The geo point field name.
|
||||
*/
|
||||
public static GeohashCellQuery.Builder geoHashCellQuery(String name) {
|
||||
return new GeohashCellQuery.Builder(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* A filter based on a bounding box defined by geohash. The field this filter is applied to
|
||||
* must have <code>{"type":"geo_point", "geohash":true}</code>
|
||||
|
@ -673,8 +686,8 @@ public abstract class QueryBuilders {
|
|||
*
|
||||
* @param name The location field name.
|
||||
*/
|
||||
public static GeoPolygonQueryBuilder geoPolygonQuery(String name) {
|
||||
return new GeoPolygonQueryBuilder(name);
|
||||
public static GeoPolygonQueryBuilder geoPolygonQuery(String name, List<GeoPoint> points) {
|
||||
return new GeoPolygonQueryBuilder(name, points);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.apache.lucene.util.BytesRef;
|
|||
import org.elasticsearch.action.get.GetRequest;
|
||||
import org.elasticsearch.action.get.GetResponse;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.lucene.BytesRefs;
|
||||
|
@ -42,6 +43,7 @@ import org.elasticsearch.search.internal.SearchContext;
|
|||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* A filter for a field based on several terms matching on any of them.
|
||||
|
@ -50,7 +52,7 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
|
|||
|
||||
public static final String NAME = "terms";
|
||||
|
||||
static final TermsQueryBuilder PROTOTYPE = new TermsQueryBuilder("");
|
||||
static final TermsQueryBuilder PROTOTYPE = new TermsQueryBuilder("field", "value");
|
||||
|
||||
public static final boolean DEFAULT_DISABLE_COORD = false;
|
||||
|
||||
|
@ -60,13 +62,26 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
|
|||
private String minimumShouldMatch;
|
||||
@Deprecated
|
||||
private boolean disableCoord = DEFAULT_DISABLE_COORD;
|
||||
private TermsLookup termsLookup;
|
||||
private final TermsLookup termsLookup;
|
||||
|
||||
public TermsQueryBuilder(String fieldName, TermsLookup termsLookup) {
|
||||
this(fieldName, null, null, DEFAULT_DISABLE_COORD, termsLookup);
|
||||
}
|
||||
|
||||
/**
|
||||
* constructor used internally for serialization of both value / termslookup variants
|
||||
*/
|
||||
TermsQueryBuilder(String fieldName, List<Object> values, String minimumShouldMatch, boolean disableCoord, TermsLookup termsLookup) {
|
||||
this.fieldName = fieldName;
|
||||
if (values == null && termsLookup == null) {
|
||||
throw new IllegalArgumentException("No value specified for terms query");
|
||||
if (Strings.isEmpty(fieldName)) {
|
||||
throw new IllegalArgumentException("field name cannot be null.");
|
||||
}
|
||||
if (values == null && termsLookup == null) {
|
||||
throw new IllegalArgumentException("No value or termsLookup specified for terms query");
|
||||
}
|
||||
if (values != null && termsLookup != null) {
|
||||
throw new IllegalArgumentException("Both values and termsLookup specified for terms query");
|
||||
}
|
||||
this.fieldName = fieldName;
|
||||
this.values = values;
|
||||
this.disableCoord = disableCoord;
|
||||
this.minimumShouldMatch = minimumShouldMatch;
|
||||
|
@ -80,7 +95,7 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
|
|||
* @param values The terms
|
||||
*/
|
||||
public TermsQueryBuilder(String fieldName, String... values) {
|
||||
this(fieldName, values != null ? Arrays.asList(values) : (Iterable<?>) null);
|
||||
this(fieldName, values != null ? Arrays.asList(values) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -100,14 +115,7 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
|
|||
* @param values The terms
|
||||
*/
|
||||
public TermsQueryBuilder(String fieldName, long... values) {
|
||||
if (values == null) {
|
||||
throw new IllegalArgumentException("No value specified for terms query");
|
||||
}
|
||||
this.fieldName = fieldName;
|
||||
this.values = new ArrayList<>(values.length);
|
||||
for (long longValue : values) {
|
||||
this.values.add(longValue);
|
||||
}
|
||||
this(fieldName, values != null ? Arrays.stream(values).mapToObj(s -> s).collect(Collectors.toList()) : (Iterable<?>) null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -117,14 +125,8 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
|
|||
* @param values The terms
|
||||
*/
|
||||
public TermsQueryBuilder(String fieldName, float... values) {
|
||||
if (values == null) {
|
||||
throw new IllegalArgumentException("No value specified for terms query");
|
||||
}
|
||||
this.fieldName = fieldName;
|
||||
this.values = new ArrayList<>(values.length);
|
||||
for (float floatValue : values) {
|
||||
this.values.add(floatValue);
|
||||
}
|
||||
this(fieldName, values != null ? IntStream.range(0, values.length)
|
||||
.mapToObj(i -> values[i]).collect(Collectors.toList()) : (Iterable<?>) null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -147,16 +149,6 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
|
|||
this(fieldName, values != null ? Arrays.asList(values) : (Iterable<?>) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used for terms query lookup.
|
||||
*
|
||||
* @param fieldName The field name
|
||||
*/
|
||||
public TermsQueryBuilder(String fieldName) {
|
||||
this.fieldName = fieldName;
|
||||
this.values = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A filter for a field based on several terms matching on any of them.
|
||||
*
|
||||
|
@ -164,11 +156,15 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
|
|||
* @param values The terms
|
||||
*/
|
||||
public TermsQueryBuilder(String fieldName, Iterable<?> values) {
|
||||
if (Strings.isEmpty(fieldName)) {
|
||||
throw new IllegalArgumentException("field name cannot be null.");
|
||||
}
|
||||
if (values == null) {
|
||||
throw new IllegalArgumentException("No value specified for terms query");
|
||||
}
|
||||
this.fieldName = fieldName;
|
||||
this.values = convertToBytesRefListIfStringList(values);
|
||||
this.termsLookup = null;
|
||||
}
|
||||
|
||||
public String fieldName() {
|
||||
|
@ -207,89 +203,10 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
|
|||
return this.disableCoord;
|
||||
}
|
||||
|
||||
private boolean isTermsLookupQuery() {
|
||||
return this.termsLookup != null;
|
||||
}
|
||||
|
||||
public TermsQueryBuilder termsLookup(TermsLookup termsLookup) {
|
||||
this.termsLookup = termsLookup;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TermsLookup termsLookup() {
|
||||
return this.termsLookup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the index name to lookup the terms from.
|
||||
*/
|
||||
public TermsQueryBuilder lookupIndex(String lookupIndex) {
|
||||
if (lookupIndex == null) {
|
||||
throw new IllegalArgumentException("Lookup index cannot be set to null");
|
||||
}
|
||||
if (this.termsLookup == null) {
|
||||
this.termsLookup = new TermsLookup();
|
||||
}
|
||||
this.termsLookup.index(lookupIndex);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type name to lookup the terms from.
|
||||
*/
|
||||
public TermsQueryBuilder lookupType(String lookupType) {
|
||||
if (lookupType == null) {
|
||||
throw new IllegalArgumentException("Lookup type cannot be set to null");
|
||||
}
|
||||
if (this.termsLookup == null) {
|
||||
this.termsLookup = new TermsLookup();
|
||||
}
|
||||
this.termsLookup.type(lookupType);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the document id to lookup the terms from.
|
||||
*/
|
||||
public TermsQueryBuilder lookupId(String lookupId) {
|
||||
if (lookupId == null) {
|
||||
throw new IllegalArgumentException("Lookup id cannot be set to null");
|
||||
}
|
||||
if (this.termsLookup == null) {
|
||||
this.termsLookup = new TermsLookup();
|
||||
}
|
||||
this.termsLookup.id(lookupId);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the path name to lookup the terms from.
|
||||
*/
|
||||
public TermsQueryBuilder lookupPath(String lookupPath) {
|
||||
if (lookupPath == null) {
|
||||
throw new IllegalArgumentException("Lookup path cannot be set to null");
|
||||
}
|
||||
if (this.termsLookup == null) {
|
||||
this.termsLookup = new TermsLookup();
|
||||
}
|
||||
this.termsLookup.path(lookupPath);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the routing to lookup the terms from.
|
||||
*/
|
||||
public TermsQueryBuilder lookupRouting(String lookupRouting) {
|
||||
if (lookupRouting == null) {
|
||||
throw new IllegalArgumentException("Lookup routing cannot be set to null");
|
||||
}
|
||||
if (this.termsLookup == null) {
|
||||
this.termsLookup = new TermsLookup();
|
||||
}
|
||||
this.termsLookup.routing(lookupRouting);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #convertToBytesRefIfString} but on Iterable.
|
||||
* @param objs the Iterable of input object
|
||||
|
@ -325,7 +242,7 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
|
|||
@Override
|
||||
public void doXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(NAME);
|
||||
if (isTermsLookupQuery()) {
|
||||
if (this.termsLookup != null) {
|
||||
builder.startObject(fieldName);
|
||||
termsLookup.toXContent(builder, params);
|
||||
builder.endObject();
|
||||
|
@ -350,7 +267,7 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
|
|||
@Override
|
||||
protected Query doToQuery(QueryShardContext context) throws IOException {
|
||||
List<Object> terms;
|
||||
if (isTermsLookupQuery()) {
|
||||
if (this.termsLookup != null) {
|
||||
if (termsLookup.index() == null) {
|
||||
termsLookup.index(context.index().name());
|
||||
}
|
||||
|
@ -413,24 +330,6 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
|
|||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryValidationException validate() {
|
||||
QueryValidationException validationException = null;
|
||||
if (this.fieldName == null) {
|
||||
validationException = addValidationError("field name cannot be null.", validationException);
|
||||
}
|
||||
if (isTermsLookupQuery() && this.values != null) {
|
||||
validationException = addValidationError("can't have both a terms query and a lookup query.", validationException);
|
||||
}
|
||||
if (isTermsLookupQuery()) {
|
||||
QueryValidationException exception = termsLookup.validate();
|
||||
if (exception != null) {
|
||||
validationException = QueryValidationException.addValidationErrors(exception.validationErrors(), validationException);
|
||||
}
|
||||
}
|
||||
return validationException;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected TermsQueryBuilder doReadFrom(StreamInput in) throws IOException {
|
||||
|
@ -448,8 +347,8 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
|
|||
@Override
|
||||
protected void doWriteTo(StreamOutput out) throws IOException {
|
||||
out.writeString(fieldName);
|
||||
out.writeBoolean(isTermsLookupQuery());
|
||||
if (isTermsLookupQuery()) {
|
||||
out.writeBoolean(termsLookup != null);
|
||||
if (termsLookup != null) {
|
||||
termsLookup.writeTo(out);
|
||||
}
|
||||
out.writeGenericValue(values);
|
||||
|
|
|
@ -21,7 +21,6 @@ package org.elasticsearch.index.query;
|
|||
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.ParsingException;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.indices.cache.query.terms.TermsLookup;
|
||||
|
||||
|
@ -77,7 +76,7 @@ public class TermsQueryParser extends BaseQueryParser {
|
|||
values = parseValues(parseContext, parser);
|
||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
fieldName = currentFieldName;
|
||||
termsLookup = parseTermsLookup(parseContext, parser);
|
||||
termsLookup = TermsLookup.parseTermsLookup(parseContext, parser);
|
||||
} else if (token.isValue()) {
|
||||
if (parseContext.parseFieldMatcher().match(currentFieldName, EXECUTION_FIELD)) {
|
||||
// ignore
|
||||
|
@ -119,42 +118,6 @@ public class TermsQueryParser extends BaseQueryParser {
|
|||
return values;
|
||||
}
|
||||
|
||||
private static TermsLookup parseTermsLookup(QueryParseContext parseContext, XContentParser parser) throws IOException {
|
||||
TermsLookup termsLookup = new TermsLookup();
|
||||
XContentParser.Token token;
|
||||
String currentFieldName = null;
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
if (token == XContentParser.Token.FIELD_NAME) {
|
||||
currentFieldName = parser.currentName();
|
||||
} else if (token.isValue()) {
|
||||
if ("index".equals(currentFieldName)) {
|
||||
termsLookup.index(parser.textOrNull());
|
||||
} else if ("type".equals(currentFieldName)) {
|
||||
termsLookup.type(parser.text());
|
||||
} else if ("id".equals(currentFieldName)) {
|
||||
termsLookup.id(parser.text());
|
||||
} else if ("routing".equals(currentFieldName)) {
|
||||
termsLookup.routing(parser.textOrNull());
|
||||
} else if ("path".equals(currentFieldName)) {
|
||||
termsLookup.path(parser.text());
|
||||
} else {
|
||||
throw new ParsingException(parseContext, "[terms] query does not support [" + currentFieldName
|
||||
+ "] within lookup element");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (termsLookup.type() == null) {
|
||||
throw new ParsingException(parseContext, "[terms] query lookup element requires specifying the type");
|
||||
}
|
||||
if (termsLookup.id() == null) {
|
||||
throw new ParsingException(parseContext, "[terms] query lookup element requires specifying the id");
|
||||
}
|
||||
if (termsLookup.path() == null) {
|
||||
throw new ParsingException(parseContext, "[terms] query lookup element requires specifying the path");
|
||||
}
|
||||
return termsLookup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TermsQueryBuilder getBuilderPrototype() {
|
||||
return TermsQueryBuilder.PROTOTYPE;
|
||||
|
|
|
@ -19,12 +19,14 @@
|
|||
|
||||
package org.elasticsearch.indices.cache.query.terms;
|
||||
|
||||
import org.elasticsearch.common.ParsingException;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.io.stream.Writeable;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.index.query.QueryValidationException;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.query.QueryParseContext;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
@ -33,18 +35,24 @@ import java.util.Objects;
|
|||
* Encapsulates the parameters needed to fetch terms.
|
||||
*/
|
||||
public class TermsLookup implements Writeable<TermsLookup>, ToXContent {
|
||||
static final TermsLookup PROTOTYPE = new TermsLookup();
|
||||
static final TermsLookup PROTOTYPE = new TermsLookup("index", "type", "id", "path");
|
||||
|
||||
private String index;
|
||||
private String type;
|
||||
private String id;
|
||||
private String path;
|
||||
private final String type;
|
||||
private final String id;
|
||||
private final String path;
|
||||
private String routing;
|
||||
|
||||
public TermsLookup() {
|
||||
}
|
||||
|
||||
public TermsLookup(String index, String type, String id, String path) {
|
||||
if (id == null) {
|
||||
throw new IllegalArgumentException("[terms] query lookup element requires specifying the id.");
|
||||
}
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("[terms] query lookup element requires specifying the type.");
|
||||
}
|
||||
if (path == null) {
|
||||
throw new IllegalArgumentException("[terms] query lookup element requires specifying the path.");
|
||||
}
|
||||
this.index = index;
|
||||
this.type = type;
|
||||
this.id = id;
|
||||
|
@ -64,29 +72,14 @@ public class TermsLookup implements Writeable<TermsLookup>, ToXContent {
|
|||
return type;
|
||||
}
|
||||
|
||||
public TermsLookup type(String type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public TermsLookup id(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String path() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public TermsLookup path(String path) {
|
||||
this.path = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String routing() {
|
||||
return routing;
|
||||
}
|
||||
|
@ -96,6 +89,43 @@ public class TermsLookup implements Writeable<TermsLookup>, ToXContent {
|
|||
return this;
|
||||
}
|
||||
|
||||
public static TermsLookup parseTermsLookup(QueryParseContext parseContext, XContentParser parser) throws IOException {
|
||||
String index = null;
|
||||
String type = null;
|
||||
String id = null;
|
||||
String path = null;
|
||||
String routing = null;
|
||||
XContentParser.Token token;
|
||||
String currentFieldName = "";
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
if (token == XContentParser.Token.FIELD_NAME) {
|
||||
currentFieldName = parser.currentName();
|
||||
} else if (token.isValue()) {
|
||||
switch (currentFieldName) {
|
||||
case "index":
|
||||
index = parser.textOrNull();
|
||||
break;
|
||||
case "type":
|
||||
type = parser.text();
|
||||
break;
|
||||
case "id":
|
||||
id = parser.text();
|
||||
break;
|
||||
case "routing":
|
||||
routing = parser.textOrNull();
|
||||
break;
|
||||
case "path":
|
||||
path = parser.text();
|
||||
break;
|
||||
default:
|
||||
throw new ParsingException(parseContext, "[terms] query does not support [" + currentFieldName
|
||||
+ "] within lookup element");
|
||||
}
|
||||
}
|
||||
}
|
||||
return new TermsLookup(index, type, id, path).routing(routing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return index + "/" + type + "/" + id + "/" + path;
|
||||
|
@ -103,11 +133,11 @@ public class TermsLookup implements Writeable<TermsLookup>, ToXContent {
|
|||
|
||||
@Override
|
||||
public TermsLookup readFrom(StreamInput in) throws IOException {
|
||||
TermsLookup termsLookup = new TermsLookup();
|
||||
termsLookup.index = in.readOptionalString();
|
||||
termsLookup.type = in.readString();
|
||||
termsLookup.id = in.readString();
|
||||
termsLookup.path = in.readString();
|
||||
String type = in.readString();
|
||||
String id = in.readString();
|
||||
String path = in.readString();
|
||||
String index = in.readOptionalString();
|
||||
TermsLookup termsLookup = new TermsLookup(index, type, id, path);
|
||||
termsLookup.routing = in.readOptionalString();
|
||||
return termsLookup;
|
||||
}
|
||||
|
@ -118,10 +148,10 @@ public class TermsLookup implements Writeable<TermsLookup>, ToXContent {
|
|||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
out.writeOptionalString(index);
|
||||
out.writeString(type);
|
||||
out.writeString(id);
|
||||
out.writeString(path);
|
||||
out.writeOptionalString(index);
|
||||
out.writeOptionalString(routing);
|
||||
}
|
||||
|
||||
|
@ -159,22 +189,4 @@ public class TermsLookup implements Writeable<TermsLookup>, ToXContent {
|
|||
Objects.equals(path, other.path) &&
|
||||
Objects.equals(routing, other.routing);
|
||||
}
|
||||
|
||||
public QueryValidationException validate() {
|
||||
QueryValidationException validationException = null;
|
||||
if (id == null) {
|
||||
validationException = addValidationError("[terms] query lookup element requires specifying the id.", validationException);
|
||||
}
|
||||
if (type == null) {
|
||||
validationException = addValidationError("[terms] query lookup element requires specifying the type.", validationException);
|
||||
}
|
||||
if (path == null) {
|
||||
validationException = addValidationError("[terms] query lookup element requires specifying the path.", validationException);
|
||||
}
|
||||
return validationException;
|
||||
}
|
||||
|
||||
private static QueryValidationException addValidationError(String validationError, QueryValidationException validationException) {
|
||||
return QueryValidationException.addValidationError("terms_lookup", validationError, validationException);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ public class ExternalValuesMapperIntegrationIT extends ESIntegTestCase {
|
|||
assertThat(response.getHits().totalHits(), equalTo((long) 1));
|
||||
|
||||
response = client().prepareSearch("test-idx")
|
||||
.setPostFilter(QueryBuilders.geoDistanceRangeQuery("field.point").point(42.0, 51.0).to("1km"))
|
||||
.setPostFilter(QueryBuilders.geoDistanceRangeQuery("field.point", 42.0, 51.0).to("1km"))
|
||||
.execute().actionGet();
|
||||
|
||||
assertThat(response.getHits().totalHits(), equalTo((long) 1));
|
||||
|
|
|
@ -480,16 +480,6 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
|
|||
return createShardContext().parseContext();
|
||||
}
|
||||
|
||||
protected static void assertValidate(QueryBuilder queryBuilder, int totalExpectedErrors) {
|
||||
QueryValidationException queryValidationException = queryBuilder.validate();
|
||||
if (totalExpectedErrors > 0) {
|
||||
assertThat(queryValidationException, notNullValue());
|
||||
assertThat(queryValidationException.validationErrors().size(), equalTo(totalExpectedErrors));
|
||||
} else {
|
||||
assertThat(queryValidationException, nullValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create a random value for either {@link AbstractQueryTestCase#BOOLEAN_FIELD_NAME}, {@link AbstractQueryTestCase#INT_FIELD_NAME},
|
||||
* {@link AbstractQueryTestCase#DOUBLE_FIELD_NAME}, {@link AbstractQueryTestCase#STRING_FIELD_NAME} or
|
||||
|
|
|
@ -89,7 +89,6 @@ public class DisMaxQueryBuilderTests extends AbstractQueryTestCase<DisMaxQueryBu
|
|||
public void testNoInnerQueries() throws IOException {
|
||||
DisMaxQueryBuilder disMaxBuilder = new DisMaxQueryBuilder();
|
||||
assertNull(disMaxBuilder.toQuery(createShardContext()));
|
||||
assertNull(disMaxBuilder.validate());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -116,14 +116,14 @@ public class GeoDistanceQueryBuilderTests extends AbstractQueryTestCase<GeoDista
|
|||
|
||||
try {
|
||||
query.distance("1", null);
|
||||
fail("must not be null");
|
||||
fail("unit must not be null");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// expected
|
||||
}
|
||||
|
||||
try {
|
||||
query.distance(1, null);
|
||||
fail("must not be null");
|
||||
fail("unit must not be null");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// expected
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import org.elasticsearch.common.geo.GeoDistance;
|
|||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.common.unit.DistanceUnit;
|
||||
import org.elasticsearch.index.search.geo.GeoDistanceRangeQuery;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -32,22 +31,21 @@ import java.io.IOException;
|
|||
import static org.hamcrest.Matchers.closeTo;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
|
||||
public class GeoDistanceRangeQueryTests extends AbstractQueryTestCase<GeoDistanceRangeQueryBuilder> {
|
||||
|
||||
@Override
|
||||
protected GeoDistanceRangeQueryBuilder doCreateTestQueryBuilder() {
|
||||
GeoDistanceRangeQueryBuilder builder = new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME);
|
||||
GeoDistanceRangeQueryBuilder builder;
|
||||
if (randomBoolean()) {
|
||||
builder.geohash(randomGeohash(1, 12));
|
||||
builder = new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME, randomGeohash(1, 12));
|
||||
} else {
|
||||
double lat = randomDouble() * 180 - 90;
|
||||
double lon = randomDouble() * 360 - 180;
|
||||
if (randomBoolean()) {
|
||||
builder.point(lat, lon);
|
||||
builder = new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME, new GeoPoint(lat, lon));
|
||||
} else {
|
||||
builder.point(new GeoPoint(lat, lon));
|
||||
builder = new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME, lat, lon);
|
||||
}
|
||||
}
|
||||
int fromValue = randomInt(1000000);
|
||||
|
@ -151,97 +149,63 @@ public class GeoDistanceRangeQueryTests extends AbstractQueryTestCase<GeoDistanc
|
|||
super.testToQuery();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testNullFieldName() {
|
||||
GeoDistanceRangeQueryBuilder builder = new GeoDistanceRangeQueryBuilder(null);
|
||||
builder.geohash(randomGeohash(1, 20));
|
||||
builder.from(10);
|
||||
QueryValidationException exception = builder.validate();
|
||||
assertThat(exception, notNullValue());
|
||||
assertThat(exception.validationErrors(), notNullValue());
|
||||
assertThat(exception.validationErrors().size(), equalTo(1));
|
||||
assertThat(exception.validationErrors().get(0), equalTo("[" + GeoDistanceRangeQueryBuilder.NAME + "] fieldName must not be null"));
|
||||
if (randomBoolean()) {
|
||||
new GeoDistanceRangeQueryBuilder(null, new GeoPoint());
|
||||
} else {
|
||||
new GeoDistanceRangeQueryBuilder("", new GeoPoint());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testNoPoint() {
|
||||
GeoDistanceRangeQueryBuilder builder = new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME);
|
||||
builder.from(10);
|
||||
QueryValidationException exception = builder.validate();
|
||||
assertThat(exception, notNullValue());
|
||||
assertThat(exception.validationErrors(), notNullValue());
|
||||
assertThat(exception.validationErrors().size(), equalTo(1));
|
||||
assertThat(exception.validationErrors().get(0), equalTo("[" + GeoDistanceRangeQueryBuilder.NAME + "] point must not be null"));
|
||||
if (randomBoolean()) {
|
||||
new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME, (GeoPoint) null);
|
||||
} else {
|
||||
new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME, (String) null);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoFromOrTo() {
|
||||
GeoDistanceRangeQueryBuilder builder = new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME);
|
||||
String geohash = randomGeohash(1, 20);
|
||||
builder.geohash(geohash);
|
||||
QueryValidationException exception = builder.validate();
|
||||
assertThat(exception, notNullValue());
|
||||
assertThat(exception.validationErrors(), notNullValue());
|
||||
assertThat(exception.validationErrors().size(), equalTo(1));
|
||||
assertThat(exception.validationErrors().get(0), equalTo("[" + GeoDistanceRangeQueryBuilder.NAME
|
||||
+ "] Must define at least one parameter from [from, to]"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testInvalidFrom() {
|
||||
GeoDistanceRangeQueryBuilder builder = new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME);
|
||||
String geohash = randomGeohash(1, 20);
|
||||
builder.geohash(geohash);
|
||||
builder.from(new DateTime());
|
||||
QueryValidationException exception = builder.validate();
|
||||
assertThat(exception, notNullValue());
|
||||
assertThat(exception.validationErrors(), notNullValue());
|
||||
assertThat(exception.validationErrors().size(), equalTo(1));
|
||||
assertThat(exception.validationErrors().get(0), equalTo("[" + GeoDistanceRangeQueryBuilder.NAME
|
||||
+ "] from must either be a number or a string. Found [" + DateTime.class.getName() + "]"));
|
||||
GeoDistanceRangeQueryBuilder builder = new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME, new GeoPoint());
|
||||
if (randomBoolean()) {
|
||||
builder.from((String) null);
|
||||
} else {
|
||||
builder.from((Number) null);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testInvalidTo() {
|
||||
GeoDistanceRangeQueryBuilder builder = new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME);
|
||||
String geohash = randomGeohash(1, 20);
|
||||
builder.geohash(geohash);
|
||||
builder.to(new DateTime());
|
||||
QueryValidationException exception = builder.validate();
|
||||
assertThat(exception, notNullValue());
|
||||
assertThat(exception.validationErrors(), notNullValue());
|
||||
assertThat(exception.validationErrors().size(), equalTo(1));
|
||||
assertThat(exception.validationErrors().get(0), equalTo("[" + GeoDistanceRangeQueryBuilder.NAME
|
||||
+ "] to must either be a number or a string. Found [" + DateTime.class.getName() + "]"));
|
||||
GeoDistanceRangeQueryBuilder builder = new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME, new GeoPoint());
|
||||
if (randomBoolean()) {
|
||||
builder.to((String) null);
|
||||
} else {
|
||||
builder.to((Number) null);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testInvalidOptimizeBBox() {
|
||||
GeoDistanceRangeQueryBuilder builder = new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME);
|
||||
String geohash = randomGeohash(1, 20);
|
||||
builder.geohash(geohash);
|
||||
builder.from(10);
|
||||
builder.optimizeBbox("foo");
|
||||
QueryValidationException exception = builder.validate();
|
||||
assertThat(exception, notNullValue());
|
||||
assertThat(exception.validationErrors(), notNullValue());
|
||||
assertThat(exception.validationErrors().size(), equalTo(1));
|
||||
assertThat(exception.validationErrors().get(0), equalTo("[" + GeoDistanceRangeQueryBuilder.NAME
|
||||
+ "] optimizeBbox must be one of [none, memory, indexed]"));
|
||||
GeoDistanceRangeQueryBuilder builder = new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME, new GeoPoint());
|
||||
if (randomBoolean()) {
|
||||
builder.optimizeBbox(null);
|
||||
} else {
|
||||
builder.optimizeBbox("foo");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleValidationErrors() {
|
||||
GeoDistanceRangeQueryBuilder builder = new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME);
|
||||
double lat = randomDouble() * 360 - 180;
|
||||
double lon = randomDouble() * 360 - 180;
|
||||
builder.point(lat, lon);
|
||||
builder.from(new DateTime());
|
||||
builder.to(new DateTime());
|
||||
builder.optimizeBbox("foo");
|
||||
QueryValidationException exception = builder.validate();
|
||||
assertThat(exception, notNullValue());
|
||||
assertThat(exception.validationErrors(), notNullValue());
|
||||
assertThat(exception.validationErrors().size(), equalTo(3));
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testInvalidGeoDistance() {
|
||||
GeoDistanceRangeQueryBuilder builder = new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME, new GeoPoint());
|
||||
builder.geoDistance(null);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testInvalidDistanceUnit() {
|
||||
GeoDistanceRangeQueryBuilder builder = new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME, new GeoPoint());
|
||||
builder.unit(null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,33 +39,13 @@ import java.util.List;
|
|||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
|
||||
public class GeoPolygonQueryBuilderTests extends AbstractQueryTestCase<GeoPolygonQueryBuilder> {
|
||||
|
||||
@Override
|
||||
protected GeoPolygonQueryBuilder doCreateTestQueryBuilder() {
|
||||
GeoPolygonQueryBuilder builder;
|
||||
List<GeoPoint> polygon = randomPolygon(randomIntBetween(4, 50));
|
||||
if (randomBoolean()) {
|
||||
builder = new GeoPolygonQueryBuilder(GEO_POINT_FIELD_NAME, polygon);
|
||||
} else {
|
||||
builder = new GeoPolygonQueryBuilder(GEO_POINT_FIELD_NAME);
|
||||
for (GeoPoint point : polygon) {
|
||||
int method = randomInt(2);
|
||||
switch (method) {
|
||||
case 0:
|
||||
builder.addPoint(point);
|
||||
break;
|
||||
case 1:
|
||||
builder.addPoint(point.geohash());
|
||||
break;
|
||||
case 2:
|
||||
builder.addPoint(point.lat(), point.lon());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
GeoPolygonQueryBuilder builder = new GeoPolygonQueryBuilder(GEO_POINT_FIELD_NAME, polygon);
|
||||
builder.coerce(randomBoolean());
|
||||
builder.ignoreMalformed(randomBoolean());
|
||||
return builder;
|
||||
|
@ -123,45 +103,34 @@ public class GeoPolygonQueryBuilderTests extends AbstractQueryTestCase<GeoPolygo
|
|||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testNullFieldName() {
|
||||
new GeoPolygonQueryBuilder(null);
|
||||
new GeoPolygonQueryBuilder(null, randomPolygon(5));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testEmptyPolygon() {
|
||||
GeoPolygonQueryBuilder builder = new GeoPolygonQueryBuilder(GEO_POINT_FIELD_NAME);
|
||||
QueryValidationException exception = builder.validate();
|
||||
assertThat(exception, notNullValue());
|
||||
assertThat(exception.validationErrors(), notNullValue());
|
||||
assertThat(exception.validationErrors().size(), equalTo(1));
|
||||
assertThat(exception.validationErrors().get(0), equalTo("[" + GeoPolygonQueryBuilder.NAME
|
||||
+ "] no points defined for geo_polygon query"));
|
||||
if (randomBoolean()) {
|
||||
new GeoPolygonQueryBuilder(GEO_POINT_FIELD_NAME, new ArrayList<GeoPoint>());
|
||||
} else {
|
||||
new GeoPolygonQueryBuilder(GEO_POINT_FIELD_NAME, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testInvalidClosedPolygon() {
|
||||
GeoPolygonQueryBuilder builder = new GeoPolygonQueryBuilder(GEO_POINT_FIELD_NAME);
|
||||
builder.addPoint(new GeoPoint(0, 90));
|
||||
builder.addPoint(new GeoPoint(90, 90));
|
||||
builder.addPoint(new GeoPoint(0, 90));
|
||||
QueryValidationException exception = builder.validate();
|
||||
assertThat(exception, notNullValue());
|
||||
assertThat(exception.validationErrors(), notNullValue());
|
||||
assertThat(exception.validationErrors().size(), equalTo(1));
|
||||
assertThat(exception.validationErrors().get(0), equalTo("[" + GeoPolygonQueryBuilder.NAME
|
||||
+ "] too few points defined for geo_polygon query"));
|
||||
List<GeoPoint> points = new ArrayList<>();
|
||||
points.add(new GeoPoint(0, 90));
|
||||
points.add(new GeoPoint(90, 90));
|
||||
points.add(new GeoPoint(0, 90));
|
||||
new GeoPolygonQueryBuilder(GEO_POINT_FIELD_NAME, points);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testInvalidOpenPolygon() {
|
||||
GeoPolygonQueryBuilder builder = new GeoPolygonQueryBuilder(GEO_POINT_FIELD_NAME);
|
||||
builder.addPoint(new GeoPoint(0, 90));
|
||||
builder.addPoint(new GeoPoint(90, 90));
|
||||
QueryValidationException exception = builder.validate();
|
||||
assertThat(exception, notNullValue());
|
||||
assertThat(exception.validationErrors(), notNullValue());
|
||||
assertThat(exception.validationErrors().size(), equalTo(1));
|
||||
assertThat(exception.validationErrors().get(0), equalTo("[" + GeoPolygonQueryBuilder.NAME
|
||||
+ "] too few points defined for geo_polygon query"));
|
||||
List<GeoPoint> points = new ArrayList<>();
|
||||
points.add(new GeoPoint(0, 90));
|
||||
points.add(new GeoPoint(90, 90));
|
||||
new GeoPolygonQueryBuilder(GEO_POINT_FIELD_NAME, points);
|
||||
}
|
||||
|
||||
public void testDeprecatedXContent() throws IOException {
|
||||
|
|
|
@ -149,13 +149,9 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
|
|||
public void testNoShape() throws IOException {
|
||||
try {
|
||||
GeoShapeQueryBuilder builder = new GeoShapeQueryBuilder(GEO_SHAPE_FIELD_NAME, (ShapeBuilder) null);
|
||||
QueryValidationException exception = builder.validate();
|
||||
assertThat(exception, notNullValue());
|
||||
assertThat(exception.validationErrors(), notNullValue());
|
||||
assertThat(exception.validationErrors().size(), equalTo(1));
|
||||
assertThat(exception.validationErrors().get(0), equalTo("[" + GeoShapeQueryBuilder.NAME + "] No Shape defined"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
fail("exception expected");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,18 +166,14 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testNoRelation() {
|
||||
public void testNoRelation() throws IOException {
|
||||
ShapeBuilder shape = RandomShapeGenerator.createShapeWithin(getRandom(), null);
|
||||
try {
|
||||
GeoShapeQueryBuilder builder = new GeoShapeQueryBuilder(GEO_SHAPE_FIELD_NAME, shape);
|
||||
builder.relation(null);
|
||||
QueryValidationException exception = builder.validate();
|
||||
assertThat(exception, notNullValue());
|
||||
assertThat(exception.validationErrors(), notNullValue());
|
||||
assertThat(exception.validationErrors().size(), equalTo(1));
|
||||
assertThat(exception.validationErrors().get(0), equalTo("[" + GeoShapeQueryBuilder.NAME + "] No Shape Relation defined"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
fail("relation cannot be null");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.apache.lucene.index.Term;
|
|||
import org.apache.lucene.queries.TermsQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.common.unit.DistanceUnit;
|
||||
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
||||
import org.elasticsearch.index.query.GeohashCellQuery.Builder;
|
||||
|
@ -32,14 +33,12 @@ import java.io.IOException;
|
|||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
|
||||
public class GeohashCellQueryBuilderTests extends AbstractQueryTestCase<Builder> {
|
||||
|
||||
@Override
|
||||
protected Builder doCreateTestQueryBuilder() {
|
||||
GeohashCellQuery.Builder builder = new Builder(GEO_POINT_FIELD_NAME);
|
||||
builder.geohash(randomGeohash(1, 12));
|
||||
GeohashCellQuery.Builder builder = new Builder(GEO_POINT_FIELD_NAME, randomGeohash(1, 12));
|
||||
if (randomBoolean()) {
|
||||
builder.neighbors(randomBoolean());
|
||||
}
|
||||
|
@ -82,38 +81,28 @@ public class GeohashCellQueryBuilderTests extends AbstractQueryTestCase<Builder>
|
|||
super.testToQuery();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testNullField() {
|
||||
GeohashCellQuery.Builder builder = new Builder(null);
|
||||
builder.geohash(randomGeohash(1, 12));
|
||||
QueryValidationException exception = builder.validate();
|
||||
assertThat(exception, notNullValue());
|
||||
assertThat(exception.validationErrors(), notNullValue());
|
||||
assertThat(exception.validationErrors().size(), equalTo(1));
|
||||
assertThat(exception.validationErrors().get(0), equalTo("[" + GeohashCellQuery.NAME + "] fieldName must not be null"));
|
||||
if (randomBoolean()) {
|
||||
new Builder(null, new GeoPoint());
|
||||
} else {
|
||||
new Builder("", new GeoPoint());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullGeohash() {
|
||||
GeohashCellQuery.Builder builder = new Builder(GEO_POINT_FIELD_NAME);
|
||||
QueryValidationException exception = builder.validate();
|
||||
assertThat(exception, notNullValue());
|
||||
assertThat(exception.validationErrors(), notNullValue());
|
||||
assertThat(exception.validationErrors().size(), equalTo(1));
|
||||
assertThat(exception.validationErrors().get(0), equalTo("[" + GeohashCellQuery.NAME + "] geohash or point must be defined"));
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testNullGeoPoint() {
|
||||
if (randomBoolean()) {
|
||||
new Builder(GEO_POINT_FIELD_NAME, (GeoPoint) null);
|
||||
} else {
|
||||
new Builder(GEO_POINT_FIELD_NAME, "");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testInvalidPrecision() {
|
||||
GeohashCellQuery.Builder builder = new Builder(GEO_POINT_FIELD_NAME);
|
||||
builder.geohash(randomGeohash(1, 12));
|
||||
GeohashCellQuery.Builder builder = new Builder(GEO_POINT_FIELD_NAME, new GeoPoint());
|
||||
builder.precision(-1);
|
||||
QueryValidationException exception = builder.validate();
|
||||
assertThat(exception, notNullValue());
|
||||
assertThat(exception.validationErrors(), notNullValue());
|
||||
assertThat(exception.validationErrors().size(), equalTo(1));
|
||||
assertThat(exception.validationErrors().get(0), equalTo("[" + GeohashCellQuery.NAME + "] precision must be greater than 0. Found ["
|
||||
+ -1 + "]"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package org.elasticsearch.index.query;
|
||||
|
||||
import com.carrotsearch.randomizedtesting.generators.RandomPicks;
|
||||
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.BooleanClause;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
|
@ -31,7 +32,6 @@ import org.elasticsearch.action.get.GetRequest;
|
|||
import org.elasticsearch.action.get.GetResponse;
|
||||
import org.elasticsearch.common.ParseFieldMatcher;
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.index.get.GetResult;
|
||||
|
@ -78,19 +78,14 @@ public class TermsQueryBuilderTests extends AbstractQueryTestCase<TermsQueryBuil
|
|||
query = new TermsQueryBuilder(fieldName, values);
|
||||
} else {
|
||||
// right now the mock service returns us a list of strings
|
||||
query = new TermsQueryBuilder(randomBoolean() ? randomAsciiOfLengthBetween(1,10) : STRING_FIELD_NAME);
|
||||
query.termsLookup(randomTermsLookup());
|
||||
query = new TermsQueryBuilder(randomBoolean() ? randomAsciiOfLengthBetween(1,10) : STRING_FIELD_NAME, randomTermsLookup());
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
private TermsLookup randomTermsLookup() {
|
||||
return new TermsLookup(
|
||||
randomBoolean() ? randomAsciiOfLength(10) : null,
|
||||
randomAsciiOfLength(10),
|
||||
randomAsciiOfLength(10),
|
||||
termsPath
|
||||
).routing(randomBoolean() ? randomAsciiOfLength(10) : null);
|
||||
return new TermsLookup(randomBoolean() ? randomAsciiOfLength(10) : null, randomAsciiOfLength(10), randomAsciiOfLength(10),
|
||||
termsPath).routing(randomBoolean() ? randomAsciiOfLength(10) : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -131,38 +126,18 @@ public class TermsQueryBuilderTests extends AbstractQueryTestCase<TermsQueryBuil
|
|||
assertEquals(expectedTerms + " vs. " + booleanTerms, expectedTerms, booleanTerms);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidate() {
|
||||
TermsQueryBuilder termsQueryBuilder = new TermsQueryBuilder(null, "term");
|
||||
assertThat(termsQueryBuilder.validate().validationErrors().size(), is(1));
|
||||
|
||||
termsQueryBuilder = new TermsQueryBuilder("field", "term").termsLookup(randomTermsLookup());
|
||||
assertThat(termsQueryBuilder.validate().validationErrors().size(), is(1));
|
||||
|
||||
termsQueryBuilder = new TermsQueryBuilder(null, "term").termsLookup(randomTermsLookup());
|
||||
assertThat(termsQueryBuilder.validate().validationErrors().size(), is(2));
|
||||
|
||||
termsQueryBuilder = new TermsQueryBuilder("field", "term");
|
||||
assertNull(termsQueryBuilder.validate());
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testEmtpyFieldName() {
|
||||
if (randomBoolean()) {
|
||||
new TermsQueryBuilder(null, "term");
|
||||
} else {
|
||||
new TermsQueryBuilder("", "term");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateLookupQuery() {
|
||||
TermsQueryBuilder termsQuery = new TermsQueryBuilder("field").termsLookup(new TermsLookup());
|
||||
int totalExpectedErrors = 3;
|
||||
if (randomBoolean()) {
|
||||
termsQuery.lookupId("id");
|
||||
totalExpectedErrors--;
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
termsQuery.lookupType("type");
|
||||
totalExpectedErrors--;
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
termsQuery.lookupPath("path");
|
||||
totalExpectedErrors--;
|
||||
}
|
||||
assertValidate(termsQuery, totalExpectedErrors);
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testEmtpyTermsLookup() {
|
||||
new TermsQueryBuilder("field", (TermsLookup) null);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -197,7 +172,7 @@ public class TermsQueryBuilderTests extends AbstractQueryTestCase<TermsQueryBuil
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testBothValuesAndLookupSet() throws IOException {
|
||||
String query = "{\n" +
|
||||
" \"terms\": {\n" +
|
||||
|
@ -214,7 +189,6 @@ public class TermsQueryBuilderTests extends AbstractQueryTestCase<TermsQueryBuil
|
|||
" }\n" +
|
||||
"}";
|
||||
QueryBuilder termsQueryBuilder = parseQuery(query);
|
||||
assertThat(termsQueryBuilder.validate().validationErrors().size(), is(1));
|
||||
}
|
||||
|
||||
public void testDeprecatedXContent() throws IOException {
|
||||
|
|
85
core/src/test/java/org/elasticsearch/indices/cache/query/terms/TermsLookupTests.java
vendored
Normal file
85
core/src/test/java/org/elasticsearch/indices/cache/query/terms/TermsLookupTests.java
vendored
Normal file
|
@ -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.indices.cache.query.terms;
|
||||
|
||||
import org.elasticsearch.common.io.stream.BytesStreamOutput;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class TermsLookupTests extends ESTestCase {
|
||||
|
||||
@Test
|
||||
public void testTermsLookup() {
|
||||
String index = randomAsciiOfLengthBetween(1, 10);
|
||||
String type = randomAsciiOfLengthBetween(1, 10);
|
||||
String id = randomAsciiOfLengthBetween(1, 10);
|
||||
String path = randomAsciiOfLengthBetween(1, 10);
|
||||
String routing = randomAsciiOfLengthBetween(1, 10);
|
||||
TermsLookup termsLookup = new TermsLookup(index, type, id, path);
|
||||
termsLookup.routing(routing);
|
||||
assertEquals(index, termsLookup.index());
|
||||
assertEquals(type, termsLookup.type());
|
||||
assertEquals(id, termsLookup.id());
|
||||
assertEquals(path, termsLookup.path());
|
||||
assertEquals(routing, termsLookup.routing());
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testIllegalArguments() {
|
||||
String type = randomAsciiOfLength(5);
|
||||
String id = randomAsciiOfLength(5);
|
||||
String path = randomAsciiOfLength(5);
|
||||
switch (randomIntBetween(0, 2)) {
|
||||
case 0:
|
||||
type = null; break;
|
||||
case 1:
|
||||
id = null; break;
|
||||
case 2:
|
||||
path = null; break;
|
||||
}
|
||||
new TermsLookup(null, type, id, path);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerialization() throws IOException {
|
||||
TermsLookup termsLookup = randomTermsLookup();
|
||||
try (BytesStreamOutput output = new BytesStreamOutput()) {
|
||||
termsLookup.writeTo(output);
|
||||
try (StreamInput in = StreamInput.wrap(output.bytes())) {
|
||||
TermsLookup deserializedLookup = TermsLookup.readTermsLookupFrom(in);
|
||||
assertEquals(deserializedLookup, termsLookup);
|
||||
assertEquals(deserializedLookup.hashCode(), termsLookup.hashCode());
|
||||
assertNotSame(deserializedLookup, termsLookup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static TermsLookup randomTermsLookup() {
|
||||
return new TermsLookup(
|
||||
randomBoolean() ? randomAsciiOfLength(10) : null,
|
||||
randomAsciiOfLength(10),
|
||||
randomAsciiOfLength(10),
|
||||
randomAsciiOfLength(10).replace('.', '_')
|
||||
).routing(randomBoolean() ? randomAsciiOfLength(10) : null);
|
||||
}
|
||||
}
|
|
@ -171,7 +171,7 @@ public class GeoDistanceIT extends ESIntegTestCase {
|
|||
}
|
||||
|
||||
searchResponse = client().prepareSearch() // from NY
|
||||
.setQuery(geoDistanceRangeQuery("location").from("1.0km").to("2.0km").point(40.7143528, -74.0059731))
|
||||
.setQuery(geoDistanceRangeQuery("location", 40.7143528, -74.0059731).from("1.0km").to("2.0km"))
|
||||
.execute().actionGet();
|
||||
assertHitCount(searchResponse, 2);
|
||||
assertThat(searchResponse.getHits().hits().length, equalTo(2));
|
||||
|
@ -179,7 +179,7 @@ public class GeoDistanceIT extends ESIntegTestCase {
|
|||
assertThat(hit.id(), anyOf(equalTo("4"), equalTo("5")));
|
||||
}
|
||||
searchResponse = client().prepareSearch() // from NY
|
||||
.setQuery(geoDistanceRangeQuery("location").from("1.0km").to("2.0km").point(40.7143528, -74.0059731).optimizeBbox("indexed"))
|
||||
.setQuery(geoDistanceRangeQuery("location", 40.7143528, -74.0059731).from("1.0km").to("2.0km").optimizeBbox("indexed"))
|
||||
.execute().actionGet();
|
||||
assertHitCount(searchResponse, 2);
|
||||
assertThat(searchResponse.getHits().hits().length, equalTo(2));
|
||||
|
@ -188,13 +188,13 @@ public class GeoDistanceIT extends ESIntegTestCase {
|
|||
}
|
||||
|
||||
searchResponse = client().prepareSearch() // from NY
|
||||
.setQuery(geoDistanceRangeQuery("location").to("2.0km").point(40.7143528, -74.0059731))
|
||||
.setQuery(geoDistanceRangeQuery("location", 40.7143528, -74.0059731).to("2.0km"))
|
||||
.execute().actionGet();
|
||||
assertHitCount(searchResponse, 4);
|
||||
assertThat(searchResponse.getHits().hits().length, equalTo(4));
|
||||
|
||||
searchResponse = client().prepareSearch() // from NY
|
||||
.setQuery(geoDistanceRangeQuery("location").from("2.0km").point(40.7143528, -74.0059731))
|
||||
.setQuery(geoDistanceRangeQuery("location", 40.7143528, -74.0059731).from("2.0km"))
|
||||
.execute().actionGet();
|
||||
assertHitCount(searchResponse, 3);
|
||||
assertThat(searchResponse.getHits().hits().length, equalTo(3));
|
||||
|
|
|
@ -20,12 +20,16 @@
|
|||
package org.elasticsearch.search.geo;
|
||||
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.search.SearchHit;
|
||||
import org.elasticsearch.test.ESIntegTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.geoPolygonQuery;
|
||||
|
@ -49,7 +53,7 @@ public class GeoPolygonIT extends ESIntegTestCase {
|
|||
indexRandom(true, client().prepareIndex("test", "type1", "1").setSource(jsonBuilder().startObject()
|
||||
.field("name", "New York")
|
||||
.startObject("location").field("lat", 40.714).field("lon", -74.006).endObject()
|
||||
.endObject()),
|
||||
.endObject()),
|
||||
// to NY: 5.286 km
|
||||
client().prepareIndex("test", "type1", "2").setSource(jsonBuilder().startObject()
|
||||
.field("name", "Times Square")
|
||||
|
@ -85,14 +89,14 @@ public class GeoPolygonIT extends ESIntegTestCase {
|
|||
|
||||
@Test
|
||||
public void simplePolygonTest() throws Exception {
|
||||
|
||||
List<GeoPoint> points = new ArrayList<>();
|
||||
points.add(new GeoPoint(40.7, -74.0));
|
||||
points.add(new GeoPoint(40.7, -74.1));
|
||||
points.add(new GeoPoint(40.8, -74.1));
|
||||
points.add(new GeoPoint(40.8, -74.0));
|
||||
points.add(new GeoPoint(40.7, -74.0));
|
||||
SearchResponse searchResponse = client().prepareSearch("test") // from NY
|
||||
.setQuery(boolQuery().must(geoPolygonQuery("location")
|
||||
.addPoint(40.7, -74.0)
|
||||
.addPoint(40.7, -74.1)
|
||||
.addPoint(40.8, -74.1)
|
||||
.addPoint(40.8, -74.0)
|
||||
.addPoint(40.7, -74.0)))
|
||||
.setQuery(boolQuery().must(geoPolygonQuery("location", points)))
|
||||
.execute().actionGet();
|
||||
assertHitCount(searchResponse, 4);
|
||||
assertThat(searchResponse.getHits().hits().length, equalTo(4));
|
||||
|
@ -103,13 +107,13 @@ public class GeoPolygonIT extends ESIntegTestCase {
|
|||
|
||||
@Test
|
||||
public void simpleUnclosedPolygon() throws Exception {
|
||||
List<GeoPoint> points = new ArrayList<>();
|
||||
points.add(new GeoPoint(40.7, -74.0));
|
||||
points.add(new GeoPoint(40.7, -74.1));
|
||||
points.add(new GeoPoint(40.8, -74.1));
|
||||
points.add(new GeoPoint(40.8, -74.0));
|
||||
SearchResponse searchResponse = client().prepareSearch("test") // from NY
|
||||
.setQuery(boolQuery().must(geoPolygonQuery("location")
|
||||
.addPoint(40.7, -74.0)
|
||||
.addPoint(40.7, -74.1)
|
||||
.addPoint(40.8, -74.1)
|
||||
.addPoint(40.8, -74.0)))
|
||||
.execute().actionGet();
|
||||
.setQuery(boolQuery().must(geoPolygonQuery("location", points))).execute().actionGet();
|
||||
assertHitCount(searchResponse, 4);
|
||||
assertThat(searchResponse.getHits().hits().length, equalTo(4));
|
||||
for (SearchHit hit : searchResponse.getHits()) {
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.elasticsearch.index.mapper.MapperParsingException;
|
|||
import org.elasticsearch.index.query.*;
|
||||
import org.elasticsearch.index.search.MatchQuery.Type;
|
||||
import org.elasticsearch.index.search.MatchQuery;
|
||||
import org.elasticsearch.indices.cache.query.terms.TermsLookup;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.search.SearchHit;
|
||||
|
@ -1231,63 +1232,54 @@ public class SearchQueryIT extends ESIntegTestCase {
|
|||
client().prepareIndex("test", "type", "4").setSource("term", "4") );
|
||||
|
||||
SearchResponse searchResponse = client().prepareSearch("test")
|
||||
.setQuery(termsLookupQuery("term").lookupIndex("lookup").lookupType("type").lookupId("1").lookupPath("terms")
|
||||
).get();
|
||||
.setQuery(termsLookupQuery("term" , new TermsLookup("lookup", "type", "1", "terms"))).get();
|
||||
assertHitCount(searchResponse, 2l);
|
||||
assertSearchHits(searchResponse, "1", "3");
|
||||
|
||||
// same as above, just on the _id...
|
||||
searchResponse = client().prepareSearch("test")
|
||||
.setQuery(termsLookupQuery("_id").lookupIndex("lookup").lookupType("type").lookupId("1").lookupPath("terms")
|
||||
.setQuery(termsLookupQuery("_id", new TermsLookup("lookup", "type", "1", "terms"))
|
||||
).get();
|
||||
assertHitCount(searchResponse, 2l);
|
||||
assertSearchHits(searchResponse, "1", "3");
|
||||
|
||||
// another search with same parameters...
|
||||
searchResponse = client().prepareSearch("test")
|
||||
.setQuery(termsLookupQuery("term").lookupIndex("lookup").lookupType("type").lookupId("1").lookupPath("terms")
|
||||
).get();
|
||||
.setQuery(termsLookupQuery("term", new TermsLookup("lookup", "type", "1", "terms"))).get();
|
||||
assertHitCount(searchResponse, 2l);
|
||||
assertSearchHits(searchResponse, "1", "3");
|
||||
|
||||
searchResponse = client().prepareSearch("test")
|
||||
.setQuery(termsLookupQuery("term").lookupIndex("lookup").lookupType("type").lookupId("2").lookupPath("terms")
|
||||
).get();
|
||||
.setQuery(termsLookupQuery("term", new TermsLookup("lookup", "type", "2", "terms"))).get();
|
||||
assertHitCount(searchResponse, 1l);
|
||||
assertFirstHit(searchResponse, hasId("2"));
|
||||
|
||||
searchResponse = client().prepareSearch("test")
|
||||
.setQuery(termsLookupQuery("term").lookupIndex("lookup").lookupType("type").lookupId("3").lookupPath("terms")
|
||||
).get();
|
||||
.setQuery(termsLookupQuery("term", new TermsLookup("lookup", "type", "3", "terms"))).get();
|
||||
assertHitCount(searchResponse, 2l);
|
||||
assertSearchHits(searchResponse, "2", "4");
|
||||
|
||||
searchResponse = client().prepareSearch("test")
|
||||
.setQuery(termsLookupQuery("term").lookupIndex("lookup").lookupType("type").lookupId("4").lookupPath("terms")
|
||||
).get();
|
||||
.setQuery(termsLookupQuery("term", new TermsLookup("lookup", "type", "4", "terms"))).get();
|
||||
assertHitCount(searchResponse, 0l);
|
||||
|
||||
searchResponse = client().prepareSearch("test")
|
||||
.setQuery(termsLookupQuery("term").lookupIndex("lookup2").lookupType("type").lookupId("1").lookupPath("arr.term")
|
||||
).get();
|
||||
.setQuery(termsLookupQuery("term", new TermsLookup("lookup2", "type", "1", "arr.term"))).get();
|
||||
assertHitCount(searchResponse, 2l);
|
||||
assertSearchHits(searchResponse, "1", "3");
|
||||
|
||||
searchResponse = client().prepareSearch("test")
|
||||
.setQuery(termsLookupQuery("term").lookupIndex("lookup2").lookupType("type").lookupId("2").lookupPath("arr.term")
|
||||
).get();
|
||||
.setQuery(termsLookupQuery("term", new TermsLookup("lookup2", "type", "2", "arr.term"))).get();
|
||||
assertHitCount(searchResponse, 1l);
|
||||
assertFirstHit(searchResponse, hasId("2"));
|
||||
|
||||
searchResponse = client().prepareSearch("test")
|
||||
.setQuery(termsLookupQuery("term").lookupIndex("lookup2").lookupType("type").lookupId("3").lookupPath("arr.term")
|
||||
).get();
|
||||
.setQuery(termsLookupQuery("term", new TermsLookup("lookup2", "type", "3", "arr.term"))).get();
|
||||
assertHitCount(searchResponse, 2l);
|
||||
assertSearchHits(searchResponse, "2", "4");
|
||||
|
||||
searchResponse = client().prepareSearch("test")
|
||||
.setQuery(termsLookupQuery("not_exists").lookupIndex("lookup2").lookupType("type").lookupId("3").lookupPath("arr.term")
|
||||
).get();
|
||||
.setQuery(termsLookupQuery("not_exists", new TermsLookup("lookup2", "type", "3", "arr.term"))).get();
|
||||
assertHitCount(searchResponse, 0l);
|
||||
}
|
||||
|
||||
|
|
|
@ -55,10 +55,10 @@ import org.elasticsearch.index.query.MoreLikeThisQueryBuilder;
|
|||
import org.elasticsearch.index.query.MoreLikeThisQueryBuilder.Item;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.index.query.TermsQueryBuilder;
|
||||
import org.elasticsearch.indices.cache.query.terms.TermsLookup;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.rest.RestController;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.script.ScriptService.ScriptType;
|
||||
import org.elasticsearch.script.Template;
|
||||
import org.elasticsearch.script.groovy.GroovyScriptEngineService;
|
||||
|
@ -161,7 +161,7 @@ public class ContextAndHeaderTransportIT extends ESIntegTestCase {
|
|||
.setSource(jsonBuilder().startObject().field("username", "foo").endObject()).get();
|
||||
transportClient().admin().indices().prepareRefresh(queryIndex, lookupIndex).get();
|
||||
|
||||
TermsQueryBuilder termsLookupFilterBuilder = QueryBuilders.termsLookupQuery("username").lookupIndex(lookupIndex).lookupType("type").lookupId("1").lookupPath("followers");
|
||||
TermsQueryBuilder termsLookupFilterBuilder = QueryBuilders.termsLookupQuery("username", new TermsLookup(lookupIndex, "type", "1", "followers"));
|
||||
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().must(QueryBuilders.matchAllQuery()).must(termsLookupFilterBuilder);
|
||||
|
||||
SearchResponse searchResponse = transportClient()
|
||||
|
|
|
@ -111,9 +111,22 @@ The deprecated `docs(Item... docs)`, `ignoreLike(Item... docs)`,
|
|||
Removing individual setters for lon() and lat() values, both values should be set together
|
||||
using point(lon, lat).
|
||||
|
||||
==== GeoDistanceRangeQueryBuilder
|
||||
|
||||
Removing setters for to(Object ...) and from(Object ...) in favour of the only two allowed input
|
||||
arguments (String, Number). Removing setter for center point (point(), geohash()) because parameter
|
||||
is mandatory and should already be set in constructor.
|
||||
Also removing setters for lt(), lte(), gt(), gte() since they can all be replaced by equivallent
|
||||
calls to to/from() and inludeLower()/includeUpper().
|
||||
|
||||
==== GeoPolygonQueryBuilder
|
||||
|
||||
Require shell of polygon already to be specified in constructor instead of adding it pointwise.
|
||||
This enables validation, but makes it necessary to remove the addPoint() methods.
|
||||
|
||||
==== MultiMatchQueryBuilder
|
||||
|
||||
Moving MultiMatchQueryBuilder.ZeroTermsQuery enum to MatchQuery..ZeroTermsQuery.
|
||||
Moving MultiMatchQueryBuilder.ZeroTermsQuery enum to MatchQuery.ZeroTermsQuery.
|
||||
Also reusing new Operator enum.
|
||||
|
||||
Removed ability to pass in boost value using `field(String field)` method in form e.g. `field^2`.
|
||||
|
@ -124,3 +137,11 @@ Use the `field(String, float)` method instead.
|
|||
The two individual setters for existence() and nullValue() were removed in favour of
|
||||
optional constructor settings in order to better capture and validate their interdependent
|
||||
settings at construction time.
|
||||
|
||||
==== TermsQueryBuilder
|
||||
|
||||
Remove the setter for `termsLookup()`, making it only possible to either use a TermsLookUp object or
|
||||
individual values at constrution time. Also moving individual settings for the TermsLookUp (lookupIndex,
|
||||
lookupType, lookupId, lookupPath) to the separate TermsLookUp class, using construtor only and moving
|
||||
checks for validation there.
|
||||
|
||||
|
|
Loading…
Reference in New Issue