Adds ignore_unmapped option to geo queries
The change adds a new option to the geo_* queries: ignore_unmapped. If this option is set to false, the toQuery method on the QueryBuilder will throw an exception if the field specified in the query is unmapped. If the option is set to true, the toQuery method on the QueryBuilder will return a MatchNoDocsQuery. The default value is false so the queries work how they do today (throwing an exception on unmapped field)
This commit is contained in:
parent
18f8f3f67a
commit
c595322d90
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.query;
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.spatial.geopoint.document.GeoPointField;
|
import org.apache.lucene.spatial.geopoint.document.GeoPointField;
|
||||||
import org.apache.lucene.spatial.geopoint.search.GeoPointInBBoxQuery;
|
import org.apache.lucene.spatial.geopoint.search.GeoPointInBBoxQuery;
|
||||||
|
@ -58,6 +59,11 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding
|
||||||
/** Default type for executing this query (memory as of this writing). */
|
/** Default type for executing this query (memory as of this writing). */
|
||||||
public static final GeoExecType DEFAULT_TYPE = GeoExecType.MEMORY;
|
public static final GeoExecType DEFAULT_TYPE = GeoExecType.MEMORY;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default value for ignore_unmapped.
|
||||||
|
*/
|
||||||
|
public static final boolean DEFAULT_IGNORE_UNMAPPED = false;
|
||||||
|
|
||||||
private static final ParseField IGNORE_MALFORMED_FIELD = new ParseField("ignore_malformed");
|
private static final ParseField IGNORE_MALFORMED_FIELD = new ParseField("ignore_malformed");
|
||||||
private static final ParseField TYPE_FIELD = new ParseField("type");
|
private static final ParseField TYPE_FIELD = new ParseField("type");
|
||||||
private static final ParseField VALIDATION_METHOD_FIELD = new ParseField("validation_method");
|
private static final ParseField VALIDATION_METHOD_FIELD = new ParseField("validation_method");
|
||||||
|
@ -71,6 +77,7 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding
|
||||||
private static final ParseField BOTTOM_RIGHT_FIELD = new ParseField("bottom_right");
|
private static final ParseField BOTTOM_RIGHT_FIELD = new ParseField("bottom_right");
|
||||||
private static final ParseField TOP_RIGHT_FIELD = new ParseField("top_right");
|
private static final ParseField TOP_RIGHT_FIELD = new ParseField("top_right");
|
||||||
private static final ParseField BOTTOM_LEFT_FIELD = new ParseField("bottom_left");
|
private static final ParseField BOTTOM_LEFT_FIELD = new ParseField("bottom_left");
|
||||||
|
private static final ParseField IGNORE_UNMAPPED_FIELD = new ParseField("ignore_unmapped");
|
||||||
|
|
||||||
/** Name of field holding geo coordinates to compute the bounding box on.*/
|
/** Name of field holding geo coordinates to compute the bounding box on.*/
|
||||||
private final String fieldName;
|
private final String fieldName;
|
||||||
|
@ -83,6 +90,8 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding
|
||||||
/** How the query should be run. */
|
/** How the query should be run. */
|
||||||
private GeoExecType type = DEFAULT_TYPE;
|
private GeoExecType type = DEFAULT_TYPE;
|
||||||
|
|
||||||
|
private boolean ignoreUnmapped = DEFAULT_IGNORE_UNMAPPED;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new bounding box query.
|
* Create new bounding box query.
|
||||||
* @param fieldName name of index field containing geo coordinates to operate on.
|
* @param fieldName name of index field containing geo coordinates to operate on.
|
||||||
|
@ -104,6 +113,7 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding
|
||||||
bottomRight = in.readGeoPoint();
|
bottomRight = in.readGeoPoint();
|
||||||
type = GeoExecType.readFromStream(in);
|
type = GeoExecType.readFromStream(in);
|
||||||
validationMethod = GeoValidationMethod.readFromStream(in);
|
validationMethod = GeoValidationMethod.readFromStream(in);
|
||||||
|
ignoreUnmapped = in.readBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -113,6 +123,7 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding
|
||||||
out.writeGeoPoint(bottomRight);
|
out.writeGeoPoint(bottomRight);
|
||||||
type.writeTo(out);
|
type.writeTo(out);
|
||||||
validationMethod.writeTo(out);
|
validationMethod.writeTo(out);
|
||||||
|
out.writeBoolean(ignoreUnmapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -245,6 +256,25 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding
|
||||||
return this.fieldName;
|
return this.fieldName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the query builder should ignore unmapped fields (and run a
|
||||||
|
* {@link MatchNoDocsQuery} in place of this query) or throw an exception if
|
||||||
|
* the field is unmapped.
|
||||||
|
*/
|
||||||
|
public GeoBoundingBoxQueryBuilder ignoreUnmapped(boolean ignoreUnmapped) {
|
||||||
|
this.ignoreUnmapped = ignoreUnmapped;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the query builder will ignore unmapped fields (and run a
|
||||||
|
* {@link MatchNoDocsQuery} in place of this query) or throw an exception if
|
||||||
|
* the field is unmapped.
|
||||||
|
*/
|
||||||
|
public boolean ignoreUnmapped() {
|
||||||
|
return ignoreUnmapped;
|
||||||
|
}
|
||||||
|
|
||||||
QueryValidationException checkLatLon(boolean indexCreatedBeforeV2_0) {
|
QueryValidationException checkLatLon(boolean indexCreatedBeforeV2_0) {
|
||||||
// validation was not available prior to 2.x, so to support bwc percolation queries we only ignore_malformed on 2.x created indexes
|
// validation was not available prior to 2.x, so to support bwc percolation queries we only ignore_malformed on 2.x created indexes
|
||||||
if (GeoValidationMethod.isIgnoreMalformed(validationMethod) == true || indexCreatedBeforeV2_0) {
|
if (GeoValidationMethod.isIgnoreMalformed(validationMethod) == true || indexCreatedBeforeV2_0) {
|
||||||
|
@ -276,7 +306,11 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding
|
||||||
public Query doToQuery(QueryShardContext context) {
|
public Query doToQuery(QueryShardContext context) {
|
||||||
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
||||||
if (fieldType == null) {
|
if (fieldType == null) {
|
||||||
throw new QueryShardException(context, "failed to find geo_point field [" + fieldName + "]");
|
if (ignoreUnmapped) {
|
||||||
|
return new MatchNoDocsQuery();
|
||||||
|
} else {
|
||||||
|
throw new QueryShardException(context, "failed to find geo_point field [" + fieldName + "]");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!(fieldType instanceof BaseGeoPointFieldMapper.GeoPointFieldType)) {
|
if (!(fieldType instanceof BaseGeoPointFieldMapper.GeoPointFieldType)) {
|
||||||
throw new QueryShardException(context, "field [" + fieldName + "] is not a geo_point field");
|
throw new QueryShardException(context, "field [" + fieldName + "] is not a geo_point field");
|
||||||
|
@ -342,6 +376,7 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
builder.field(VALIDATION_METHOD_FIELD.getPreferredName(), validationMethod);
|
builder.field(VALIDATION_METHOD_FIELD.getPreferredName(), validationMethod);
|
||||||
builder.field(TYPE_FIELD.getPreferredName(), type);
|
builder.field(TYPE_FIELD.getPreferredName(), type);
|
||||||
|
builder.field(IGNORE_UNMAPPED_FIELD.getPreferredName(), ignoreUnmapped);
|
||||||
|
|
||||||
printBoostAndQueryName(builder);
|
printBoostAndQueryName(builder);
|
||||||
|
|
||||||
|
@ -365,6 +400,7 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding
|
||||||
boolean coerce = GeoValidationMethod.DEFAULT_LENIENT_PARSING;
|
boolean coerce = GeoValidationMethod.DEFAULT_LENIENT_PARSING;
|
||||||
boolean ignoreMalformed = GeoValidationMethod.DEFAULT_LENIENT_PARSING;
|
boolean ignoreMalformed = GeoValidationMethod.DEFAULT_LENIENT_PARSING;
|
||||||
GeoValidationMethod validationMethod = null;
|
GeoValidationMethod validationMethod = null;
|
||||||
|
boolean ignoreUnmapped = DEFAULT_IGNORE_UNMAPPED;
|
||||||
|
|
||||||
GeoPoint sparse = new GeoPoint();
|
GeoPoint sparse = new GeoPoint();
|
||||||
|
|
||||||
|
@ -431,6 +467,8 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding
|
||||||
}
|
}
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, VALIDATION_METHOD_FIELD)) {
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, VALIDATION_METHOD_FIELD)) {
|
||||||
validationMethod = GeoValidationMethod.fromString(parser.text());
|
validationMethod = GeoValidationMethod.fromString(parser.text());
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, IGNORE_UNMAPPED_FIELD)) {
|
||||||
|
ignoreUnmapped = parser.booleanValue();
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, TYPE_FIELD)) {
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, TYPE_FIELD)) {
|
||||||
type = parser.text();
|
type = parser.text();
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, IGNORE_MALFORMED_FIELD)) {
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, IGNORE_MALFORMED_FIELD)) {
|
||||||
|
@ -449,6 +487,7 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding
|
||||||
builder.queryName(queryName);
|
builder.queryName(queryName);
|
||||||
builder.boost(boost);
|
builder.boost(boost);
|
||||||
builder.type(GeoExecType.fromString(type));
|
builder.type(GeoExecType.fromString(type));
|
||||||
|
builder.ignoreUnmapped(ignoreUnmapped);
|
||||||
if (validationMethod != null) {
|
if (validationMethod != null) {
|
||||||
// ignore deprecated coerce/ignoreMalformed settings if validationMethod is set
|
// ignore deprecated coerce/ignoreMalformed settings if validationMethod is set
|
||||||
builder.setValidationMethod(validationMethod);
|
builder.setValidationMethod(validationMethod);
|
||||||
|
@ -464,12 +503,13 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding
|
||||||
Objects.equals(bottomRight, other.bottomRight) &&
|
Objects.equals(bottomRight, other.bottomRight) &&
|
||||||
Objects.equals(type, other.type) &&
|
Objects.equals(type, other.type) &&
|
||||||
Objects.equals(validationMethod, other.validationMethod) &&
|
Objects.equals(validationMethod, other.validationMethod) &&
|
||||||
Objects.equals(fieldName, other.fieldName);
|
Objects.equals(fieldName, other.fieldName) &&
|
||||||
|
Objects.equals(ignoreUnmapped, other.ignoreUnmapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int doHashCode() {
|
protected int doHashCode() {
|
||||||
return Objects.hash(topLeft, bottomRight, type, validationMethod, fieldName);
|
return Objects.hash(topLeft, bottomRight, type, validationMethod, fieldName, ignoreUnmapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.query;
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.spatial.geopoint.document.GeoPointField;
|
import org.apache.lucene.spatial.geopoint.document.GeoPointField;
|
||||||
import org.apache.lucene.spatial.geopoint.search.GeoPointDistanceQuery;
|
import org.apache.lucene.spatial.geopoint.search.GeoPointDistanceQuery;
|
||||||
|
@ -66,6 +67,11 @@ public class GeoDistanceQueryBuilder extends AbstractQueryBuilder<GeoDistanceQue
|
||||||
/** Default for optimising query through pre computed bounding box query. */
|
/** Default for optimising query through pre computed bounding box query. */
|
||||||
public static final String DEFAULT_OPTIMIZE_BBOX = "memory";
|
public static final String DEFAULT_OPTIMIZE_BBOX = "memory";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default value for ignore_unmapped.
|
||||||
|
*/
|
||||||
|
public static final boolean DEFAULT_IGNORE_UNMAPPED = false;
|
||||||
|
|
||||||
private static final ParseField VALIDATION_METHOD_FIELD = new ParseField("validation_method");
|
private static final ParseField VALIDATION_METHOD_FIELD = new ParseField("validation_method");
|
||||||
private static final ParseField IGNORE_MALFORMED_FIELD = new ParseField("ignore_malformed");
|
private static final ParseField IGNORE_MALFORMED_FIELD = new ParseField("ignore_malformed");
|
||||||
private static final ParseField COERCE_FIELD = new ParseField("coerce", "normalize");
|
private static final ParseField COERCE_FIELD = new ParseField("coerce", "normalize");
|
||||||
|
@ -73,6 +79,7 @@ public class GeoDistanceQueryBuilder extends AbstractQueryBuilder<GeoDistanceQue
|
||||||
private static final ParseField DISTANCE_TYPE_FIELD = new ParseField("distance_type");
|
private static final ParseField DISTANCE_TYPE_FIELD = new ParseField("distance_type");
|
||||||
private static final ParseField UNIT_FIELD = new ParseField("unit");
|
private static final ParseField UNIT_FIELD = new ParseField("unit");
|
||||||
private static final ParseField DISTANCE_FIELD = new ParseField("distance");
|
private static final ParseField DISTANCE_FIELD = new ParseField("distance");
|
||||||
|
private static final ParseField IGNORE_UNMAPPED_FIELD = new ParseField("ignore_unmapped");
|
||||||
|
|
||||||
private final String fieldName;
|
private final String fieldName;
|
||||||
/** Distance from center to cover. */
|
/** Distance from center to cover. */
|
||||||
|
@ -86,6 +93,8 @@ public class GeoDistanceQueryBuilder extends AbstractQueryBuilder<GeoDistanceQue
|
||||||
/** How strict should geo coordinate validation be? */
|
/** How strict should geo coordinate validation be? */
|
||||||
private GeoValidationMethod validationMethod = GeoValidationMethod.DEFAULT;
|
private GeoValidationMethod validationMethod = GeoValidationMethod.DEFAULT;
|
||||||
|
|
||||||
|
private boolean ignoreUnmapped = DEFAULT_IGNORE_UNMAPPED;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct new GeoDistanceQueryBuilder.
|
* Construct new GeoDistanceQueryBuilder.
|
||||||
* @param fieldName name of indexed geo field to operate distance computation on.
|
* @param fieldName name of indexed geo field to operate distance computation on.
|
||||||
|
@ -108,6 +117,7 @@ public class GeoDistanceQueryBuilder extends AbstractQueryBuilder<GeoDistanceQue
|
||||||
center = in.readGeoPoint();
|
center = in.readGeoPoint();
|
||||||
optimizeBbox = in.readString();
|
optimizeBbox = in.readString();
|
||||||
geoDistance = GeoDistance.readFromStream(in);
|
geoDistance = GeoDistance.readFromStream(in);
|
||||||
|
ignoreUnmapped = in.readBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -118,6 +128,7 @@ public class GeoDistanceQueryBuilder extends AbstractQueryBuilder<GeoDistanceQue
|
||||||
out.writeGeoPoint(center);
|
out.writeGeoPoint(center);
|
||||||
out.writeString(optimizeBbox);
|
out.writeString(optimizeBbox);
|
||||||
geoDistance.writeTo(out);
|
geoDistance.writeTo(out);
|
||||||
|
out.writeBoolean(ignoreUnmapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Name of the field this query is operating on. */
|
/** Name of the field this query is operating on. */
|
||||||
|
@ -243,11 +254,34 @@ public class GeoDistanceQueryBuilder extends AbstractQueryBuilder<GeoDistanceQue
|
||||||
return this.validationMethod;
|
return this.validationMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the query builder should ignore unmapped fields (and run a
|
||||||
|
* {@link MatchNoDocsQuery} in place of this query) or throw an exception if
|
||||||
|
* the field is unmapped.
|
||||||
|
*/
|
||||||
|
public GeoDistanceQueryBuilder ignoreUnmapped(boolean ignoreUnmapped) {
|
||||||
|
this.ignoreUnmapped = ignoreUnmapped;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the query builder will ignore unmapped fields (and run a
|
||||||
|
* {@link MatchNoDocsQuery} in place of this query) or throw an exception if
|
||||||
|
* the field is unmapped.
|
||||||
|
*/
|
||||||
|
public boolean ignoreUnmapped() {
|
||||||
|
return ignoreUnmapped;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Query doToQuery(QueryShardContext shardContext) throws IOException {
|
protected Query doToQuery(QueryShardContext shardContext) throws IOException {
|
||||||
MappedFieldType fieldType = shardContext.fieldMapper(fieldName);
|
MappedFieldType fieldType = shardContext.fieldMapper(fieldName);
|
||||||
if (fieldType == null) {
|
if (fieldType == null) {
|
||||||
throw new QueryShardException(shardContext, "failed to find geo_point field [" + fieldName + "]");
|
if (ignoreUnmapped) {
|
||||||
|
return new MatchNoDocsQuery();
|
||||||
|
} else {
|
||||||
|
throw new QueryShardException(shardContext, "failed to find geo_point field [" + fieldName + "]");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(fieldType instanceof BaseGeoPointFieldMapper.GeoPointFieldType)) {
|
if (!(fieldType instanceof BaseGeoPointFieldMapper.GeoPointFieldType)) {
|
||||||
|
@ -289,6 +323,7 @@ public class GeoDistanceQueryBuilder extends AbstractQueryBuilder<GeoDistanceQue
|
||||||
builder.field(DISTANCE_TYPE_FIELD.getPreferredName(), geoDistance.name().toLowerCase(Locale.ROOT));
|
builder.field(DISTANCE_TYPE_FIELD.getPreferredName(), geoDistance.name().toLowerCase(Locale.ROOT));
|
||||||
builder.field(OPTIMIZE_BBOX_FIELD.getPreferredName(), optimizeBbox);
|
builder.field(OPTIMIZE_BBOX_FIELD.getPreferredName(), optimizeBbox);
|
||||||
builder.field(VALIDATION_METHOD_FIELD.getPreferredName(), validationMethod);
|
builder.field(VALIDATION_METHOD_FIELD.getPreferredName(), validationMethod);
|
||||||
|
builder.field(IGNORE_UNMAPPED_FIELD.getPreferredName(), ignoreUnmapped);
|
||||||
printBoostAndQueryName(builder);
|
printBoostAndQueryName(builder);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
|
@ -310,6 +345,7 @@ public class GeoDistanceQueryBuilder extends AbstractQueryBuilder<GeoDistanceQue
|
||||||
boolean coerce = GeoValidationMethod.DEFAULT_LENIENT_PARSING;
|
boolean coerce = GeoValidationMethod.DEFAULT_LENIENT_PARSING;
|
||||||
boolean ignoreMalformed = GeoValidationMethod.DEFAULT_LENIENT_PARSING;
|
boolean ignoreMalformed = GeoValidationMethod.DEFAULT_LENIENT_PARSING;
|
||||||
GeoValidationMethod validationMethod = null;
|
GeoValidationMethod validationMethod = null;
|
||||||
|
boolean ignoreUnmapped = DEFAULT_IGNORE_UNMAPPED;
|
||||||
|
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||||
if (token == XContentParser.Token.FIELD_NAME) {
|
if (token == XContentParser.Token.FIELD_NAME) {
|
||||||
|
@ -370,6 +406,8 @@ public class GeoDistanceQueryBuilder extends AbstractQueryBuilder<GeoDistanceQue
|
||||||
}
|
}
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, IGNORE_MALFORMED_FIELD)) {
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, IGNORE_MALFORMED_FIELD)) {
|
||||||
ignoreMalformed = parser.booleanValue();
|
ignoreMalformed = parser.booleanValue();
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, IGNORE_UNMAPPED_FIELD)) {
|
||||||
|
ignoreUnmapped = parser.booleanValue();
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, VALIDATION_METHOD_FIELD)) {
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, VALIDATION_METHOD_FIELD)) {
|
||||||
validationMethod = GeoValidationMethod.fromString(parser.text());
|
validationMethod = GeoValidationMethod.fromString(parser.text());
|
||||||
} else {
|
} else {
|
||||||
|
@ -404,12 +442,13 @@ public class GeoDistanceQueryBuilder extends AbstractQueryBuilder<GeoDistanceQue
|
||||||
qb.geoDistance(geoDistance);
|
qb.geoDistance(geoDistance);
|
||||||
qb.boost(boost);
|
qb.boost(boost);
|
||||||
qb.queryName(queryName);
|
qb.queryName(queryName);
|
||||||
|
qb.ignoreUnmapped(ignoreUnmapped);
|
||||||
return qb;
|
return qb;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int doHashCode() {
|
protected int doHashCode() {
|
||||||
return Objects.hash(center, geoDistance, optimizeBbox, distance, validationMethod);
|
return Objects.hash(center, geoDistance, optimizeBbox, distance, validationMethod, ignoreUnmapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -419,7 +458,8 @@ public class GeoDistanceQueryBuilder extends AbstractQueryBuilder<GeoDistanceQue
|
||||||
Objects.equals(validationMethod, other.validationMethod) &&
|
Objects.equals(validationMethod, other.validationMethod) &&
|
||||||
Objects.equals(center, other.center) &&
|
Objects.equals(center, other.center) &&
|
||||||
Objects.equals(optimizeBbox, other.optimizeBbox) &&
|
Objects.equals(optimizeBbox, other.optimizeBbox) &&
|
||||||
Objects.equals(geoDistance, other.geoDistance);
|
Objects.equals(geoDistance, other.geoDistance) &&
|
||||||
|
Objects.equals(ignoreUnmapped, other.ignoreUnmapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
private QueryValidationException checkLatLon(boolean indexCreatedBeforeV2_0) {
|
private QueryValidationException checkLatLon(boolean indexCreatedBeforeV2_0) {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.query;
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.spatial.geopoint.document.GeoPointField;
|
import org.apache.lucene.spatial.geopoint.document.GeoPointField;
|
||||||
import org.apache.lucene.spatial.geopoint.search.XGeoPointDistanceRangeQuery;
|
import org.apache.lucene.spatial.geopoint.search.XGeoPointDistanceRangeQuery;
|
||||||
|
@ -59,6 +60,11 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
||||||
public static final DistanceUnit DEFAULT_UNIT = DistanceUnit.DEFAULT;
|
public static final DistanceUnit DEFAULT_UNIT = DistanceUnit.DEFAULT;
|
||||||
public static final String DEFAULT_OPTIMIZE_BBOX = "memory";
|
public static final String DEFAULT_OPTIMIZE_BBOX = "memory";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default value for ignore_unmapped.
|
||||||
|
*/
|
||||||
|
public static final boolean DEFAULT_IGNORE_UNMAPPED = false;
|
||||||
|
|
||||||
private static final ParseField FROM_FIELD = new ParseField("from");
|
private static final ParseField FROM_FIELD = new ParseField("from");
|
||||||
private static final ParseField TO_FIELD = new ParseField("to");
|
private static final ParseField TO_FIELD = new ParseField("to");
|
||||||
private static final ParseField INCLUDE_LOWER_FIELD = new ParseField("include_lower");
|
private static final ParseField INCLUDE_LOWER_FIELD = new ParseField("include_lower");
|
||||||
|
@ -75,6 +81,7 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
||||||
private static final ParseField COERCE_FIELD = new ParseField("coerce", "normalize");
|
private static final ParseField COERCE_FIELD = new ParseField("coerce", "normalize");
|
||||||
private static final ParseField IGNORE_MALFORMED_FIELD = new ParseField("ignore_malformed");
|
private static final ParseField IGNORE_MALFORMED_FIELD = new ParseField("ignore_malformed");
|
||||||
private static final ParseField VALIDATION_METHOD = new ParseField("validation_method");
|
private static final ParseField VALIDATION_METHOD = new ParseField("validation_method");
|
||||||
|
private static final ParseField IGNORE_UNMAPPED_FIELD = new ParseField("ignore_unmapped");
|
||||||
|
|
||||||
private final String fieldName;
|
private final String fieldName;
|
||||||
|
|
||||||
|
@ -83,6 +90,8 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
||||||
private boolean includeLower = DEFAULT_INCLUDE_LOWER;
|
private boolean includeLower = DEFAULT_INCLUDE_LOWER;
|
||||||
private boolean includeUpper = DEFAULT_INCLUDE_UPPER;
|
private boolean includeUpper = DEFAULT_INCLUDE_UPPER;
|
||||||
|
|
||||||
|
private boolean ignoreUnmapped = DEFAULT_IGNORE_UNMAPPED;
|
||||||
|
|
||||||
private final GeoPoint point;
|
private final GeoPoint point;
|
||||||
|
|
||||||
private GeoDistance geoDistance = DEFAULT_GEO_DISTANCE;
|
private GeoDistance geoDistance = DEFAULT_GEO_DISTANCE;
|
||||||
|
@ -127,6 +136,7 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
||||||
geoDistance = GeoDistance.readFromStream(in);
|
geoDistance = GeoDistance.readFromStream(in);
|
||||||
optimizeBbox = in.readString();
|
optimizeBbox = in.readString();
|
||||||
validationMethod = GeoValidationMethod.readFromStream(in);
|
validationMethod = GeoValidationMethod.readFromStream(in);
|
||||||
|
ignoreUnmapped = in.readBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -141,6 +151,7 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
||||||
geoDistance.writeTo(out);;
|
geoDistance.writeTo(out);;
|
||||||
out.writeString(optimizeBbox);
|
out.writeString(optimizeBbox);
|
||||||
validationMethod.writeTo(out);
|
validationMethod.writeTo(out);
|
||||||
|
out.writeBoolean(ignoreUnmapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String fieldName() {
|
public String fieldName() {
|
||||||
|
@ -264,11 +275,34 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
||||||
return this.validationMethod;
|
return this.validationMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the query builder should ignore unmapped fields (and run a
|
||||||
|
* {@link MatchNoDocsQuery} in place of this query) or throw an exception if
|
||||||
|
* the field is unmapped.
|
||||||
|
*/
|
||||||
|
public GeoDistanceRangeQueryBuilder ignoreUnmapped(boolean ignoreUnmapped) {
|
||||||
|
this.ignoreUnmapped = ignoreUnmapped;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the query builder will ignore unmapped fields (and run a
|
||||||
|
* {@link MatchNoDocsQuery} in place of this query) or throw an exception if
|
||||||
|
* the field is unmapped.
|
||||||
|
*/
|
||||||
|
public boolean ignoreUnmapped() {
|
||||||
|
return ignoreUnmapped;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Query doToQuery(QueryShardContext context) throws IOException {
|
protected Query doToQuery(QueryShardContext context) throws IOException {
|
||||||
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
||||||
if (fieldType == null) {
|
if (fieldType == null) {
|
||||||
throw new QueryShardException(context, "failed to find geo_point field [" + fieldName + "]");
|
if (ignoreUnmapped) {
|
||||||
|
return new MatchNoDocsQuery();
|
||||||
|
} else {
|
||||||
|
throw new QueryShardException(context, "failed to find geo_point field [" + fieldName + "]");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!(fieldType instanceof BaseGeoPointFieldMapper.GeoPointFieldType)) {
|
if (!(fieldType instanceof BaseGeoPointFieldMapper.GeoPointFieldType)) {
|
||||||
throw new QueryShardException(context, "field [" + fieldName + "] is not a geo_point field");
|
throw new QueryShardException(context, "field [" + fieldName + "] is not a geo_point field");
|
||||||
|
@ -350,6 +384,7 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
||||||
builder.field(DISTANCE_TYPE_FIELD.getPreferredName(), geoDistance.name().toLowerCase(Locale.ROOT));
|
builder.field(DISTANCE_TYPE_FIELD.getPreferredName(), geoDistance.name().toLowerCase(Locale.ROOT));
|
||||||
builder.field(OPTIMIZE_BBOX_FIELD.getPreferredName(), optimizeBbox);
|
builder.field(OPTIMIZE_BBOX_FIELD.getPreferredName(), optimizeBbox);
|
||||||
builder.field(VALIDATION_METHOD.getPreferredName(), validationMethod);
|
builder.field(VALIDATION_METHOD.getPreferredName(), validationMethod);
|
||||||
|
builder.field(IGNORE_UNMAPPED_FIELD.getPreferredName(), ignoreUnmapped);
|
||||||
printBoostAndQueryName(builder);
|
printBoostAndQueryName(builder);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
|
@ -374,6 +409,7 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
||||||
boolean coerce = GeoValidationMethod.DEFAULT_LENIENT_PARSING;
|
boolean coerce = GeoValidationMethod.DEFAULT_LENIENT_PARSING;
|
||||||
boolean ignoreMalformed = GeoValidationMethod.DEFAULT_LENIENT_PARSING;
|
boolean ignoreMalformed = GeoValidationMethod.DEFAULT_LENIENT_PARSING;
|
||||||
GeoValidationMethod validationMethod = null;
|
GeoValidationMethod validationMethod = null;
|
||||||
|
boolean ignoreUnmapped = DEFAULT_IGNORE_UNMAPPED;
|
||||||
|
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||||
if (token == XContentParser.Token.FIELD_NAME) {
|
if (token == XContentParser.Token.FIELD_NAME) {
|
||||||
|
@ -422,6 +458,8 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
||||||
includeLower = parser.booleanValue();
|
includeLower = parser.booleanValue();
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, INCLUDE_UPPER_FIELD)) {
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, INCLUDE_UPPER_FIELD)) {
|
||||||
includeUpper = parser.booleanValue();
|
includeUpper = parser.booleanValue();
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, IGNORE_UNMAPPED_FIELD)) {
|
||||||
|
ignoreUnmapped = parser.booleanValue();
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, GT_FIELD)) {
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, GT_FIELD)) {
|
||||||
if (token == XContentParser.Token.VALUE_NULL) {
|
if (token == XContentParser.Token.VALUE_NULL) {
|
||||||
} else if (token == XContentParser.Token.VALUE_STRING) {
|
} else if (token == XContentParser.Token.VALUE_STRING) {
|
||||||
|
@ -562,6 +600,7 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
||||||
} else {
|
} else {
|
||||||
queryBuilder.setValidationMethod(GeoValidationMethod.infer(coerce, ignoreMalformed));
|
queryBuilder.setValidationMethod(GeoValidationMethod.infer(coerce, ignoreMalformed));
|
||||||
}
|
}
|
||||||
|
queryBuilder.ignoreUnmapped(ignoreUnmapped);
|
||||||
return queryBuilder;
|
return queryBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,12 +614,14 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan
|
||||||
(Objects.equals(includeLower, other.includeLower)) &&
|
(Objects.equals(includeLower, other.includeLower)) &&
|
||||||
(Objects.equals(geoDistance, other.geoDistance)) &&
|
(Objects.equals(geoDistance, other.geoDistance)) &&
|
||||||
(Objects.equals(optimizeBbox, other.optimizeBbox)) &&
|
(Objects.equals(optimizeBbox, other.optimizeBbox)) &&
|
||||||
(Objects.equals(validationMethod, other.validationMethod)));
|
(Objects.equals(validationMethod, other.validationMethod))) &&
|
||||||
|
Objects.equals(ignoreUnmapped, other.ignoreUnmapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int doHashCode() {
|
protected int doHashCode() {
|
||||||
return Objects.hash(fieldName, point, from, to, includeUpper, includeLower, geoDistance, optimizeBbox, validationMethod);
|
return Objects.hash(fieldName, point, from, to, includeUpper, includeLower, geoDistance, optimizeBbox, validationMethod,
|
||||||
|
ignoreUnmapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.query;
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.spatial.geopoint.document.GeoPointField;
|
import org.apache.lucene.spatial.geopoint.document.GeoPointField;
|
||||||
import org.apache.lucene.spatial.geopoint.search.GeoPointInPolygonQuery;
|
import org.apache.lucene.spatial.geopoint.search.GeoPointInPolygonQuery;
|
||||||
|
@ -48,10 +49,16 @@ public class GeoPolygonQueryBuilder extends AbstractQueryBuilder<GeoPolygonQuery
|
||||||
public static final String NAME = "geo_polygon";
|
public static final String NAME = "geo_polygon";
|
||||||
public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME);
|
public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default value for ignore_unmapped.
|
||||||
|
*/
|
||||||
|
public static final boolean DEFAULT_IGNORE_UNMAPPED = false;
|
||||||
|
|
||||||
private static final ParseField COERCE_FIELD = new ParseField("coerce", "normalize");
|
private static final ParseField COERCE_FIELD = new ParseField("coerce", "normalize");
|
||||||
private static final ParseField IGNORE_MALFORMED_FIELD = new ParseField("ignore_malformed");
|
private static final ParseField IGNORE_MALFORMED_FIELD = new ParseField("ignore_malformed");
|
||||||
private static final ParseField VALIDATION_METHOD = new ParseField("validation_method");
|
private static final ParseField VALIDATION_METHOD = new ParseField("validation_method");
|
||||||
private static final ParseField POINTS_FIELD = new ParseField("points");
|
private static final ParseField POINTS_FIELD = new ParseField("points");
|
||||||
|
private static final ParseField IGNORE_UNMAPPED_FIELD = new ParseField("ignore_unmapped");
|
||||||
|
|
||||||
private final String fieldName;
|
private final String fieldName;
|
||||||
|
|
||||||
|
@ -59,6 +66,8 @@ public class GeoPolygonQueryBuilder extends AbstractQueryBuilder<GeoPolygonQuery
|
||||||
|
|
||||||
private GeoValidationMethod validationMethod = GeoValidationMethod.DEFAULT;
|
private GeoValidationMethod validationMethod = GeoValidationMethod.DEFAULT;
|
||||||
|
|
||||||
|
private boolean ignoreUnmapped = DEFAULT_IGNORE_UNMAPPED;
|
||||||
|
|
||||||
public GeoPolygonQueryBuilder(String fieldName, List<GeoPoint> points) {
|
public GeoPolygonQueryBuilder(String fieldName, List<GeoPoint> points) {
|
||||||
if (Strings.isEmpty(fieldName)) {
|
if (Strings.isEmpty(fieldName)) {
|
||||||
throw new IllegalArgumentException("fieldName must not be null");
|
throw new IllegalArgumentException("fieldName must not be null");
|
||||||
|
@ -96,6 +105,7 @@ public class GeoPolygonQueryBuilder extends AbstractQueryBuilder<GeoPolygonQuery
|
||||||
shell.add(in.readGeoPoint());
|
shell.add(in.readGeoPoint());
|
||||||
}
|
}
|
||||||
validationMethod = GeoValidationMethod.readFromStream(in);
|
validationMethod = GeoValidationMethod.readFromStream(in);
|
||||||
|
ignoreUnmapped = in.readBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -106,6 +116,7 @@ public class GeoPolygonQueryBuilder extends AbstractQueryBuilder<GeoPolygonQuery
|
||||||
out.writeGeoPoint(point);
|
out.writeGeoPoint(point);
|
||||||
}
|
}
|
||||||
validationMethod.writeTo(out);
|
validationMethod.writeTo(out);
|
||||||
|
out.writeBoolean(ignoreUnmapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String fieldName() {
|
public String fieldName() {
|
||||||
|
@ -127,11 +138,34 @@ public class GeoPolygonQueryBuilder extends AbstractQueryBuilder<GeoPolygonQuery
|
||||||
return this.validationMethod;
|
return this.validationMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the query builder should ignore unmapped fields (and run a
|
||||||
|
* {@link MatchNoDocsQuery} in place of this query) or throw an exception if
|
||||||
|
* the field is unmapped.
|
||||||
|
*/
|
||||||
|
public GeoPolygonQueryBuilder ignoreUnmapped(boolean ignoreUnmapped) {
|
||||||
|
this.ignoreUnmapped = ignoreUnmapped;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the query builder will ignore unmapped fields (and run a
|
||||||
|
* {@link MatchNoDocsQuery} in place of this query) or throw an exception if
|
||||||
|
* the field is unmapped.
|
||||||
|
*/
|
||||||
|
public boolean ignoreUnmapped() {
|
||||||
|
return ignoreUnmapped;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Query doToQuery(QueryShardContext context) throws IOException {
|
protected Query doToQuery(QueryShardContext context) throws IOException {
|
||||||
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
||||||
if (fieldType == null) {
|
if (fieldType == null) {
|
||||||
throw new QueryShardException(context, "failed to find geo_point field [" + fieldName + "]");
|
if (ignoreUnmapped) {
|
||||||
|
return new MatchNoDocsQuery();
|
||||||
|
} else {
|
||||||
|
throw new QueryShardException(context, "failed to find geo_point field [" + fieldName + "]");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!(fieldType instanceof BaseGeoPointFieldMapper.GeoPointFieldType)) {
|
if (!(fieldType instanceof BaseGeoPointFieldMapper.GeoPointFieldType)) {
|
||||||
throw new QueryShardException(context, "field [" + fieldName + "] is not a geo_point field");
|
throw new QueryShardException(context, "field [" + fieldName + "] is not a geo_point field");
|
||||||
|
@ -201,6 +235,7 @@ public class GeoPolygonQueryBuilder extends AbstractQueryBuilder<GeoPolygonQuery
|
||||||
builder.field(COERCE_FIELD.getPreferredName(), GeoValidationMethod.isCoerce(validationMethod));
|
builder.field(COERCE_FIELD.getPreferredName(), GeoValidationMethod.isCoerce(validationMethod));
|
||||||
builder.field(IGNORE_MALFORMED_FIELD.getPreferredName(),
|
builder.field(IGNORE_MALFORMED_FIELD.getPreferredName(),
|
||||||
GeoValidationMethod.isIgnoreMalformed(validationMethod));
|
GeoValidationMethod.isIgnoreMalformed(validationMethod));
|
||||||
|
builder.field(IGNORE_UNMAPPED_FIELD.getPreferredName(), ignoreUnmapped);
|
||||||
|
|
||||||
printBoostAndQueryName(builder);
|
printBoostAndQueryName(builder);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
|
@ -220,6 +255,7 @@ public class GeoPolygonQueryBuilder extends AbstractQueryBuilder<GeoPolygonQuery
|
||||||
String queryName = null;
|
String queryName = null;
|
||||||
String currentFieldName = null;
|
String currentFieldName = null;
|
||||||
XContentParser.Token token;
|
XContentParser.Token token;
|
||||||
|
boolean ignoreUnmapped = DEFAULT_IGNORE_UNMAPPED;
|
||||||
|
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||||
if (token == XContentParser.Token.FIELD_NAME) {
|
if (token == XContentParser.Token.FIELD_NAME) {
|
||||||
|
@ -257,6 +293,8 @@ public class GeoPolygonQueryBuilder extends AbstractQueryBuilder<GeoPolygonQuery
|
||||||
if (coerce) {
|
if (coerce) {
|
||||||
ignoreMalformed = true;
|
ignoreMalformed = true;
|
||||||
}
|
}
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, IGNORE_UNMAPPED_FIELD)) {
|
||||||
|
ignoreUnmapped = parser.booleanValue();
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, IGNORE_MALFORMED_FIELD)) {
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, IGNORE_MALFORMED_FIELD)) {
|
||||||
ignoreMalformed = parser.booleanValue();
|
ignoreMalformed = parser.booleanValue();
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, VALIDATION_METHOD)) {
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, VALIDATION_METHOD)) {
|
||||||
|
@ -283,6 +321,7 @@ public class GeoPolygonQueryBuilder extends AbstractQueryBuilder<GeoPolygonQuery
|
||||||
if (boost != null) {
|
if (boost != null) {
|
||||||
builder.boost(boost);
|
builder.boost(boost);
|
||||||
}
|
}
|
||||||
|
builder.ignoreUnmapped(ignoreUnmapped);
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,12 +329,13 @@ public class GeoPolygonQueryBuilder extends AbstractQueryBuilder<GeoPolygonQuery
|
||||||
protected boolean doEquals(GeoPolygonQueryBuilder other) {
|
protected boolean doEquals(GeoPolygonQueryBuilder other) {
|
||||||
return Objects.equals(validationMethod, other.validationMethod)
|
return Objects.equals(validationMethod, other.validationMethod)
|
||||||
&& Objects.equals(fieldName, other.fieldName)
|
&& Objects.equals(fieldName, other.fieldName)
|
||||||
&& Objects.equals(shell, other.shell);
|
&& Objects.equals(shell, other.shell)
|
||||||
|
&& Objects.equals(ignoreUnmapped, other.ignoreUnmapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int doHashCode() {
|
protected int doHashCode() {
|
||||||
return Objects.hash(validationMethod, fieldName, shell);
|
return Objects.hash(validationMethod, fieldName, shell, ignoreUnmapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -22,6 +22,7 @@ package org.elasticsearch.index.query;
|
||||||
import org.apache.lucene.search.BooleanClause;
|
import org.apache.lucene.search.BooleanClause;
|
||||||
import org.apache.lucene.search.BooleanQuery;
|
import org.apache.lucene.search.BooleanQuery;
|
||||||
import org.apache.lucene.search.ConstantScoreQuery;
|
import org.apache.lucene.search.ConstantScoreQuery;
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.spatial.prefix.PrefixTreeStrategy;
|
import org.apache.lucene.spatial.prefix.PrefixTreeStrategy;
|
||||||
import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
|
import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
|
||||||
|
@ -60,6 +61,11 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
|
||||||
public static final String DEFAULT_SHAPE_FIELD_NAME = "shape";
|
public static final String DEFAULT_SHAPE_FIELD_NAME = "shape";
|
||||||
public static final ShapeRelation DEFAULT_SHAPE_RELATION = ShapeRelation.INTERSECTS;
|
public static final ShapeRelation DEFAULT_SHAPE_RELATION = ShapeRelation.INTERSECTS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default value for ignore_unmapped.
|
||||||
|
*/
|
||||||
|
public static final boolean DEFAULT_IGNORE_UNMAPPED = false;
|
||||||
|
|
||||||
private static final ParseField SHAPE_FIELD = new ParseField("shape");
|
private static final ParseField SHAPE_FIELD = new ParseField("shape");
|
||||||
private static final ParseField STRATEGY_FIELD = new ParseField("strategy");
|
private static final ParseField STRATEGY_FIELD = new ParseField("strategy");
|
||||||
private static final ParseField RELATION_FIELD = new ParseField("relation");
|
private static final ParseField RELATION_FIELD = new ParseField("relation");
|
||||||
|
@ -68,6 +74,7 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
|
||||||
private static final ParseField SHAPE_TYPE_FIELD = new ParseField("type");
|
private static final ParseField SHAPE_TYPE_FIELD = new ParseField("type");
|
||||||
private static final ParseField SHAPE_INDEX_FIELD = new ParseField("index");
|
private static final ParseField SHAPE_INDEX_FIELD = new ParseField("index");
|
||||||
private static final ParseField SHAPE_PATH_FIELD = new ParseField("path");
|
private static final ParseField SHAPE_PATH_FIELD = new ParseField("path");
|
||||||
|
private static final ParseField IGNORE_UNMAPPED_FIELD = new ParseField("ignore_unmapped");
|
||||||
|
|
||||||
private final String fieldName;
|
private final String fieldName;
|
||||||
|
|
||||||
|
@ -83,6 +90,8 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
|
||||||
|
|
||||||
private ShapeRelation relation = DEFAULT_SHAPE_RELATION;
|
private ShapeRelation relation = DEFAULT_SHAPE_RELATION;
|
||||||
|
|
||||||
|
private boolean ignoreUnmapped = DEFAULT_IGNORE_UNMAPPED;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new GeoShapeQueryBuilder whose Query will be against the given
|
* Creates a new GeoShapeQueryBuilder whose Query will be against the given
|
||||||
* field name using the given Shape
|
* field name using the given Shape
|
||||||
|
@ -147,6 +156,7 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
|
||||||
}
|
}
|
||||||
relation = ShapeRelation.DISJOINT.readFrom(in);
|
relation = ShapeRelation.DISJOINT.readFrom(in);
|
||||||
strategy = in.readOptionalWriteable(SpatialStrategy.RECURSIVE::readFrom);
|
strategy = in.readOptionalWriteable(SpatialStrategy.RECURSIVE::readFrom);
|
||||||
|
ignoreUnmapped = in.readBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -164,6 +174,7 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
|
||||||
}
|
}
|
||||||
relation.writeTo(out);
|
relation.writeTo(out);
|
||||||
out.writeOptionalWriteable(strategy);
|
out.writeOptionalWriteable(strategy);
|
||||||
|
out.writeBoolean(ignoreUnmapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -282,6 +293,25 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
|
||||||
return relation;
|
return relation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the query builder should ignore unmapped fields (and run a
|
||||||
|
* {@link MatchNoDocsQuery} in place of this query) or throw an exception if
|
||||||
|
* the field is unmapped.
|
||||||
|
*/
|
||||||
|
public GeoShapeQueryBuilder ignoreUnmapped(boolean ignoreUnmapped) {
|
||||||
|
this.ignoreUnmapped = ignoreUnmapped;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the query builder will ignore unmapped fields (and run a
|
||||||
|
* {@link MatchNoDocsQuery} in place of this query) or throw an exception if
|
||||||
|
* the field is unmapped.
|
||||||
|
*/
|
||||||
|
public boolean ignoreUnmapped() {
|
||||||
|
return ignoreUnmapped;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Query doToQuery(QueryShardContext context) {
|
protected Query doToQuery(QueryShardContext context) {
|
||||||
if (shape == null) {
|
if (shape == null) {
|
||||||
|
@ -290,7 +320,11 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
|
||||||
final ShapeBuilder shapeToQuery = shape;
|
final ShapeBuilder shapeToQuery = shape;
|
||||||
final MappedFieldType fieldType = context.fieldMapper(fieldName);
|
final MappedFieldType fieldType = context.fieldMapper(fieldName);
|
||||||
if (fieldType == null) {
|
if (fieldType == null) {
|
||||||
throw new QueryShardException(context, "Failed to find geo_shape field [" + fieldName + "]");
|
if (ignoreUnmapped) {
|
||||||
|
return new MatchNoDocsQuery();
|
||||||
|
} else {
|
||||||
|
throw new QueryShardException(context, "failed to find geo_shape field [" + fieldName + "]");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This isn't the nicest way to check this
|
// TODO: This isn't the nicest way to check this
|
||||||
|
@ -419,6 +453,7 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
|
builder.field(IGNORE_UNMAPPED_FIELD.getPreferredName(), ignoreUnmapped);
|
||||||
|
|
||||||
printBoostAndQueryName(builder);
|
printBoostAndQueryName(builder);
|
||||||
|
|
||||||
|
@ -442,6 +477,7 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
|
||||||
String currentFieldName = null;
|
String currentFieldName = null;
|
||||||
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
|
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
|
||||||
String queryName = null;
|
String queryName = null;
|
||||||
|
boolean ignoreUnmapped = DEFAULT_IGNORE_UNMAPPED;
|
||||||
|
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||||
if (token == XContentParser.Token.FIELD_NAME) {
|
if (token == XContentParser.Token.FIELD_NAME) {
|
||||||
|
@ -499,6 +535,8 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
|
||||||
boost = parser.floatValue();
|
boost = parser.floatValue();
|
||||||
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
|
||||||
queryName = parser.text();
|
queryName = parser.text();
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(currentFieldName, IGNORE_UNMAPPED_FIELD)) {
|
||||||
|
ignoreUnmapped = parser.booleanValue();
|
||||||
} else {
|
} else {
|
||||||
throw new ParsingException(parser.getTokenLocation(), "[" + GeoShapeQueryBuilder.NAME +
|
throw new ParsingException(parser.getTokenLocation(), "[" + GeoShapeQueryBuilder.NAME +
|
||||||
"] query does not support [" + currentFieldName + "]");
|
"] query does not support [" + currentFieldName + "]");
|
||||||
|
@ -526,7 +564,8 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
|
||||||
if (queryName != null) {
|
if (queryName != null) {
|
||||||
builder.queryName(queryName);
|
builder.queryName(queryName);
|
||||||
}
|
}
|
||||||
builder.boost(boost);
|
builder.boost(boost);
|
||||||
|
builder.ignoreUnmapped(ignoreUnmapped);
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,13 +578,14 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
|
||||||
&& Objects.equals(indexedShapeType, other.indexedShapeType)
|
&& Objects.equals(indexedShapeType, other.indexedShapeType)
|
||||||
&& Objects.equals(relation, other.relation)
|
&& Objects.equals(relation, other.relation)
|
||||||
&& Objects.equals(shape, other.shape)
|
&& Objects.equals(shape, other.shape)
|
||||||
&& Objects.equals(strategy, other.strategy);
|
&& Objects.equals(strategy, other.strategy)
|
||||||
|
&& Objects.equals(ignoreUnmapped, other.ignoreUnmapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int doHashCode() {
|
protected int doHashCode() {
|
||||||
return Objects.hash(fieldName, indexedShapeId, indexedShapeIndex,
|
return Objects.hash(fieldName, indexedShapeId, indexedShapeIndex,
|
||||||
indexedShapePath, indexedShapeType, relation, shape, strategy);
|
indexedShapePath, indexedShapeType, relation, shape, strategy, ignoreUnmapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.query;
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.elasticsearch.common.geo.GeoHashUtils;
|
import org.elasticsearch.common.geo.GeoHashUtils;
|
||||||
import org.elasticsearch.ElasticsearchParseException;
|
import org.elasticsearch.ElasticsearchParseException;
|
||||||
|
@ -64,8 +65,14 @@ public class GeohashCellQuery {
|
||||||
|
|
||||||
public static final boolean DEFAULT_NEIGHBORS = false;
|
public static final boolean DEFAULT_NEIGHBORS = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default value for ignore_unmapped.
|
||||||
|
*/
|
||||||
|
public static final boolean DEFAULT_IGNORE_UNMAPPED = false;
|
||||||
|
|
||||||
private static final ParseField NEIGHBORS_FIELD = new ParseField("neighbors");
|
private static final ParseField NEIGHBORS_FIELD = new ParseField("neighbors");
|
||||||
private static final ParseField PRECISION_FIELD = new ParseField("precision");
|
private static final ParseField PRECISION_FIELD = new ParseField("precision");
|
||||||
|
private static final ParseField IGNORE_UNMAPPED_FIELD = new ParseField("ignore_unmapped");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new geohash filter for a given set of geohashes. In general this method
|
* Create a new geohash filter for a given set of geohashes. In general this method
|
||||||
|
@ -107,6 +114,8 @@ public class GeohashCellQuery {
|
||||||
private Integer levels = null;
|
private Integer levels = null;
|
||||||
private boolean neighbors = DEFAULT_NEIGHBORS;
|
private boolean neighbors = DEFAULT_NEIGHBORS;
|
||||||
|
|
||||||
|
private boolean ignoreUnmapped = DEFAULT_IGNORE_UNMAPPED;
|
||||||
|
|
||||||
public Builder(String field, GeoPoint point) {
|
public Builder(String field, GeoPoint point) {
|
||||||
this(field, point == null ? null : point.geohash(), false);
|
this(field, point == null ? null : point.geohash(), false);
|
||||||
}
|
}
|
||||||
|
@ -136,6 +145,7 @@ public class GeohashCellQuery {
|
||||||
geohash = in.readString();
|
geohash = in.readString();
|
||||||
levels = in.readOptionalVInt();
|
levels = in.readOptionalVInt();
|
||||||
neighbors = in.readBoolean();
|
neighbors = in.readBoolean();
|
||||||
|
ignoreUnmapped = in.readBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -144,6 +154,7 @@ public class GeohashCellQuery {
|
||||||
out.writeString(geohash);
|
out.writeString(geohash);
|
||||||
out.writeOptionalVInt(levels);
|
out.writeOptionalVInt(levels);
|
||||||
out.writeBoolean(neighbors);
|
out.writeBoolean(neighbors);
|
||||||
|
out.writeBoolean(ignoreUnmapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder point(GeoPoint point) {
|
public Builder point(GeoPoint point) {
|
||||||
|
@ -200,12 +211,35 @@ public class GeohashCellQuery {
|
||||||
return fieldName;
|
return fieldName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the query builder should ignore unmapped fields (and run
|
||||||
|
* a {@link MatchNoDocsQuery} in place of this query) or throw an
|
||||||
|
* exception if the field is unmapped.
|
||||||
|
*/
|
||||||
|
public GeohashCellQuery.Builder ignoreUnmapped(boolean ignoreUnmapped) {
|
||||||
|
this.ignoreUnmapped = ignoreUnmapped;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the query builder will ignore unmapped fields (and run a
|
||||||
|
* {@link MatchNoDocsQuery} in place of this query) or throw an
|
||||||
|
* exception if the field is unmapped.
|
||||||
|
*/
|
||||||
|
public boolean ignoreUnmapped() {
|
||||||
|
return ignoreUnmapped;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Query doToQuery(QueryShardContext context) throws IOException {
|
protected Query doToQuery(QueryShardContext context) throws IOException {
|
||||||
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
||||||
if (fieldType == null) {
|
if (fieldType == null) {
|
||||||
throw new QueryShardException(context, "failed to parse [{}] query. missing [{}] field [{}]", NAME,
|
if (ignoreUnmapped) {
|
||||||
BaseGeoPointFieldMapper.CONTENT_TYPE, fieldName);
|
return new MatchNoDocsQuery();
|
||||||
|
} else {
|
||||||
|
throw new QueryShardException(context, "failed to parse [{}] query. missing [{}] field [{}]", NAME,
|
||||||
|
BaseGeoPointFieldMapper.CONTENT_TYPE, fieldName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(fieldType instanceof BaseGeoPointFieldMapper.GeoPointFieldType)) {
|
if (!(fieldType instanceof BaseGeoPointFieldMapper.GeoPointFieldType)) {
|
||||||
|
@ -241,6 +275,7 @@ public class GeohashCellQuery {
|
||||||
builder.field(PRECISION_FIELD.getPreferredName(), levels);
|
builder.field(PRECISION_FIELD.getPreferredName(), levels);
|
||||||
}
|
}
|
||||||
builder.field(fieldName, geohash);
|
builder.field(fieldName, geohash);
|
||||||
|
builder.field(IGNORE_UNMAPPED_FIELD.getPreferredName(), ignoreUnmapped);
|
||||||
printBoostAndQueryName(builder);
|
printBoostAndQueryName(builder);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
|
@ -254,6 +289,7 @@ public class GeohashCellQuery {
|
||||||
Boolean neighbors = null;
|
Boolean neighbors = null;
|
||||||
String queryName = null;
|
String queryName = null;
|
||||||
Float boost = null;
|
Float boost = null;
|
||||||
|
boolean ignoreUnmapped = DEFAULT_IGNORE_UNMAPPED;
|
||||||
|
|
||||||
XContentParser.Token token;
|
XContentParser.Token token;
|
||||||
if ((token = parser.currentToken()) != Token.START_OBJECT) {
|
if ((token = parser.currentToken()) != Token.START_OBJECT) {
|
||||||
|
@ -280,6 +316,9 @@ public class GeohashCellQuery {
|
||||||
} else if (parseContext.parseFieldMatcher().match(field, AbstractQueryBuilder.NAME_FIELD)) {
|
} else if (parseContext.parseFieldMatcher().match(field, AbstractQueryBuilder.NAME_FIELD)) {
|
||||||
parser.nextToken();
|
parser.nextToken();
|
||||||
queryName = parser.text();
|
queryName = parser.text();
|
||||||
|
} else if (parseContext.parseFieldMatcher().match(field, IGNORE_UNMAPPED_FIELD)) {
|
||||||
|
parser.nextToken();
|
||||||
|
ignoreUnmapped = parser.booleanValue();
|
||||||
} else if (parseContext.parseFieldMatcher().match(field, AbstractQueryBuilder.BOOST_FIELD)) {
|
} else if (parseContext.parseFieldMatcher().match(field, AbstractQueryBuilder.BOOST_FIELD)) {
|
||||||
parser.nextToken();
|
parser.nextToken();
|
||||||
boost = parser.floatValue();
|
boost = parser.floatValue();
|
||||||
|
@ -322,6 +361,7 @@ public class GeohashCellQuery {
|
||||||
if (boost != null) {
|
if (boost != null) {
|
||||||
builder.boost(boost);
|
builder.boost(boost);
|
||||||
}
|
}
|
||||||
|
builder.ignoreUnmapped(ignoreUnmapped);
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,12 +370,13 @@ public class GeohashCellQuery {
|
||||||
return Objects.equals(fieldName, other.fieldName)
|
return Objects.equals(fieldName, other.fieldName)
|
||||||
&& Objects.equals(geohash, other.geohash)
|
&& Objects.equals(geohash, other.geohash)
|
||||||
&& Objects.equals(levels, other.levels)
|
&& Objects.equals(levels, other.levels)
|
||||||
&& Objects.equals(neighbors, other.neighbors);
|
&& Objects.equals(neighbors, other.neighbors)
|
||||||
|
&& Objects.equals(ignoreUnmapped, other.ignoreUnmapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int doHashCode() {
|
protected int doHashCode() {
|
||||||
return Objects.hash(fieldName, geohash, levels, neighbors);
|
return Objects.hash(fieldName, geohash, levels, neighbors, ignoreUnmapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.apache.lucene.search.BooleanClause;
|
||||||
import org.apache.lucene.search.BooleanQuery;
|
import org.apache.lucene.search.BooleanQuery;
|
||||||
import org.apache.lucene.search.ConstantScoreQuery;
|
import org.apache.lucene.search.ConstantScoreQuery;
|
||||||
import org.apache.lucene.search.LegacyNumericRangeQuery;
|
import org.apache.lucene.search.LegacyNumericRangeQuery;
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.spatial.geopoint.search.GeoPointInBBoxQuery;
|
import org.apache.lucene.spatial.geopoint.search.GeoPointInBBoxQuery;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
|
@ -36,8 +37,10 @@ import org.locationtech.spatial4j.shape.Rectangle;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
|
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||||
|
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||||
import static org.hamcrest.Matchers.closeTo;
|
import static org.hamcrest.Matchers.closeTo;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
@ -84,6 +87,10 @@ public class GeoBoundingBoxQueryBuilderTests extends AbstractQueryTestCase<GeoBo
|
||||||
builder.setValidationMethod(randomFrom(GeoValidationMethod.values()));
|
builder.setValidationMethod(randomFrom(GeoValidationMethod.values()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (randomBoolean()) {
|
||||||
|
builder.ignoreUnmapped(randomBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
builder.type(randomFrom(GeoExecType.values()));
|
builder.type(randomFrom(GeoExecType.values()));
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
@ -454,6 +461,7 @@ public class GeoBoundingBoxQueryBuilderTests extends AbstractQueryTestCase<GeoBo
|
||||||
" },\n" +
|
" },\n" +
|
||||||
" \"validation_method\" : \"STRICT\",\n" +
|
" \"validation_method\" : \"STRICT\",\n" +
|
||||||
" \"type\" : \"MEMORY\",\n" +
|
" \"type\" : \"MEMORY\",\n" +
|
||||||
|
" \"ignore_unmapped\" : false,\n" +
|
||||||
" \"boost\" : 1.0\n" +
|
" \"boost\" : 1.0\n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
"}";
|
"}";
|
||||||
|
@ -475,6 +483,7 @@ public class GeoBoundingBoxQueryBuilderTests extends AbstractQueryTestCase<GeoBo
|
||||||
" },\n" +
|
" },\n" +
|
||||||
" \"validation_method\" : \"STRICT\",\n" +
|
" \"validation_method\" : \"STRICT\",\n" +
|
||||||
" \"type\" : \"MEMORY\",\n" +
|
" \"type\" : \"MEMORY\",\n" +
|
||||||
|
" \"ignore_unmapped\" : false,\n" +
|
||||||
" \"boost\" : 1.0\n" +
|
" \"boost\" : 1.0\n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
"}";
|
"}";
|
||||||
|
@ -494,4 +503,17 @@ public class GeoBoundingBoxQueryBuilderTests extends AbstractQueryTestCase<GeoBo
|
||||||
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
|
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
|
||||||
super.testMustRewrite();
|
super.testMustRewrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testIgnoreUnmapped() throws IOException {
|
||||||
|
final GeoBoundingBoxQueryBuilder queryBuilder = new GeoBoundingBoxQueryBuilder("unmapped").setCorners(1.0, 0.0, 0.0, 1.0);
|
||||||
|
queryBuilder.ignoreUnmapped(true);
|
||||||
|
Query query = queryBuilder.toQuery(queryShardContext());
|
||||||
|
assertThat(query, notNullValue());
|
||||||
|
assertThat(query, instanceOf(MatchNoDocsQuery.class));
|
||||||
|
|
||||||
|
final GeoBoundingBoxQueryBuilder failingQueryBuilder = new GeoBoundingBoxQueryBuilder("unmapped").setCorners(1.0, 0.0, 0.0, 1.0);
|
||||||
|
failingQueryBuilder.ignoreUnmapped(false);
|
||||||
|
QueryShardException e = expectThrows(QueryShardException.class, () -> failingQueryBuilder.toQuery(queryShardContext()));
|
||||||
|
assertThat(e.getMessage(), containsString("failed to find geo_point field [unmapped]"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ package org.elasticsearch.index.query;
|
||||||
|
|
||||||
import org.locationtech.spatial4j.shape.Point;
|
import org.locationtech.spatial4j.shape.Point;
|
||||||
import org.apache.lucene.spatial.geopoint.search.GeoPointDistanceQuery;
|
import org.apache.lucene.spatial.geopoint.search.GeoPointDistanceQuery;
|
||||||
|
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.spatial.util.GeoEncodingUtils;
|
import org.apache.lucene.spatial.util.GeoEncodingUtils;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
|
@ -32,9 +34,11 @@ import org.elasticsearch.test.geo.RandomShapeGenerator;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
|
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||||
|
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||||
import static org.hamcrest.Matchers.closeTo;
|
import static org.hamcrest.Matchers.closeTo;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.instanceOf;
|
|
||||||
|
|
||||||
public class GeoDistanceQueryBuilderTests extends AbstractQueryTestCase<GeoDistanceQueryBuilder> {
|
public class GeoDistanceQueryBuilderTests extends AbstractQueryTestCase<GeoDistanceQueryBuilder> {
|
||||||
|
|
||||||
|
@ -73,6 +77,10 @@ public class GeoDistanceQueryBuilderTests extends AbstractQueryTestCase<GeoDista
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
qb.geoDistance(randomFrom(GeoDistance.values()));
|
qb.geoDistance(randomFrom(GeoDistance.values()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (randomBoolean()) {
|
||||||
|
qb.ignoreUnmapped(randomBoolean());
|
||||||
|
}
|
||||||
return qb;
|
return qb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,6 +410,7 @@ public class GeoDistanceQueryBuilderTests extends AbstractQueryTestCase<GeoDista
|
||||||
" \"distance_type\" : \"sloppy_arc\",\n" +
|
" \"distance_type\" : \"sloppy_arc\",\n" +
|
||||||
" \"optimize_bbox\" : \"memory\",\n" +
|
" \"optimize_bbox\" : \"memory\",\n" +
|
||||||
" \"validation_method\" : \"STRICT\",\n" +
|
" \"validation_method\" : \"STRICT\",\n" +
|
||||||
|
" \"ignore_unmapped\" : false,\n" +
|
||||||
" \"boost\" : 1.0\n" +
|
" \"boost\" : 1.0\n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
"}";
|
"}";
|
||||||
|
@ -417,4 +426,17 @@ public class GeoDistanceQueryBuilderTests extends AbstractQueryTestCase<GeoDista
|
||||||
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
|
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
|
||||||
super.testMustRewrite();
|
super.testMustRewrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testIgnoreUnmapped() throws IOException {
|
||||||
|
final GeoDistanceQueryBuilder queryBuilder = new GeoDistanceQueryBuilder("unmapped").point(0.0, 0.0).distance("20m");
|
||||||
|
queryBuilder.ignoreUnmapped(true);
|
||||||
|
Query query = queryBuilder.toQuery(queryShardContext());
|
||||||
|
assertThat(query, notNullValue());
|
||||||
|
assertThat(query, instanceOf(MatchNoDocsQuery.class));
|
||||||
|
|
||||||
|
final GeoDistanceQueryBuilder failingQueryBuilder = new GeoDistanceQueryBuilder("unmapped").point(0.0, 0.0).distance("20m");
|
||||||
|
failingQueryBuilder.ignoreUnmapped(false);
|
||||||
|
QueryShardException e = expectThrows(QueryShardException.class, () -> failingQueryBuilder.toQuery(queryShardContext()));
|
||||||
|
assertThat(e.getMessage(), containsString("failed to find geo_point field [unmapped]"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.query;
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.spatial.geopoint.search.XGeoPointDistanceRangeQuery;
|
import org.apache.lucene.spatial.geopoint.search.XGeoPointDistanceRangeQuery;
|
||||||
import org.apache.lucene.spatial.util.GeoDistanceUtils;
|
import org.apache.lucene.spatial.util.GeoDistanceUtils;
|
||||||
|
@ -35,9 +36,11 @@ import org.elasticsearch.test.geo.RandomGeoGenerator;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
|
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||||
|
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||||
import static org.hamcrest.Matchers.closeTo;
|
import static org.hamcrest.Matchers.closeTo;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.instanceOf;
|
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
public class GeoDistanceRangeQueryTests extends AbstractQueryTestCase<GeoDistanceRangeQueryBuilder> {
|
public class GeoDistanceRangeQueryTests extends AbstractQueryTestCase<GeoDistanceRangeQueryBuilder> {
|
||||||
|
@ -111,6 +114,10 @@ public class GeoDistanceRangeQueryTests extends AbstractQueryTestCase<GeoDistanc
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
builder.setValidationMethod(randomFrom(GeoValidationMethod.values()));
|
builder.setValidationMethod(randomFrom(GeoValidationMethod.values()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (randomBoolean()) {
|
||||||
|
builder.ignoreUnmapped(randomBoolean());
|
||||||
|
}
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,6 +348,7 @@ public class GeoDistanceRangeQueryTests extends AbstractQueryTestCase<GeoDistanc
|
||||||
" \"distance_type\" : \"sloppy_arc\",\n" +
|
" \"distance_type\" : \"sloppy_arc\",\n" +
|
||||||
" \"optimize_bbox\" : \"memory\",\n" +
|
" \"optimize_bbox\" : \"memory\",\n" +
|
||||||
" \"validation_method\" : \"STRICT\",\n" +
|
" \"validation_method\" : \"STRICT\",\n" +
|
||||||
|
" \"ignore_unmapped\" : false,\n" +
|
||||||
" \"boost\" : 1.0\n" +
|
" \"boost\" : 1.0\n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
"}";
|
"}";
|
||||||
|
@ -354,4 +362,18 @@ public class GeoDistanceRangeQueryTests extends AbstractQueryTestCase<GeoDistanc
|
||||||
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
|
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
|
||||||
super.testMustRewrite();
|
super.testMustRewrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testIgnoreUnmapped() throws IOException {
|
||||||
|
final GeoDistanceRangeQueryBuilder queryBuilder = new GeoDistanceRangeQueryBuilder("unmapped", new GeoPoint(0.0, 0.0)).from("20m");
|
||||||
|
queryBuilder.ignoreUnmapped(true);
|
||||||
|
Query query = queryBuilder.toQuery(queryShardContext());
|
||||||
|
assertThat(query, notNullValue());
|
||||||
|
assertThat(query, instanceOf(MatchNoDocsQuery.class));
|
||||||
|
|
||||||
|
final GeoDistanceRangeQueryBuilder failingQueryBuilder = new GeoDistanceRangeQueryBuilder("unmapped", new GeoPoint(0.0, 0.0))
|
||||||
|
.from("20m");
|
||||||
|
failingQueryBuilder.ignoreUnmapped(false);
|
||||||
|
QueryShardException e = expectThrows(QueryShardException.class, () -> failingQueryBuilder.toQuery(queryShardContext()));
|
||||||
|
assertThat(e.getMessage(), containsString("failed to find geo_point field [unmapped]"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,10 @@
|
||||||
package org.elasticsearch.index.query;
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
import org.locationtech.spatial4j.shape.jts.JtsGeometry;
|
import org.locationtech.spatial4j.shape.jts.JtsGeometry;
|
||||||
|
|
||||||
import com.vividsolutions.jts.geom.Coordinate;
|
import com.vividsolutions.jts.geom.Coordinate;
|
||||||
|
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.spatial.geopoint.search.GeoPointInPolygonQuery;
|
import org.apache.lucene.spatial.geopoint.search.GeoPointInPolygonQuery;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
|
@ -39,9 +42,11 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.elasticsearch.test.StreamsUtils.copyToStringFromClasspath;
|
import static org.elasticsearch.test.StreamsUtils.copyToStringFromClasspath;
|
||||||
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
|
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||||
|
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||||
import static org.hamcrest.Matchers.closeTo;
|
import static org.hamcrest.Matchers.closeTo;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.instanceOf;
|
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
public class GeoPolygonQueryBuilderTests extends AbstractQueryTestCase<GeoPolygonQueryBuilder> {
|
public class GeoPolygonQueryBuilderTests extends AbstractQueryTestCase<GeoPolygonQueryBuilder> {
|
||||||
|
@ -52,6 +57,10 @@ public class GeoPolygonQueryBuilderTests extends AbstractQueryTestCase<GeoPolygo
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
builder.setValidationMethod(randomFrom(GeoValidationMethod.values()));
|
builder.setValidationMethod(randomFrom(GeoValidationMethod.values()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (randomBoolean()) {
|
||||||
|
builder.ignoreUnmapped(randomBoolean());
|
||||||
|
}
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,6 +345,7 @@ public class GeoPolygonQueryBuilderTests extends AbstractQueryTestCase<GeoPolygo
|
||||||
" },\n" +
|
" },\n" +
|
||||||
" \"coerce\" : false,\n" +
|
" \"coerce\" : false,\n" +
|
||||||
" \"ignore_malformed\" : false,\n" +
|
" \"ignore_malformed\" : false,\n" +
|
||||||
|
" \"ignore_unmapped\" : false,\n" +
|
||||||
" \"boost\" : 1.0\n" +
|
" \"boost\" : 1.0\n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
"}";
|
"}";
|
||||||
|
@ -349,4 +359,18 @@ public class GeoPolygonQueryBuilderTests extends AbstractQueryTestCase<GeoPolygo
|
||||||
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
|
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
|
||||||
super.testMustRewrite();
|
super.testMustRewrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testIgnoreUnmapped() throws IOException {
|
||||||
|
List<GeoPoint> polygon = randomPolygon(randomIntBetween(4, 50));
|
||||||
|
final GeoPolygonQueryBuilder queryBuilder = new GeoPolygonQueryBuilder("unmapped", polygon);
|
||||||
|
queryBuilder.ignoreUnmapped(true);
|
||||||
|
Query query = queryBuilder.toQuery(queryShardContext());
|
||||||
|
assertThat(query, notNullValue());
|
||||||
|
assertThat(query, instanceOf(MatchNoDocsQuery.class));
|
||||||
|
|
||||||
|
final GeoPolygonQueryBuilder failingQueryBuilder = new GeoPolygonQueryBuilder("unmapped", polygon);
|
||||||
|
failingQueryBuilder.ignoreUnmapped(false);
|
||||||
|
QueryShardException e = expectThrows(QueryShardException.class, () -> failingQueryBuilder.toQuery(queryShardContext()));
|
||||||
|
assertThat(e.getMessage(), containsString("failed to find geo_point field [unmapped]"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import com.vividsolutions.jts.geom.Coordinate;
|
||||||
|
|
||||||
import org.apache.lucene.search.BooleanQuery;
|
import org.apache.lucene.search.BooleanQuery;
|
||||||
import org.apache.lucene.search.ConstantScoreQuery;
|
import org.apache.lucene.search.ConstantScoreQuery;
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.action.get.GetRequest;
|
import org.elasticsearch.action.get.GetRequest;
|
||||||
|
@ -43,11 +44,12 @@ import org.junit.After;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
|
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||||
|
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||||
import static org.hamcrest.Matchers.anyOf;
|
import static org.hamcrest.Matchers.anyOf;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.instanceOf;
|
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.notNullValue;
|
|
||||||
|
|
||||||
public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQueryBuilder> {
|
public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQueryBuilder> {
|
||||||
|
|
||||||
|
@ -92,6 +94,10 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
|
||||||
builder.relation(randomFrom(ShapeRelation.values()));
|
builder.relation(randomFrom(ShapeRelation.values()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (randomBoolean()) {
|
||||||
|
builder.ignoreUnmapped(randomBoolean());
|
||||||
|
}
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,6 +239,7 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
|
||||||
" },\n" +
|
" },\n" +
|
||||||
" \"relation\" : \"intersects\"\n" +
|
" \"relation\" : \"intersects\"\n" +
|
||||||
" },\n" +
|
" },\n" +
|
||||||
|
" \"ignore_unmapped\" : false,\n" +
|
||||||
" \"boost\" : 42.0\n" +
|
" \"boost\" : 42.0\n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
"}";
|
"}";
|
||||||
|
@ -260,4 +267,19 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
|
||||||
geoShapeQueryBuilder.relation(sqb.relation());
|
geoShapeQueryBuilder.relation(sqb.relation());
|
||||||
assertEquals(geoShapeQueryBuilder, rewrite);
|
assertEquals(geoShapeQueryBuilder, rewrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testIgnoreUnmapped() throws IOException {
|
||||||
|
ShapeType shapeType = ShapeType.randomType(random());
|
||||||
|
ShapeBuilder shape = RandomShapeGenerator.createShapeWithin(random(), null, shapeType);
|
||||||
|
final GeoShapeQueryBuilder queryBuilder = new GeoShapeQueryBuilder("unmapped", shape);
|
||||||
|
queryBuilder.ignoreUnmapped(true);
|
||||||
|
Query query = queryBuilder.toQuery(queryShardContext());
|
||||||
|
assertThat(query, notNullValue());
|
||||||
|
assertThat(query, instanceOf(MatchNoDocsQuery.class));
|
||||||
|
|
||||||
|
final GeoShapeQueryBuilder failingQueryBuilder = new GeoShapeQueryBuilder("unmapped", shape);
|
||||||
|
failingQueryBuilder.ignoreUnmapped(false);
|
||||||
|
QueryShardException e = expectThrows(QueryShardException.class, () -> failingQueryBuilder.toQuery(queryShardContext()));
|
||||||
|
assertThat(e.getMessage(), containsString("failed to find geo_shape field [unmapped]"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,21 +20,25 @@
|
||||||
package org.elasticsearch.index.query;
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
import org.locationtech.spatial4j.shape.Point;
|
import org.locationtech.spatial4j.shape.Point;
|
||||||
|
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
import org.apache.lucene.queries.TermsQuery;
|
import org.apache.lucene.queries.TermsQuery;
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.search.TermQuery;
|
import org.apache.lucene.search.TermQuery;
|
||||||
import org.elasticsearch.common.geo.GeoPoint;
|
import org.elasticsearch.common.geo.GeoPoint;
|
||||||
import org.elasticsearch.common.unit.DistanceUnit;
|
import org.elasticsearch.common.unit.DistanceUnit;
|
||||||
|
import org.elasticsearch.index.mapper.geo.BaseGeoPointFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
||||||
import org.elasticsearch.index.query.GeohashCellQuery.Builder;
|
import org.elasticsearch.index.query.GeohashCellQuery.Builder;
|
||||||
import org.elasticsearch.test.geo.RandomShapeGenerator;
|
import org.elasticsearch.test.geo.RandomShapeGenerator;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
|
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||||
|
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.instanceOf;
|
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
public class GeohashCellQueryBuilderTests extends AbstractQueryTestCase<Builder> {
|
public class GeohashCellQueryBuilderTests extends AbstractQueryTestCase<Builder> {
|
||||||
|
@ -52,6 +56,9 @@ public class GeohashCellQueryBuilderTests extends AbstractQueryTestCase<Builder>
|
||||||
builder.precision(randomIntBetween(1, 1000000) + randomFrom(DistanceUnit.values()).toString());
|
builder.precision(randomIntBetween(1, 1000000) + randomFrom(DistanceUnit.values()).toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (randomBoolean()) {
|
||||||
|
builder.ignoreUnmapped(randomBoolean());
|
||||||
|
}
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +145,7 @@ public class GeohashCellQueryBuilderTests extends AbstractQueryTestCase<Builder>
|
||||||
" \"neighbors\" : true,\n" +
|
" \"neighbors\" : true,\n" +
|
||||||
" \"precision\" : 3,\n" +
|
" \"precision\" : 3,\n" +
|
||||||
" \"pin\" : \"t4mk70fgk067\",\n" +
|
" \"pin\" : \"t4mk70fgk067\",\n" +
|
||||||
|
" \"ignore_unmapped\" : false,\n" +
|
||||||
" \"boost\" : 1.0\n" +
|
" \"boost\" : 1.0\n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
"}";
|
"}";
|
||||||
|
@ -151,4 +159,18 @@ public class GeohashCellQueryBuilderTests extends AbstractQueryTestCase<Builder>
|
||||||
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
|
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
|
||||||
super.testMustRewrite();
|
super.testMustRewrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testIgnoreUnmapped() throws IOException {
|
||||||
|
final GeohashCellQuery.Builder queryBuilder = new GeohashCellQuery.Builder("unmapped", "c");
|
||||||
|
queryBuilder.ignoreUnmapped(true);
|
||||||
|
Query query = queryBuilder.toQuery(queryShardContext());
|
||||||
|
assertThat(query, notNullValue());
|
||||||
|
assertThat(query, instanceOf(MatchNoDocsQuery.class));
|
||||||
|
|
||||||
|
final GeohashCellQuery.Builder failingQueryBuilder = new GeohashCellQuery.Builder("unmapped", "c");
|
||||||
|
failingQueryBuilder.ignoreUnmapped(false);
|
||||||
|
QueryShardException e = expectThrows(QueryShardException.class, () -> failingQueryBuilder.toQuery(queryShardContext()));
|
||||||
|
assertThat(e.getMessage(), containsString("failed to parse [" + GeohashCellQuery.NAME + "] query. missing ["
|
||||||
|
+ BaseGeoPointFieldMapper.CONTENT_TYPE + "] field [unmapped]"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,3 +247,11 @@ are not supported. Here is an example:
|
||||||
}
|
}
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
|
|
||||||
|
[float]
|
||||||
|
==== Ignore Unmapped
|
||||||
|
|
||||||
|
When set to `true` the `ignore_unmapped` option will ignore an unmapped field
|
||||||
|
and will not match any documents for this query. This can be useful when
|
||||||
|
querying multiple indexes which might have different mappings. When set to
|
||||||
|
`false` (the default value) the query will throw an exception if the field
|
||||||
|
is not mapped.
|
||||||
|
|
|
@ -180,3 +180,11 @@ The `geo_distance` filter can work with multiple locations / points per
|
||||||
document. Once a single location / point matches the filter, the
|
document. Once a single location / point matches the filter, the
|
||||||
document will be included in the filter.
|
document will be included in the filter.
|
||||||
|
|
||||||
|
[float]
|
||||||
|
==== Ignore Unmapped
|
||||||
|
|
||||||
|
When set to `true` the `ignore_unmapped` option will ignore an unmapped field
|
||||||
|
and will not match any documents for this query. This can be useful when
|
||||||
|
querying multiple indexes which might have different mappings. When set to
|
||||||
|
`false` (the default value) the query will throw an exception if the field
|
||||||
|
is not mapped.
|
||||||
|
|
|
@ -28,3 +28,12 @@ Supports the same point location parameter and query options as the
|
||||||
<<query-dsl-geo-distance-query,geo_distance>>
|
<<query-dsl-geo-distance-query,geo_distance>>
|
||||||
filter. And also support the common parameters for range (lt, lte, gt,
|
filter. And also support the common parameters for range (lt, lte, gt,
|
||||||
gte, from, to, include_upper and include_lower).
|
gte, from, to, include_upper and include_lower).
|
||||||
|
|
||||||
|
[float]
|
||||||
|
==== Ignore Unmapped
|
||||||
|
|
||||||
|
When set to `true` the `ignore_unmapped` option will ignore an unmapped field
|
||||||
|
and will not match any documents for this query. This can be useful when
|
||||||
|
querying multiple indexes which might have different mappings. When set to
|
||||||
|
`false` (the default value) the query will throw an exception if the field
|
||||||
|
is not mapped.
|
||||||
|
|
|
@ -127,3 +127,11 @@ Format in `lat,lon`.
|
||||||
The query *requires* the <<geo-point,`geo_point`>> type to be set on the
|
The query *requires* the <<geo-point,`geo_point`>> type to be set on the
|
||||||
relevant field.
|
relevant field.
|
||||||
|
|
||||||
|
[float]
|
||||||
|
==== Ignore Unmapped
|
||||||
|
|
||||||
|
When set to `true` the `ignore_unmapped` option will ignore an unmapped field
|
||||||
|
and will not match any documents for this query. This can be useful when
|
||||||
|
querying multiple indexes which might have different mappings. When set to
|
||||||
|
`false` (the default value) the query will throw an exception if the field
|
||||||
|
is not mapped.
|
||||||
|
|
|
@ -116,4 +116,13 @@ has nothing in common with the query geometry.
|
||||||
* `WITHIN` - Return all documents whose `geo_shape` field
|
* `WITHIN` - Return all documents whose `geo_shape` field
|
||||||
is within the query geometry.
|
is within the query geometry.
|
||||||
* `CONTAINS` - Return all documents whose `geo_shape` field
|
* `CONTAINS` - Return all documents whose `geo_shape` field
|
||||||
contains the query geometry.
|
contains the query geometry.
|
||||||
|
|
||||||
|
[float]
|
||||||
|
==== Ignore Unmapped
|
||||||
|
|
||||||
|
When set to `true` the `ignore_unmapped` option will ignore an unmapped field
|
||||||
|
and will not match any documents for this query. This can be useful when
|
||||||
|
querying multiple indexes which might have different mappings. When set to
|
||||||
|
`false` (the default value) the query will throw an exception if the field
|
||||||
|
is not mapped.
|
||||||
|
|
|
@ -61,3 +61,11 @@ next to the given cell.
|
||||||
}
|
}
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
|
|
||||||
|
[float]
|
||||||
|
==== Ignore Unmapped
|
||||||
|
|
||||||
|
When set to `true` the `ignore_unmapped` option will ignore an unmapped field
|
||||||
|
and will not match any documents for this query. This can be useful when
|
||||||
|
querying multiple indexes which might have different mappings. When set to
|
||||||
|
`false` (the default value) the query will throw an exception if the field
|
||||||
|
is not mapped.
|
||||||
|
|
Loading…
Reference in New Issue