diff options
author | Nicholas Knize <nknize@gmail.com> | 2016-08-24 13:53:38 -0500 |
---|---|---|
committer | Nicholas Knize <nknize@gmail.com> | 2016-09-13 12:17:36 -0500 |
commit | ef926894f428f782073170173f2b1d144f42062f (patch) | |
tree | 7b53240d91558a4e31957afe3a377611cce64bee /core/src/main | |
parent | e0074ee9d44440affae0ebf30c3172409f1e21f0 (diff) |
Cut over geo_point field and queries to new LatLonPoint type
This commit cuts over geo_point fields to use Lucene's new point-based LatLonPoint type for indexes created in 5.0. Indexes created prior to 5.0 continue to use their respective encoding type. Below is a description of the changes made to support the new encoding type:
* New indexes use a new LatLonPointFieldMapper which provides a parse method for the new type
* The new LatLonPoint parse method removes support for lat_lon and geohash parameters
* Backcompat testing for deprecated lat_lon and geohash parameters is added to all unit and integration tests
* LatLonPointFieldMapper provides DocValues support (enabled by default) which uses Lucene's new LatLonDocValuesField type
* New LatLonPoint field data classes are added for aggregation support (wraps LatLonPoint's Numeric Doc Values)
* MultiFields use the geohash as the string value instead of the lat,lon string making it easier to perform geo string queries on the geohash instead of a lat,lon comma delimited string.
Removed Features:
* With the removal of geohash indexing, GeoHashCellQuery support is removed for all new indexes (still supported on existing indexes)
* LatLonPoint does not support a Distance Range query because it is super inefficient. Instead, the geo_distance_range query should be accomplished using either the geo_distance aggregation, sorting by descending distance on a geo_distance query, or a boolean must not of the excluded distance (which is what the distance_range query did anyway).
TODO:
* fix/finish yaml changes for plugin and rest integration tests
* update documentation
Diffstat (limited to 'core/src/main')
15 files changed, 533 insertions, 96 deletions
diff --git a/core/src/main/java/org/elasticsearch/common/geo/GeoPoint.java b/core/src/main/java/org/elasticsearch/common/geo/GeoPoint.java index 504fc41313..aaa552fbec 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/GeoPoint.java +++ b/core/src/main/java/org/elasticsearch/common/geo/GeoPoint.java @@ -19,8 +19,13 @@ package org.elasticsearch.common.geo; +import org.apache.lucene.document.LatLonDocValuesField; +import org.apache.lucene.document.LatLonPoint; +import org.apache.lucene.geo.GeoEncodingUtils; +import org.apache.lucene.index.IndexableField; import org.apache.lucene.spatial.geopoint.document.GeoPointField; import org.apache.lucene.util.BitUtil; +import org.apache.lucene.util.NumericUtils; import static org.elasticsearch.common.geo.GeoHashUtils.mortonEncode; import static org.elasticsearch.common.geo.GeoHashUtils.stringEncode; @@ -88,6 +93,23 @@ public final class GeoPoint { return this; } + // todo this is a crutch because LatLonPoint doesn't have a helper for returning .stringValue() + // todo remove with next release of lucene + public GeoPoint resetFromIndexableField(IndexableField field) { + if (field instanceof LatLonPoint) { + byte[] bytes = field.binaryValue().bytes; + return this.reset( + GeoEncodingUtils.decodeLatitude(bytes, 0), + GeoEncodingUtils.decodeLongitude(bytes, Integer.BYTES)); + } else if (field instanceof LatLonDocValuesField) { + long encoded = (long)(field.numericValue()); + return this.reset( + GeoEncodingUtils.decodeLatitude((int)(encoded >>> 32)), + GeoEncodingUtils.decodeLongitude((int)encoded)); + } + return resetFromIndexHash(Long.parseLong(field.stringValue())); + } + public GeoPoint resetFromGeoHash(String geohash) { final long hash = mortonEncode(geohash); return this.reset(GeoPointField.decodeLatitude(hash), GeoPointField.decodeLongitude(hash)); diff --git a/core/src/main/java/org/elasticsearch/index/fielddata/plain/AbstractLatLonPointDVIndexFieldData.java b/core/src/main/java/org/elasticsearch/index/fielddata/plain/AbstractLatLonPointDVIndexFieldData.java new file mode 100644 index 0000000000..c4198a2689 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/index/fielddata/plain/AbstractLatLonPointDVIndexFieldData.java @@ -0,0 +1,100 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.elasticsearch.index.fielddata.plain; + +import org.apache.lucene.document.LatLonDocValuesField; +import org.apache.lucene.index.DocValues; +import org.apache.lucene.index.DocValuesType; +import org.apache.lucene.index.FieldInfo; +import org.apache.lucene.index.LeafReader; +import org.apache.lucene.index.LeafReaderContext; +import org.elasticsearch.common.Nullable; +import org.elasticsearch.index.Index; +import org.elasticsearch.index.IndexSettings; +import org.elasticsearch.index.fielddata.AtomicGeoPointFieldData; +import org.elasticsearch.index.fielddata.IndexFieldData; +import org.elasticsearch.index.fielddata.IndexFieldDataCache; +import org.elasticsearch.index.fielddata.IndexGeoPointFieldData; +import org.elasticsearch.index.mapper.MappedFieldType; +import org.elasticsearch.index.mapper.MapperService; +import org.elasticsearch.indices.breaker.CircuitBreakerService; +import org.elasticsearch.search.MultiValueMode; + +import java.io.IOException; + +/** + * Created by nknize on 8/23/16. + */ +public abstract class AbstractLatLonPointDVIndexFieldData extends DocValuesIndexFieldData + implements IndexGeoPointFieldData { + AbstractLatLonPointDVIndexFieldData(Index index, String fieldName) { + super(index, fieldName); + } + + @Override + public final XFieldComparatorSource comparatorSource(@Nullable Object missingValue, MultiValueMode sortMode, + XFieldComparatorSource.Nested nested) { + throw new IllegalArgumentException("can't sort on geo_point field without using specific sorting feature, like geo_distance"); + } + + public static class LatLonPointDVIndexFieldData extends AbstractLatLonPointDVIndexFieldData { + public LatLonPointDVIndexFieldData(Index index, String fieldName) { + super(index, fieldName); + } + + @Override + public AtomicGeoPointFieldData load(LeafReaderContext context) { + try { + LeafReader reader = context.reader(); + FieldInfo info = reader.getFieldInfos().fieldInfo(fieldName); + if (info != null) { + checkCompatible(info); + } + return new LatLonPointDVAtomicFieldData(DocValues.getSortedNumeric(reader, fieldName)); + } catch (IOException e) { + throw new IllegalStateException("Cannot load doc values", e); + } + } + + @Override + public AtomicGeoPointFieldData loadDirect(LeafReaderContext context) throws Exception { + return load(context); + } + + /** helper: checks a fieldinfo and throws exception if its definitely not a LatLonDocValuesField */ + static void checkCompatible(FieldInfo fieldInfo) { + // dv properties could be "unset", if you e.g. used only StoredField with this same name in the segment. + if (fieldInfo.getDocValuesType() != DocValuesType.NONE + && fieldInfo.getDocValuesType() != LatLonDocValuesField.TYPE.docValuesType()) { + throw new IllegalArgumentException("field=\"" + fieldInfo.name + "\" was indexed with docValuesType=" + + fieldInfo.getDocValuesType() + " but this type has docValuesType=" + + LatLonDocValuesField.TYPE.docValuesType() + ", is the field really a LatLonDocValuesField?"); + } + } + } + + public static class Builder implements IndexFieldData.Builder { + @Override + public IndexFieldData<?> build(IndexSettings indexSettings, MappedFieldType fieldType, IndexFieldDataCache cache, + CircuitBreakerService breakerService, MapperService mapperService) { + // ignore breaker + return new LatLonPointDVIndexFieldData(indexSettings.getIndex(), fieldType.name()); + } + } +} diff --git a/core/src/main/java/org/elasticsearch/index/fielddata/plain/LatLonPointDVAtomicFieldData.java b/core/src/main/java/org/elasticsearch/index/fielddata/plain/LatLonPointDVAtomicFieldData.java new file mode 100644 index 0000000000..420233b5e6 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/index/fielddata/plain/LatLonPointDVAtomicFieldData.java @@ -0,0 +1,94 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.elasticsearch.index.fielddata.plain; + +import org.apache.lucene.geo.GeoEncodingUtils; +import org.apache.lucene.index.SortedNumericDocValues; +import org.apache.lucene.util.Accountable; +import org.apache.lucene.util.ArrayUtil; +import org.apache.lucene.util.RamUsageEstimator; +import org.elasticsearch.common.geo.GeoPoint; +import org.elasticsearch.index.fielddata.MultiGeoPointValues; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +/** + * Created by nknize on 8/23/16. + */ +final class LatLonPointDVAtomicFieldData extends AbstractAtomicGeoPointFieldData { + private final SortedNumericDocValues values; + + LatLonPointDVAtomicFieldData(SortedNumericDocValues values) { + super(); + this.values = values; + } + + @Override + public long ramBytesUsed() { + return 0; // not exposed by lucene + } + + @Override + public Collection<Accountable> getChildResources() { + return Collections.emptyList(); + } + + @Override + public void close() { + // noop + } + + @Override + public MultiGeoPointValues getGeoPointValues() { + return new MultiGeoPointValues() { + GeoPoint[] points = new GeoPoint[0]; + private int count = 0; + + @Override + public void setDocument(int docId) { + values.setDocument(docId); + count = values.count(); + if (count > points.length) { + final int previousLength = points.length; + points = Arrays.copyOf(points, ArrayUtil.oversize(count, RamUsageEstimator.NUM_BYTES_OBJECT_REF)); + for (int i = previousLength; i < points.length; ++i) { + points[i] = new GeoPoint(Double.NaN, Double.NaN); + } + } + long encoded; + for (int i=0; i<count; ++i) { + encoded = values.valueAt(i); + points[i].reset(GeoEncodingUtils.decodeLatitude((int)(encoded >>> 32)), GeoEncodingUtils.decodeLongitude((int)encoded)); + } + } + + @Override + public int count() { + return count; + } + + @Override + public GeoPoint valueAt(int index) { + return points[index]; + } + }; + } +} diff --git a/core/src/main/java/org/elasticsearch/index/mapper/BaseGeoPointFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/BaseGeoPointFieldMapper.java index 2a24b6a94c..b64c09553c 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/BaseGeoPointFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/BaseGeoPointFieldMapper.java @@ -89,7 +89,7 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr protected Boolean ignoreMalformed; - public Builder(String name, GeoPointFieldType fieldType) { + public Builder(String name, MappedFieldType fieldType) { super(name, fieldType, fieldType); } @@ -143,7 +143,16 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr FieldMapper geoHashMapper, MultiFields multiFields, Explicit<Boolean> ignoreMalformed, CopyTo copyTo); public Y build(Mapper.BuilderContext context) { - GeoPointFieldType geoPointFieldType = (GeoPointFieldType)fieldType; + // version 5.0 cuts over to LatLonPoint and no longer indexes geohash, or lat/lon separately + if (context.indexCreatedVersion().before(Version.V_5_0_0_alpha6)) { + return buildLegacy(context); + } + return build(context, name, fieldType, defaultFieldType, context.indexSettings(), + null, null, null, multiFieldsBuilder.build(this, context), ignoreMalformed(context), copyTo); + } + + private Y buildLegacy(Mapper.BuilderContext context) { + LegacyGeoPointFieldType geoPointFieldType = (LegacyGeoPointFieldType)fieldType; FieldMapper latMapper = null; FieldMapper lonMapper = null; @@ -161,9 +170,9 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr lonMapper = (LegacyDoubleFieldMapper) lonMapperBuilder.includeInAll(false).store(fieldType.stored()).docValues(false).build(context); } else { latMapper = new NumberFieldMapper.Builder(Names.LAT, NumberFieldMapper.NumberType.DOUBLE) - .includeInAll(false).store(fieldType.stored()).docValues(false).build(context); + .includeInAll(false).store(fieldType.stored()).docValues(false).build(context); lonMapper = new NumberFieldMapper.Builder(Names.LON, NumberFieldMapper.NumberType.DOUBLE) - .includeInAll(false).store(fieldType.stored()).docValues(false).build(context); + .includeInAll(false).store(fieldType.stored()).docValues(false).build(context); } geoPointFieldType.setLatLonEnabled(latMapper.fieldType(), lonMapper.fieldType()); } @@ -183,7 +192,7 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr context.path().remove(); return build(context, name, fieldType, defaultFieldType, context.indexSettings(), - latMapper, lonMapper, geoHashMapper, multiFieldsBuilder.build(this, context), ignoreMalformed(context), copyTo); + latMapper, lonMapper, geoHashMapper, multiFieldsBuilder.build(this, context), ignoreMalformed(context), copyTo); } } @@ -191,8 +200,11 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr @Override public Mapper.Builder<?, ?> parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException { Builder builder; - if (parserContext.indexVersionCreated().before(Version.V_2_2_0)) { + Version indexVersionCreated = parserContext.indexVersionCreated(); + if (indexVersionCreated.before(Version.V_2_2_0)) { builder = new LegacyGeoPointFieldMapper.Builder(name); + } else if (indexVersionCreated.onOrAfter(Version.V_5_0_0_alpha6)) { + builder = new LatLonPointFieldMapper.Builder(name); } else { builder = new GeoPointFieldMapper.Builder(name); } @@ -202,39 +214,43 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr Map.Entry<String, Object> entry = iterator.next(); String propName = entry.getKey(); Object propNode = entry.getValue(); - if (propName.equals("lat_lon")) { - deprecationLogger.deprecated(CONTENT_TYPE + " lat_lon parameter is deprecated and will be removed " - + "in the next major release"); - builder.enableLatLon(XContentMapValues.lenientNodeBooleanValue(propNode)); - iterator.remove(); - } else if (propName.equals("precision_step")) { - deprecationLogger.deprecated(CONTENT_TYPE + " precision_step parameter is deprecated and will be removed " - + "in the next major release"); - builder.precisionStep(XContentMapValues.nodeIntegerValue(propNode)); - iterator.remove(); - } else if (propName.equals("geohash")) { - deprecationLogger.deprecated(CONTENT_TYPE + " geohash parameter is deprecated and will be removed " - + "in the next major release"); - builder.enableGeoHash(XContentMapValues.lenientNodeBooleanValue(propNode)); - iterator.remove(); - } else if (propName.equals("geohash_prefix")) { - deprecationLogger.deprecated(CONTENT_TYPE + " geohash_prefix parameter is deprecated and will be removed " - + "in the next major release"); - builder.geoHashPrefix(XContentMapValues.lenientNodeBooleanValue(propNode)); - if (XContentMapValues.lenientNodeBooleanValue(propNode)) { - builder.enableGeoHash(true); - } - iterator.remove(); - } else if (propName.equals("geohash_precision")) { - deprecationLogger.deprecated(CONTENT_TYPE + " geohash_precision parameter is deprecated and will be removed " - + "in the next major release"); - if (propNode instanceof Integer) { - builder.geoHashPrecision(XContentMapValues.nodeIntegerValue(propNode)); - } else { - builder.geoHashPrecision(GeoUtils.geoHashLevelsForPrecision(propNode.toString())); + if (indexVersionCreated.before(Version.V_5_0_0_alpha6)) { + if (propName.equals("lat_lon")) { + deprecationLogger.deprecated(CONTENT_TYPE + " lat_lon parameter is deprecated and will be removed " + + "in the next major release"); + builder.enableLatLon(XContentMapValues.lenientNodeBooleanValue(propNode)); + iterator.remove(); + } else if (propName.equals("precision_step")) { + deprecationLogger.deprecated(CONTENT_TYPE + " precision_step parameter is deprecated and will be removed " + + "in the next major release"); + builder.precisionStep(XContentMapValues.nodeIntegerValue(propNode)); + iterator.remove(); + } else if (propName.equals("geohash")) { + deprecationLogger.deprecated(CONTENT_TYPE + " geohash parameter is deprecated and will be removed " + + "in the next major release"); + builder.enableGeoHash(XContentMapValues.lenientNodeBooleanValue(propNode)); + iterator.remove(); + } else if (propName.equals("geohash_prefix")) { + deprecationLogger.deprecated(CONTENT_TYPE + " geohash_prefix parameter is deprecated and will be removed " + + "in the next major release"); + builder.geoHashPrefix(XContentMapValues.lenientNodeBooleanValue(propNode)); + if (XContentMapValues.lenientNodeBooleanValue(propNode)) { + builder.enableGeoHash(true); + } + iterator.remove(); + } else if (propName.equals("geohash_precision")) { + deprecationLogger.deprecated(CONTENT_TYPE + " geohash_precision parameter is deprecated and will be removed " + + "in the next major release"); + if (propNode instanceof Integer) { + builder.geoHashPrecision(XContentMapValues.nodeIntegerValue(propNode)); + } else { + builder.geoHashPrecision(GeoUtils.geoHashLevelsForPrecision(propNode.toString())); + } + iterator.remove(); } - iterator.remove(); - } else if (propName.equals(Names.IGNORE_MALFORMED)) { + } + + if (propName.equals(Names.IGNORE_MALFORMED)) { builder.ignoreMalformed(XContentMapValues.lenientNodeBooleanValue(propNode)); iterator.remove(); } @@ -242,13 +258,29 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr if (builder instanceof LegacyGeoPointFieldMapper.Builder) { return LegacyGeoPointFieldMapper.parse((LegacyGeoPointFieldMapper.Builder) builder, node, parserContext); + } else if (builder instanceof LatLonPointFieldMapper.Builder) { + return (LatLonPointFieldMapper.Builder) builder; } return (GeoPointFieldMapper.Builder) builder; } } - public static class GeoPointFieldType extends MappedFieldType { + public abstract static class GeoPointFieldType extends MappedFieldType { + GeoPointFieldType() { + } + + GeoPointFieldType(GeoPointFieldType ref) { + super(ref); + } + + @Override + public String typeName() { + return CONTENT_TYPE; + } + } + + public static class LegacyGeoPointFieldType extends GeoPointFieldType { protected MappedFieldType geoHashFieldType; protected int geoHashPrecision; protected boolean geoHashPrefixEnabled; @@ -256,9 +288,9 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr protected MappedFieldType latFieldType; protected MappedFieldType lonFieldType; - GeoPointFieldType() {} + LegacyGeoPointFieldType() {} - GeoPointFieldType(GeoPointFieldType ref) { + LegacyGeoPointFieldType(LegacyGeoPointFieldType ref) { super(ref); this.geoHashFieldType = ref.geoHashFieldType; // copying ref is ok, this can never be modified this.geoHashPrecision = ref.geoHashPrecision; @@ -269,13 +301,13 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr @Override public MappedFieldType clone() { - return new GeoPointFieldType(this); + return new LegacyGeoPointFieldType(this); } @Override public boolean equals(Object o) { if (!super.equals(o)) return false; - GeoPointFieldType that = (GeoPointFieldType) o; + LegacyGeoPointFieldType that = (LegacyGeoPointFieldType) o; return geoHashPrecision == that.geoHashPrecision && geoHashPrefixEnabled == that.geoHashPrefixEnabled && java.util.Objects.equals(geoHashFieldType, that.geoHashFieldType) && @@ -290,14 +322,9 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr } @Override - public String typeName() { - return CONTENT_TYPE; - } - - @Override public void checkCompatibility(MappedFieldType fieldType, List<String> conflicts, boolean strict) { super.checkCompatibility(fieldType, conflicts, strict); - GeoPointFieldType other = (GeoPointFieldType)fieldType; + LegacyGeoPointFieldType other = (LegacyGeoPointFieldType)fieldType; if (isLatLonEnabled() != other.isLatLonEnabled()) { conflicts.add("mapper [" + name() + "] has different [lat_lon]"); } @@ -398,9 +425,10 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr this.ignoreMalformed = ignoreMalformed; } - @Override - public GeoPointFieldType fieldType() { - return (GeoPointFieldType) super.fieldType(); + + + public LegacyGeoPointFieldType legacyFieldType() { + return (LegacyGeoPointFieldType) super.fieldType(); } @Override @@ -414,15 +442,22 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr @Override public Iterator<Mapper> iterator() { + if (this instanceof LatLonPointFieldMapper == false) { + return Iterators.concat(super.iterator(), legacyIterator()); + } + return super.iterator(); + } + + public Iterator<Mapper> legacyIterator() { List<Mapper> extras = new ArrayList<>(); - if (fieldType().isGeoHashEnabled()) { + if (legacyFieldType().isGeoHashEnabled()) { extras.add(geoHashMapper); } - if (fieldType().isLatLonEnabled()) { + if (legacyFieldType().isLatLonEnabled()) { extras.add(latMapper); extras.add(lonMapper); } - return Iterators.concat(super.iterator(), extras.iterator()); + return extras.iterator(); } @Override @@ -436,13 +471,13 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr } protected void parse(ParseContext context, GeoPoint point, String geoHash) throws IOException { - if (fieldType().isGeoHashEnabled()) { + if (legacyFieldType().isGeoHashEnabled()) { if (geoHash == null) { geoHash = GeoHashUtils.stringEncode(point.lon(), point.lat()); } addGeoHashField(context, geoHash); } - if (fieldType().isLatLonEnabled()) { + if (legacyFieldType().isLatLonEnabled()) { latMapper.parse(context.createExternalValueContext(point.lat())); lonMapper.parse(context.createExternalValueContext(point.lon())); } @@ -517,8 +552,9 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr } private void addGeoHashField(ParseContext context, String geoHash) throws IOException { - int len = Math.min(fieldType().geoHashPrecision(), geoHash.length()); - int min = fieldType().isGeoHashPrefixEnabled() ? 1 : len; + LegacyGeoPointFieldType ft = (LegacyGeoPointFieldType)fieldType; + int len = Math.min(ft.geoHashPrecision(), geoHash.length()); + int min = ft.isGeoHashPrefixEnabled() ? 1 : len; for (int i = len; i >= min; i--) { // side effect of this call is adding the field @@ -537,23 +573,30 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr @Override protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException { super.doXContentBody(builder, includeDefaults, params); - if (includeDefaults || fieldType().isLatLonEnabled() != GeoPointFieldMapper.Defaults.ENABLE_LATLON) { - builder.field("lat_lon", fieldType().isLatLonEnabled()); + if (this instanceof LatLonPointFieldMapper == false) { + legacyDoXContentBody(builder, includeDefaults, params); } - if (fieldType().isLatLonEnabled() && (includeDefaults || fieldType().latFieldType().numericPrecisionStep() != LegacyNumericUtils.PRECISION_STEP_DEFAULT)) { - builder.field("precision_step", fieldType().latFieldType().numericPrecisionStep()); + if (includeDefaults || ignoreMalformed.explicit()) { + builder.field(Names.IGNORE_MALFORMED, ignoreMalformed.value()); } - if (includeDefaults || fieldType().isGeoHashEnabled() != Defaults.ENABLE_GEOHASH) { - builder.field("geohash", fieldType().isGeoHashEnabled()); + } + + protected void legacyDoXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException { + LegacyGeoPointFieldType ft = (LegacyGeoPointFieldType) fieldType; + if (includeDefaults || ft.isLatLonEnabled() != GeoPointFieldMapper.Defaults.ENABLE_LATLON) { + builder.field("lat_lon", ft.isLatLonEnabled()); } - if (includeDefaults || fieldType().isGeoHashPrefixEnabled() != Defaults.ENABLE_GEOHASH_PREFIX) { - builder.field("geohash_prefix", fieldType().isGeoHashPrefixEnabled()); + if (ft.isLatLonEnabled() && (includeDefaults || ft.latFieldType().numericPrecisionStep() != LegacyNumericUtils.PRECISION_STEP_DEFAULT)) { + builder.field("precision_step", ft.latFieldType().numericPrecisionStep()); } - if (fieldType().isGeoHashEnabled() && (includeDefaults || fieldType().geoHashPrecision() != Defaults.GEO_HASH_PRECISION)) { - builder.field("geohash_precision", fieldType().geoHashPrecision()); + if (includeDefaults || ft.isGeoHashEnabled() != Defaults.ENABLE_GEOHASH) { + builder.field("geohash", ft.isGeoHashEnabled()); } - if (includeDefaults || ignoreMalformed.explicit()) { - builder.field(Names.IGNORE_MALFORMED, ignoreMalformed.value()); + if (includeDefaults || ft.isGeoHashPrefixEnabled() != Defaults.ENABLE_GEOHASH_PREFIX) { + builder.field("geohash_prefix", ft.isGeoHashPrefixEnabled()); + } + if (ft.isGeoHashEnabled() && (includeDefaults || ft.geoHashPrecision() != Defaults.GEO_HASH_PRECISION)) { + builder.field("geohash_precision", ft.geoHashPrecision()); } } diff --git a/core/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java index ee7a9fa07f..c1ba15be78 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java @@ -48,7 +48,7 @@ public class GeoPointFieldMapper extends BaseGeoPointFieldMapper { public static class Defaults extends BaseGeoPointFieldMapper.Defaults { - public static final GeoPointFieldType FIELD_TYPE = new GeoPointFieldType(); + public static final GeoPointFieldType FIELD_TYPE = new LegacyGeoPointFieldType(); static { FIELD_TYPE.setIndexOptions(IndexOptions.DOCS); @@ -130,4 +130,9 @@ public class GeoPointFieldMapper extends BaseGeoPointFieldMapper { } super.parse(context, point, geoHash); } + + @Override + public LegacyGeoPointFieldType fieldType() { + return (LegacyGeoPointFieldType) super.fieldType(); + } } diff --git a/core/src/main/java/org/elasticsearch/index/mapper/LatLonPointFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/LatLonPointFieldMapper.java new file mode 100644 index 0000000000..588ef9c373 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/index/mapper/LatLonPointFieldMapper.java @@ -0,0 +1,148 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.elasticsearch.index.mapper; + +import org.apache.lucene.document.LatLonDocValuesField; +import org.apache.lucene.document.LatLonPoint; +import org.apache.lucene.index.IndexOptions; +import org.apache.lucene.search.Query; +import org.elasticsearch.common.Explicit; +import org.elasticsearch.common.geo.GeoPoint; +import org.elasticsearch.common.geo.GeoUtils; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.index.fielddata.IndexFieldData; +import org.elasticsearch.index.fielddata.plain.AbstractLatLonPointDVIndexFieldData; +import org.elasticsearch.index.query.QueryShardContext; +import org.elasticsearch.index.query.QueryShardException; + +import java.io.IOException; +import java.util.Iterator; +import java.util.Map; + +/** + * Created by nknize on 8/23/16. + */ +public class LatLonPointFieldMapper extends BaseGeoPointFieldMapper { + public static final String CONTENT_TYPE = "geo_point"; + + public static class Defaults extends BaseGeoPointFieldMapper.Defaults { + public static final LatLonPointFieldType FIELD_TYPE = new LatLonPointFieldType(); + + static { + FIELD_TYPE.setTokenized(false); + FIELD_TYPE.setHasDocValues(true); + FIELD_TYPE.setDimensions(2, Integer.BYTES); + FIELD_TYPE.freeze(); + } + } + + public static class Builder extends BaseGeoPointFieldMapper.Builder<Builder, LatLonPointFieldMapper> { + public Builder(String name) { + super(name, Defaults.FIELD_TYPE); + } + + @Override + public LatLonPointFieldMapper build(BuilderContext context, String simpleName, MappedFieldType fieldType, + MappedFieldType defaultFieldType, Settings indexSettings, + FieldMapper latMapper, FieldMapper lonMapper, FieldMapper geoHashMapper, + MultiFields multiFields, Explicit<Boolean> ignoreMalformed, + CopyTo copyTo) { + setupFieldType(context); + return new LatLonPointFieldMapper(simpleName, fieldType, defaultFieldType, indexSettings, multiFields, + ignoreMalformed, copyTo); + } + + @Override + public LatLonPointFieldMapper build(BuilderContext context) { + return super.build(context); + } + } + + public static class TypeParser extends BaseGeoPointFieldMapper.TypeParser { + @Override + public Mapper.Builder<?, ?> parse(String name, Map<String, Object> node, ParserContext parserContext) + throws MapperParsingException { + return super.parse(name, node, parserContext); + } + } + + public LatLonPointFieldMapper(String simpleName, MappedFieldType fieldType, MappedFieldType defaultFieldType, + Settings indexSettings, MultiFields multiFields, Explicit<Boolean> ignoreMalformed, + CopyTo copyTo) { + super(simpleName, fieldType, defaultFieldType, indexSettings, null, null, null, multiFields, ignoreMalformed, copyTo); + } + + public static class LatLonPointFieldType extends GeoPointFieldType { + LatLonPointFieldType() { + } + + LatLonPointFieldType(LatLonPointFieldType ref) { + super(ref); + } + + @Override + public String typeName() { + return CONTENT_TYPE; + } + + @Override + public MappedFieldType clone() { + return new LatLonPointFieldType(this); + } + + @Override + public IndexFieldData.Builder fielddataBuilder() { + failIfNoDocValues(); + return new AbstractLatLonPointDVIndexFieldData.Builder(); + } + + @Override + public Query termQuery(Object value, QueryShardContext context) { + throw new QueryShardException(context, "Geo fields do not support exact searching, use dedicated geo queries instead: [" + + name() + "]"); + } + } + + @Override + protected void parse(ParseContext originalContext, GeoPoint point, String geoHash) throws IOException { + // Geopoint fields, by default, will not be included in _all + final ParseContext context = originalContext.setIncludeInAllDefault(false); + + if (ignoreMalformed.value() == false) { + if (point.lat() > 90.0 || point.lat() < -90.0) { + throw new IllegalArgumentException("illegal latitude value [" + point.lat() + "] for " + name()); + } + if (point.lon() > 180.0 || point.lon() < -180) { + throw new IllegalArgumentException("illegal longitude value [" + point.lon() + "] for " + name()); + } + } else { + GeoUtils.normalizePoint(point); + } + if (fieldType().indexOptions() != IndexOptions.NONE || fieldType().stored()) { + context.doc().add(new LatLonPoint(fieldType().name(), point.lat(), point.lon())); + } + if (fieldType.hasDocValues()) { + context.doc().add(new LatLonDocValuesField(fieldType().name(), point.lat(), point.lon())); + } + // if the mapping contains multifields then use the geohash string + if (multiFields.iterator().hasNext()) { + multiFields.parse(this, context.createExternalValueContext(point.geohash())); + } + } +} diff --git a/core/src/main/java/org/elasticsearch/index/mapper/LegacyGeoPointFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/LegacyGeoPointFieldMapper.java index 3fe195c5d9..99ca07b06b 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/LegacyGeoPointFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/LegacyGeoPointFieldMapper.java @@ -60,7 +60,7 @@ public class LegacyGeoPointFieldMapper extends BaseGeoPointFieldMapper implement public static class Defaults extends BaseGeoPointFieldMapper.Defaults{ public static final Explicit<Boolean> COERCE = new Explicit<>(false, false); - public static final GeoPointFieldType FIELD_TYPE = new GeoPointFieldType(); + public static final GeoPointFieldType FIELD_TYPE = new LegacyGeoPointFieldType(); static { FIELD_TYPE.setIndexOptions(IndexOptions.DOCS); @@ -331,6 +331,11 @@ public class LegacyGeoPointFieldMapper extends BaseGeoPointFieldMapper implement } } + @Override + public LegacyGeoPointFieldType fieldType() { + return (LegacyGeoPointFieldType) super.fieldType(); + } + public static class CustomGeoPointDocValuesField extends CustomDocValuesField { private final ObjectHashSet<GeoPoint> points; diff --git a/core/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java index ee7220111f..45e84254bf 100644 --- a/core/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java @@ -19,6 +19,7 @@ package org.elasticsearch.index.query; +import org.apache.lucene.document.LatLonPoint; import org.apache.lucene.geo.Rectangle; import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.Query; @@ -38,7 +39,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.fielddata.IndexGeoPointFieldData; import org.elasticsearch.index.mapper.BaseGeoPointFieldMapper; -import org.elasticsearch.index.mapper.LegacyGeoPointFieldMapper; +import org.elasticsearch.index.mapper.BaseGeoPointFieldMapper.LegacyGeoPointFieldType; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.search.geo.LegacyInMemoryGeoBoundingBoxQuery; import org.elasticsearch.index.search.geo.LegacyIndexedGeoBoundingBoxQuery; @@ -359,7 +360,10 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding } } - if (indexVersionCreated.onOrAfter(Version.V_2_2_0)) { + if (indexVersionCreated.onOrAfter(Version.V_5_0_0_alpha6)) { + return LatLonPoint.newBoxQuery(fieldType.name(), luceneBottomRight.getLat(), luceneTopLeft.getLat(), + luceneTopLeft.getLon(), luceneBottomRight.getLon()); + } else if (indexVersionCreated.onOrAfter(Version.V_2_2_0)) { // if index created V_2_2 use (soon to be legacy) numeric encoding postings format // if index created V_2_3 > use prefix encoded postings format final GeoPointField.TermEncoding encoding = (indexVersionCreated.before(Version.V_2_3_0)) ? @@ -371,7 +375,7 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding Query query; switch(type) { case INDEXED: - LegacyGeoPointFieldMapper.GeoPointFieldType geoFieldType = ((LegacyGeoPointFieldMapper.GeoPointFieldType) fieldType); + LegacyGeoPointFieldType geoFieldType = ((LegacyGeoPointFieldType) fieldType); query = LegacyIndexedGeoBoundingBoxQuery.create(luceneTopLeft, luceneBottomRight, geoFieldType); break; case MEMORY: diff --git a/core/src/main/java/org/elasticsearch/index/query/GeoDistanceQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/GeoDistanceQueryBuilder.java index a0226f44f7..436f854bc2 100644 --- a/core/src/main/java/org/elasticsearch/index/query/GeoDistanceQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/GeoDistanceQueryBuilder.java @@ -19,6 +19,7 @@ package org.elasticsearch.index.query; +import org.apache.lucene.document.LatLonPoint; import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.Query; import org.apache.lucene.spatial.geopoint.document.GeoPointField; @@ -297,8 +298,10 @@ public class GeoDistanceQueryBuilder extends AbstractQueryBuilder<GeoDistanceQue double normDistance = geoDistance.normalize(this.distance, DistanceUnit.DEFAULT); - if (indexVersionCreated.before(Version.V_2_2_0)) { - LegacyGeoPointFieldMapper.GeoPointFieldType geoFieldType = ((LegacyGeoPointFieldMapper.GeoPointFieldType) fieldType); + if (indexVersionCreated.onOrAfter(Version.V_5_0_0_alpha6)) { + return LatLonPoint.newDistanceQuery(fieldType.name(), center.lat(), center.lon(), normDistance); + } else if (indexVersionCreated.before(Version.V_2_2_0)) { + LegacyGeoPointFieldMapper.LegacyGeoPointFieldType geoFieldType = (LegacyGeoPointFieldMapper.LegacyGeoPointFieldType) fieldType; IndexGeoPointFieldData indexFieldData = shardContext.getForField(fieldType); String bboxOptimization = Strings.isEmpty(optimizeBbox) ? DEFAULT_OPTIMIZE_BBOX : optimizeBbox; return new GeoDistanceRangeQuery(center, null, normDistance, true, false, geoDistance, diff --git a/core/src/main/java/org/elasticsearch/index/query/GeoDistanceRangeQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/GeoDistanceRangeQueryBuilder.java index 0b06e07e02..ebd80b9e28 100644 --- a/core/src/main/java/org/elasticsearch/index/query/GeoDistanceRangeQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/GeoDistanceRangeQueryBuilder.java @@ -37,8 +37,8 @@ import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.fielddata.IndexGeoPointFieldData; import org.elasticsearch.index.mapper.BaseGeoPointFieldMapper; +import org.elasticsearch.index.mapper.BaseGeoPointFieldMapper.LegacyGeoPointFieldType; import org.elasticsearch.index.mapper.GeoPointFieldMapper; -import org.elasticsearch.index.mapper.LegacyGeoPointFieldMapper; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.search.geo.GeoDistanceRangeQuery; @@ -347,8 +347,11 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder<GeoDistan } final Version indexVersionCreated = context.indexVersionCreated(); - if (indexVersionCreated.before(Version.V_2_2_0)) { - LegacyGeoPointFieldMapper.GeoPointFieldType geoFieldType = ((LegacyGeoPointFieldMapper.GeoPointFieldType) fieldType); + if (indexVersionCreated.onOrAfter(Version.V_5_0_0_alpha6)) { + throw new QueryShardException(context, "[{}] queries are no longer supported for geo_point field types. " + + "Use geo_distance sort or aggregations", NAME); + } else if (indexVersionCreated.before(Version.V_2_2_0)) { + LegacyGeoPointFieldType geoFieldType = (LegacyGeoPointFieldType) fieldType; IndexGeoPointFieldData indexFieldData = context.getForField(fieldType); String bboxOptimization = Strings.isEmpty(optimizeBbox) ? DEFAULT_OPTIMIZE_BBOX : optimizeBbox; return new GeoDistanceRangeQuery(point, fromValue, toValue, includeLower, includeUpper, geoDistance, geoFieldType, diff --git a/core/src/main/java/org/elasticsearch/index/query/GeohashCellQuery.java b/core/src/main/java/org/elasticsearch/index/query/GeohashCellQuery.java index 57a189b72f..ab3b23af0f 100644 --- a/core/src/main/java/org/elasticsearch/index/query/GeohashCellQuery.java +++ b/core/src/main/java/org/elasticsearch/index/query/GeohashCellQuery.java @@ -36,6 +36,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser.Token; import org.elasticsearch.index.mapper.BaseGeoPointFieldMapper; +import org.elasticsearch.index.mapper.LatLonPointFieldMapper; import org.elasticsearch.index.mapper.MappedFieldType; import java.io.IOException; @@ -83,7 +84,7 @@ public class GeohashCellQuery { * @param geohashes optional array of additional geohashes * @return a new GeoBoundinboxfilter */ - public static Query create(QueryShardContext context, BaseGeoPointFieldMapper.GeoPointFieldType fieldType, + public static Query create(QueryShardContext context, BaseGeoPointFieldMapper.LegacyGeoPointFieldType fieldType, String geohash, @Nullable List<CharSequence> geohashes) { MappedFieldType geoHashMapper = fieldType.geoHashFieldType(); if (geoHashMapper == null) { @@ -241,11 +242,14 @@ public class GeohashCellQuery { } } - if (!(fieldType instanceof BaseGeoPointFieldMapper.GeoPointFieldType)) { + if (fieldType instanceof LatLonPointFieldMapper.LatLonPointFieldType) { + throw new QueryShardException(context, "failed to parse [{}] query. " + + "geo_point field no longer supports geohash_cell queries", NAME); + } else if (!(fieldType instanceof BaseGeoPointFieldMapper.LegacyGeoPointFieldType)) { throw new QueryShardException(context, "failed to parse [{}] query. field [{}] is not a geo_point field", NAME, fieldName); } - BaseGeoPointFieldMapper.GeoPointFieldType geoFieldType = ((BaseGeoPointFieldMapper.GeoPointFieldType) fieldType); + BaseGeoPointFieldMapper.LegacyGeoPointFieldType geoFieldType = ((BaseGeoPointFieldMapper.LegacyGeoPointFieldType) fieldType); if (!geoFieldType.isGeoHashPrefixEnabled()) { throw new QueryShardException(context, "failed to parse [{}] query. [geohash_prefix] is not enabled for field [{}]", NAME, fieldName); diff --git a/core/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceRangeQuery.java b/core/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceRangeQuery.java index 53cdf5861a..823f882f40 100644 --- a/core/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceRangeQuery.java +++ b/core/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceRangeQuery.java @@ -35,6 +35,7 @@ import org.elasticsearch.common.geo.GeoPoint; import org.elasticsearch.common.unit.DistanceUnit; import org.elasticsearch.index.fielddata.IndexGeoPointFieldData; import org.elasticsearch.index.fielddata.MultiGeoPointValues; +import org.elasticsearch.index.mapper.BaseGeoPointFieldMapper; import org.elasticsearch.index.mapper.LegacyGeoPointFieldMapper; import java.io.IOException; @@ -60,7 +61,8 @@ public class GeoDistanceRangeQuery extends Query { private final IndexGeoPointFieldData indexFieldData; public GeoDistanceRangeQuery(GeoPoint point, Double lowerVal, Double upperVal, boolean includeLower, - boolean includeUpper, GeoDistance geoDistance, LegacyGeoPointFieldMapper.GeoPointFieldType fieldType, + boolean includeUpper, GeoDistance geoDistance, + LegacyGeoPointFieldMapper.LegacyGeoPointFieldType fieldType, IndexGeoPointFieldData indexFieldData, String optimizeBbox) { this.lat = point.lat(); this.lon = point.lon(); diff --git a/core/src/main/java/org/elasticsearch/index/search/geo/LegacyIndexedGeoBoundingBoxQuery.java b/core/src/main/java/org/elasticsearch/index/search/geo/LegacyIndexedGeoBoundingBoxQuery.java index f60a12f023..6fdb2a906c 100644 --- a/core/src/main/java/org/elasticsearch/index/search/geo/LegacyIndexedGeoBoundingBoxQuery.java +++ b/core/src/main/java/org/elasticsearch/index/search/geo/LegacyIndexedGeoBoundingBoxQuery.java @@ -33,7 +33,8 @@ import org.elasticsearch.index.mapper.LegacyGeoPointFieldMapper; @Deprecated public class LegacyIndexedGeoBoundingBoxQuery { - public static Query create(GeoPoint topLeft, GeoPoint bottomRight, LegacyGeoPointFieldMapper.GeoPointFieldType fieldType) { + public static Query create(GeoPoint topLeft, GeoPoint bottomRight, + LegacyGeoPointFieldMapper.LegacyGeoPointFieldType fieldType) { if (!fieldType.isLatLonEnabled()) { throw new IllegalArgumentException("lat/lon is not enabled (indexed) for field [" + fieldType.name() + "], can't use indexed filter on it"); @@ -47,7 +48,7 @@ public class LegacyIndexedGeoBoundingBoxQuery { } private static Query westGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, - LegacyGeoPointFieldMapper.GeoPointFieldType fieldType) { + LegacyGeoPointFieldMapper.LegacyGeoPointFieldType fieldType) { BooleanQuery.Builder filter = new BooleanQuery.Builder(); filter.setMinimumNumberShouldMatch(1); filter.add(fieldType.lonFieldType().rangeQuery(null, bottomRight.lon(), true, true), Occur.SHOULD); @@ -57,7 +58,7 @@ public class LegacyIndexedGeoBoundingBoxQuery { } private static Query eastGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, - LegacyGeoPointFieldMapper.GeoPointFieldType fieldType) { + LegacyGeoPointFieldMapper.LegacyGeoPointFieldType fieldType) { BooleanQuery.Builder filter = new BooleanQuery.Builder(); filter.add(fieldType.lonFieldType().rangeQuery(topLeft.lon(), bottomRight.lon(), true, true), Occur.MUST); filter.add(fieldType.latFieldType().rangeQuery(bottomRight.lat(), topLeft.lat(), true, true), Occur.MUST); diff --git a/core/src/main/java/org/elasticsearch/indices/IndicesModule.java b/core/src/main/java/org/elasticsearch/indices/IndicesModule.java index fed710244f..eb1843dc7d 100644 --- a/core/src/main/java/org/elasticsearch/indices/IndicesModule.java +++ b/core/src/main/java/org/elasticsearch/indices/IndicesModule.java @@ -36,23 +36,24 @@ import org.elasticsearch.index.mapper.DateFieldMapper; import org.elasticsearch.index.mapper.FieldNamesFieldMapper; import org.elasticsearch.index.mapper.GeoPointFieldMapper; import org.elasticsearch.index.mapper.GeoShapeFieldMapper; -import org.elasticsearch.index.mapper.IdFieldMapper; -import org.elasticsearch.index.mapper.IndexFieldMapper; import org.elasticsearch.index.mapper.IpFieldMapper; import org.elasticsearch.index.mapper.KeywordFieldMapper; +import org.elasticsearch.index.mapper.LatLonPointFieldMapper; import org.elasticsearch.index.mapper.Mapper; import org.elasticsearch.index.mapper.MetadataFieldMapper; import org.elasticsearch.index.mapper.NumberFieldMapper; import org.elasticsearch.index.mapper.ObjectMapper; +import org.elasticsearch.index.mapper.TextFieldMapper; +import org.elasticsearch.index.mapper.TokenCountFieldMapper; +import org.elasticsearch.index.mapper.ScaledFloatFieldMapper; +import org.elasticsearch.index.mapper.StringFieldMapper; +import org.elasticsearch.index.mapper.IdFieldMapper; +import org.elasticsearch.index.mapper.IndexFieldMapper; import org.elasticsearch.index.mapper.ParentFieldMapper; import org.elasticsearch.index.mapper.RoutingFieldMapper; -import org.elasticsearch.index.mapper.ScaledFloatFieldMapper; import org.elasticsearch.index.mapper.SourceFieldMapper; -import org.elasticsearch.index.mapper.StringFieldMapper; -import org.elasticsearch.index.mapper.TTLFieldMapper; -import org.elasticsearch.index.mapper.TextFieldMapper; import org.elasticsearch.index.mapper.TimestampFieldMapper; -import org.elasticsearch.index.mapper.TokenCountFieldMapper; +import org.elasticsearch.index.mapper.TTLFieldMapper; import org.elasticsearch.index.mapper.TypeFieldMapper; import org.elasticsearch.index.mapper.UidFieldMapper; import org.elasticsearch.index.mapper.VersionFieldMapper; @@ -119,6 +120,7 @@ public class IndicesModule extends AbstractModule { mappers.put(ObjectMapper.NESTED_CONTENT_TYPE, new ObjectMapper.TypeParser()); mappers.put(CompletionFieldMapper.CONTENT_TYPE, new CompletionFieldMapper.TypeParser()); mappers.put(GeoPointFieldMapper.CONTENT_TYPE, new GeoPointFieldMapper.TypeParser()); + mappers.put(LatLonPointFieldMapper.CONTENT_TYPE, new LatLonPointFieldMapper.TypeParser()); if (ShapesAvailability.JTS_AVAILABLE && ShapesAvailability.SPATIAL4J_AVAILABLE) { mappers.put(GeoShapeFieldMapper.CONTENT_TYPE, new GeoShapeFieldMapper.TypeParser()); } diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoContextMapping.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoContextMapping.java index 854a5fb0e1..bd1449bbfe 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoContextMapping.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoContextMapping.java @@ -207,7 +207,8 @@ public class GeoContextMapping extends ContextMapping<GeoQueryContext> { if (field instanceof StringField) { spare.resetFromString(field.stringValue()); } else { - spare.resetFromIndexHash(Long.parseLong(field.stringValue())); + // todo return this to .stringValue() once LatLonPoint implements it + spare.resetFromIndexableField(field); } geohashes.add(spare.geohash()); } |