This moves the `distance_feature` query building out of `DistanceFeatureQueryBuilder` and into subclasses of `MappedFieldType`. Without this we don't have a chance of supporting this for runtime fields. In general I'm not sad to see the `instanceof`s go. Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
1b2a015734
commit
0286d0a769
|
@ -41,6 +41,7 @@ import org.elasticsearch.common.time.DateFormatter;
|
|||
import org.elasticsearch.common.time.DateFormatters;
|
||||
import org.elasticsearch.common.time.DateMathParser;
|
||||
import org.elasticsearch.common.time.DateUtils;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.common.util.LocaleUtils;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.index.fielddata.IndexNumericFieldData.NumericType;
|
||||
|
@ -94,6 +95,11 @@ public final class DateFieldMapper extends ParametrizedFieldMapper {
|
|||
public long parsePointAsMillis(byte[] value) {
|
||||
return LongPoint.decodeDimension(value, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Query distanceFeatureQuery(String field, float boost, long origin, TimeValue pivot) {
|
||||
return LongPoint.newDistanceFeatureQuery(field, boost, origin, pivot.getMillis());
|
||||
}
|
||||
},
|
||||
NANOSECONDS(DATE_NANOS_CONTENT_TYPE, NumericType.DATE_NANOSECONDS) {
|
||||
@Override
|
||||
|
@ -115,6 +121,11 @@ public final class DateFieldMapper extends ParametrizedFieldMapper {
|
|||
public long parsePointAsMillis(byte[] value) {
|
||||
return DateUtils.toMilliSeconds(LongPoint.decodeDimension(value, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Query distanceFeatureQuery(String field, float boost, long origin, TimeValue pivot) {
|
||||
return LongPoint.newDistanceFeatureQuery(field, boost, origin, pivot.getNanos());
|
||||
}
|
||||
};
|
||||
|
||||
private final String type;
|
||||
|
@ -162,6 +173,8 @@ public final class DateFieldMapper extends ParametrizedFieldMapper {
|
|||
}
|
||||
throw new IllegalArgumentException("unknown resolution ordinal [" + ord + "]");
|
||||
}
|
||||
|
||||
protected abstract Query distanceFeatureQuery(String field, float boost, long origin, TimeValue pivot);
|
||||
}
|
||||
|
||||
private static DateFieldMapper toType(FieldMapper in) {
|
||||
|
@ -370,6 +383,13 @@ public final class DateFieldMapper extends ParametrizedFieldMapper {
|
|||
return resolution.convert(instant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query distanceFeatureQuery(Object origin, String pivot, float boost, QueryShardContext context) {
|
||||
long originLong = parseToLong(origin, true, null, null, context::nowInMillis);
|
||||
TimeValue pivotTime = TimeValue.parseTimeValue(pivot, "distance_feature.pivot");
|
||||
return resolution.distanceFeatureQuery(name(), boost, originLong, pivotTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Relation isFieldWithinQuery(IndexReader reader,
|
||||
Object from, Object to, boolean includeLower, boolean includeUpper,
|
||||
|
|
|
@ -24,15 +24,18 @@ import org.apache.lucene.document.LatLonPoint;
|
|||
import org.apache.lucene.document.StoredField;
|
||||
import org.apache.lucene.index.IndexOptions;
|
||||
import org.apache.lucene.index.IndexableField;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.elasticsearch.ElasticsearchParseException;
|
||||
import org.elasticsearch.common.Explicit;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.common.geo.GeoUtils;
|
||||
import org.elasticsearch.common.unit.DistanceUnit;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.geometry.Point;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.index.fielddata.plain.AbstractLatLonPointIndexFieldData;
|
||||
import org.elasticsearch.index.mapper.GeoPointFieldMapper.ParsedGeoPoint;
|
||||
import org.elasticsearch.index.query.QueryShardContext;
|
||||
import org.elasticsearch.index.query.VectorGeoPointShapeQueryProcessor;
|
||||
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
|
||||
|
||||
|
@ -186,6 +189,20 @@ public class GeoPointFieldMapper extends AbstractPointGeometryFieldMapper<List<P
|
|||
return new AbstractLatLonPointIndexFieldData.Builder(name(), CoreValuesSourceType.GEOPOINT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query distanceFeatureQuery(Object origin, String pivot, float boost, QueryShardContext context) {
|
||||
GeoPoint originGeoPoint;
|
||||
if (origin instanceof GeoPoint) {
|
||||
originGeoPoint = (GeoPoint) origin;
|
||||
} else if (origin instanceof String) {
|
||||
originGeoPoint = GeoUtils.parseFromString((String) origin);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Illegal type ["+ origin.getClass() + "] for [origin]! " +
|
||||
"Must be of type [geo_point] or [string] for geo_point fields!");
|
||||
}
|
||||
double pivotDouble = DistanceUnit.DEFAULT.parse(pivot, DistanceUnit.DEFAULT);
|
||||
return LatLonPoint.newDistanceFeatureQuery(name(), boost, originGeoPoint.lat(), originGeoPoint.lon(), pivotDouble);
|
||||
}
|
||||
}
|
||||
|
||||
// Eclipse requires the AbstractPointGeometryFieldMapper prefix or it can't find ParsedPoint
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.elasticsearch.common.time.DateMathParser;
|
|||
import org.elasticsearch.common.unit.Fuzziness;
|
||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.index.query.DistanceFeatureQueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryRewriteContext;
|
||||
import org.elasticsearch.index.query.QueryShardContext;
|
||||
import org.elasticsearch.index.query.QueryShardException;
|
||||
|
@ -241,6 +242,11 @@ public abstract class MappedFieldType {
|
|||
+ "] which is of type [" + typeName() + "]");
|
||||
}
|
||||
|
||||
public Query distanceFeatureQuery(Object origin, String pivot, float boost, QueryShardContext context) {
|
||||
throw new IllegalArgumentException("Illegal data type of [" + typeName() + "]!"+
|
||||
"[" + DistanceFeatureQueryBuilder.NAME + "] query can only be run on a date, date_nanos or geo_point field type!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an {@link IntervalsSource} to be used for proximity queries
|
||||
*/
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
|
||||
package org.elasticsearch.index.query;
|
||||
|
||||
import org.apache.lucene.document.LatLonPoint;
|
||||
import org.apache.lucene.document.LongPoint;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.ParsingException;
|
||||
|
@ -29,15 +27,10 @@ import org.elasticsearch.common.geo.GeoUtils;
|
|||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.lucene.search.Queries;
|
||||
import org.elasticsearch.common.unit.DistanceUnit;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.mapper.DateFieldMapper;
|
||||
import org.elasticsearch.index.mapper.DateFieldMapper.DateFieldType;
|
||||
import org.elasticsearch.index.mapper.GeoPointFieldMapper.GeoPointFieldType;
|
||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -119,30 +112,7 @@ public class DistanceFeatureQueryBuilder extends AbstractQueryBuilder<DistanceFe
|
|||
if (fieldType == null) {
|
||||
return Queries.newMatchNoDocsQuery("Can't run [" + NAME + "] query on unmapped fields!");
|
||||
}
|
||||
Object originObj = origin.origin();
|
||||
if (fieldType instanceof DateFieldType) {
|
||||
long originLong = ((DateFieldType) fieldType).parseToLong(originObj, true, null, null, context::nowInMillis);
|
||||
TimeValue pivotVal = TimeValue.parseTimeValue(pivot, DistanceFeatureQueryBuilder.class.getSimpleName() + ".pivot");
|
||||
if (((DateFieldType) fieldType).resolution() == DateFieldMapper.Resolution.MILLISECONDS) {
|
||||
return LongPoint.newDistanceFeatureQuery(field, boost, originLong, pivotVal.getMillis());
|
||||
} else { // NANOSECONDS
|
||||
return LongPoint.newDistanceFeatureQuery(field, boost, originLong, pivotVal.getNanos());
|
||||
}
|
||||
} else if (fieldType instanceof GeoPointFieldType) {
|
||||
GeoPoint originGeoPoint;
|
||||
if (originObj instanceof GeoPoint) {
|
||||
originGeoPoint = (GeoPoint) originObj;
|
||||
} else if (originObj instanceof String) {
|
||||
originGeoPoint = GeoUtils.parseFromString((String) originObj);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Illegal type ["+ origin.getClass() + "] for [origin]! " +
|
||||
"Must be of type [geo_point] or [string] for geo_point fields!");
|
||||
}
|
||||
double pivotDouble = DistanceUnit.DEFAULT.parse(pivot, DistanceUnit.DEFAULT);
|
||||
return LatLonPoint.newDistanceFeatureQuery(field, boost, originGeoPoint.lat(), originGeoPoint.lon(), pivotDouble);
|
||||
}
|
||||
throw new IllegalArgumentException("Illegal data type of [" + fieldType.typeName() + "]!"+
|
||||
"[" + NAME + "] query can only be run on a date, date_nanos or geo_point field type!");
|
||||
return fieldType.distanceFeatureQuery(origin.origin(), pivot, boost, context);
|
||||
}
|
||||
|
||||
String fieldName() {
|
||||
|
|
Loading…
Reference in New Issue