diff options
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.java | 147 |
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)); } } } |