summaryrefslogtreecommitdiff
path: root/core/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoContextMapping.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoContextMapping.java')
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoContextMapping.java147
1 files changed, 13 insertions, 134 deletions
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 9a01322145..f895f280d2 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
@@ -232,151 +232,30 @@ public class GeoContextMapping extends ContextMapping {
* see {@link GeoUtils#parseGeoPoint(String, GeoPoint)} for GEO POINT
*/
@Override
- public List<CategoryQueryContext> parseQueryContext(XContentParser parser) throws IOException, ElasticsearchParseException {
- List<CategoryQueryContext> queryContexts = new ArrayList<>();
+ public List<QueryContext> parseQueryContext(XContentParser parser) throws IOException, ElasticsearchParseException {
+ List<GeoQueryContext> queryContexts = new ArrayList<>();
Token token = parser.nextToken();
if (token == Token.START_OBJECT || token == Token.VALUE_STRING) {
- queryContexts.add(innerParseQueryContext(parser));
+ queryContexts.add(GeoQueryContext.parse(parser));
} else if (token == Token.START_ARRAY) {
while (parser.nextToken() != Token.END_ARRAY) {
- queryContexts.add(innerParseQueryContext(parser));
+ queryContexts.add(GeoQueryContext.parse(parser));
}
}
- return queryContexts;
- }
-
- private GeoQueryContext innerParseQueryContext(XContentParser parser) throws IOException, ElasticsearchParseException {
- Token token = parser.currentToken();
- if (token == Token.VALUE_STRING) {
- return new GeoQueryContext(GeoUtils.parseGeoPoint(parser), 1, precision, precision);
- } else if (token == Token.START_OBJECT) {
- String currentFieldName = null;
- GeoPoint point = null;
- double lat = Double.NaN;
- double lon = Double.NaN;
- int precision = this.precision;
- List<Integer> neighbours = new ArrayList<>();
- int boost = 1;
- while ((token = parser.nextToken()) != Token.END_OBJECT) {
- if (token == Token.FIELD_NAME) {
- currentFieldName = parser.currentName();
- } else if (currentFieldName != null) {
- if ("lat".equals(currentFieldName)) {
- if (token == Token.VALUE_STRING || token == Token.VALUE_NUMBER) {
- if (point == null) {
- lat = parser.doubleValue(true);
- } else {
- throw new ElasticsearchParseException("context must have either lat/lon or geohash");
- }
- } else {
- throw new ElasticsearchParseException("lat must be a number");
- }
- } else if ("lon".equals(currentFieldName)) {
- if (token == Token.VALUE_STRING || token == Token.VALUE_NUMBER) {
- if (point == null) {
- lon = parser.doubleValue(true);
- } else {
- throw new ElasticsearchParseException("context must have either lat/lon or geohash");
- }
- } else {
- throw new ElasticsearchParseException("lon must be a number");
- }
- } else if (CONTEXT_VALUE.equals(currentFieldName)) {
- point = GeoUtils.parseGeoPoint(parser);
- } else if (CONTEXT_BOOST.equals(currentFieldName)) {
- final Number number;
- if (token == Token.VALUE_STRING) {
- try {
- number = Long.parseLong(parser.text());
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException("boost must be a string representing a numeric value, but was [" + parser.text() + "]");
- }
- } else if (token == Token.VALUE_NUMBER) {
- XContentParser.NumberType numberType = parser.numberType();
- number = parser.numberValue();
- if (numberType != XContentParser.NumberType.INT) {
- throw new ElasticsearchParseException("boost must be in the interval [0..2147483647], but was [" + number.longValue() + "]");
- }
- } else {
- throw new ElasticsearchParseException("boost must be an int");
- }
- boost = number.intValue();
- } else if (CONTEXT_NEIGHBOURS.equals(currentFieldName)) {
- if (token == Token.VALUE_STRING) {
- neighbours.add(GeoUtils.geoHashLevelsForPrecision(parser.text()));
- } else if (token == Token.VALUE_NUMBER) {
- XContentParser.NumberType numberType = parser.numberType();
- if (numberType == XContentParser.NumberType.INT || numberType == XContentParser.NumberType.LONG) {
- neighbours.add(parser.intValue());
- } else {
- neighbours.add(GeoUtils.geoHashLevelsForPrecision(parser.doubleValue()));
- }
- } else if (token == Token.START_ARRAY) {
- while ((token = parser.nextToken()) != Token.END_ARRAY) {
- if (token == Token.VALUE_STRING || token == Token.VALUE_NUMBER) {
- neighbours.add(parser.intValue(true));
- } else {
- throw new ElasticsearchParseException("neighbours array must have only numbers");
- }
- }
- } else {
- throw new ElasticsearchParseException("neighbours must be a number or a list of numbers");
- }
- } else if (CONTEXT_PRECISION.equals(currentFieldName)) {
- if (token == Token.VALUE_STRING) {
- precision = GeoUtils.geoHashLevelsForPrecision(parser.text());
- } else if (token == Token.VALUE_NUMBER) {
- XContentParser.NumberType numberType = parser.numberType();
- if (numberType == XContentParser.NumberType.INT || numberType == XContentParser.NumberType.LONG) {
- precision = parser.intValue();
- } else {
- precision = GeoUtils.geoHashLevelsForPrecision(parser.doubleValue());
- }
- } else {
- throw new ElasticsearchParseException("precision must be a number");
- }
- }
- }
- }
- if (point == null) {
- if (Double.isNaN(lat) == false && Double.isNaN(lon) == false) {
- point = new GeoPoint(lat, lon);
- } else {
- throw new ElasticsearchParseException("no context provided");
- }
- }
-
- String geoHash = GeoHashUtils.stringEncode(point.getLon(), point.getLat(), precision);
- if (neighbours.size() > 0) {
- final int[] neighbourValues = new int[neighbours.size()];
- for (int i = 0; i < neighbours.size(); i++) {
- neighbourValues[i] = neighbours.get(i);
- }
- return new GeoQueryContext(geoHash, boost, precision, neighbourValues);
- } else {
- return new GeoQueryContext(geoHash, boost, precision, precision);
- }
- } else {
- throw new ElasticsearchParseException("contexts field expected string or object but was [" + token.name() + "]");
- }
- }
-
- @Override
- public List<CategoryQueryContext> getQueryContexts(List<CategoryQueryContext> queryContexts) {
- List<CategoryQueryContext> queryContextList = new ArrayList<>();
- for (CategoryQueryContext queryContext : queryContexts) {
- GeoQueryContext geoQueryContext = ((GeoQueryContext) queryContext);
- int precision = Math.min(this.precision, geoQueryContext.context.length());
- String truncatedGeohash = geoQueryContext.context.toString().substring(0, precision);
- queryContextList.add(new CategoryQueryContext(truncatedGeohash, geoQueryContext.boost, false));
+ List<QueryContext> queryContextList = new ArrayList<>();
+ for (GeoQueryContext geoQueryContext : queryContexts) {
+ int minPrecision = Math.min(this.precision, geoQueryContext.precision);
+ int precision = Math.min(minPrecision, geoQueryContext.geoHash.length());
+ String truncatedGeohash = geoQueryContext.geoHash.toString().substring(0, precision);
+ queryContextList.add(new QueryContext(truncatedGeohash, geoQueryContext.boost, truncatedGeohash.length() < this.precision));
for (int neighboursPrecision : geoQueryContext.neighbours) {
int neighbourPrecision = Math.min(neighboursPrecision, truncatedGeohash.length());
String neighbourGeohash = truncatedGeohash.substring(0, neighbourPrecision);
- Collection<String> locations = new HashSet<>();
+ Collection<String> locations = new ArrayList<>();
GeoHashUtils.addNeighbors(neighbourGeohash, neighbourPrecision, locations);
- boolean isPrefix = neighbourPrecision < precision;
+ boolean isPrefix = neighbourPrecision < this.precision;
for (String location : locations) {
- queryContextList.add(new CategoryQueryContext(location, geoQueryContext.boost, isPrefix));
+ queryContextList.add(new QueryContext(location, geoQueryContext.boost, isPrefix));
}
}
}