summaryrefslogtreecommitdiffstats
path: root/container-search/src/main/java/com/yahoo
diff options
context:
space:
mode:
authorArne Juul <arnej@verizonmedia.com>2020-07-08 12:55:09 +0000
committerArne Juul <arnej@verizonmedia.com>2020-07-15 15:39:20 +0000
commitc50ae024b2ff3f4b1890373ed30fa5a8c90db177 (patch)
tree958fc77db774fc4d3188535297e8db98d1733737 /container-search/src/main/java/com/yahoo
parentaacf9c9ccbcd558e58086ee657c5061e038a62f0 (diff)
test geoLocation parsing and generation
Diffstat (limited to 'container-search/src/main/java/com/yahoo')
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/SelectParser.java39
-rw-r--r--container-search/src/main/java/com/yahoo/search/yql/VespaSerializer.java9
-rw-r--r--container-search/src/main/java/com/yahoo/search/yql/YqlParser.java20
3 files changed, 57 insertions, 11 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/query/SelectParser.java b/container-search/src/main/java/com/yahoo/search/query/SelectParser.java
index 4ae2e4ceddd..330f9a1fef2 100644
--- a/container-search/src/main/java/com/yahoo/search/query/SelectParser.java
+++ b/container-search/src/main/java/com/yahoo/search/query/SelectParser.java
@@ -3,6 +3,8 @@ package com.yahoo.search.query;
import com.google.common.base.Preconditions;
import com.yahoo.collections.LazyMap;
+import com.yahoo.geo.ParseDegree;
+import com.yahoo.geo.ParseDistance;
import com.yahoo.language.Language;
import com.yahoo.language.process.Normalizer;
import com.yahoo.prelude.IndexFacts;
@@ -49,6 +51,7 @@ import com.yahoo.slime.ArrayTraverser;
import com.yahoo.slime.Inspector;
import com.yahoo.slime.ObjectTraverser;
import com.yahoo.slime.SlimeUtils;
+import com.yahoo.slime.Type;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
@@ -156,7 +159,7 @@ public class SelectParser implements Parser {
}
private QueryTree buildTree() {
- Inspector inspector = SlimeUtils.jsonToSlime(this.query.getSelect().getWhereString().getBytes()).get();
+ Inspector inspector = SlimeUtils.jsonToSlime(this.query.getSelect().getWhereString()).get();
if (inspector.field("error_message").valid()) {
throw new QueryException("Illegal query: " + inspector.field("error_message").asString() +
" at: '" + new String(inspector.field("offending_input").asData(), StandardCharsets.UTF_8) + "'");
@@ -216,7 +219,7 @@ public class SelectParser implements Parser {
/** Translates a list of grouping requests on JSON form to a list in the grouping language form */
private List<String> toGroupingRequests(String groupingJson) {
- Inspector inspector = SlimeUtils.jsonToSlime(groupingJson.getBytes()).get();
+ Inspector inspector = SlimeUtils.jsonToSlime(groupingJson).get();
if (inspector.field("error_message").valid()) {
throw new QueryException("Illegal query: " + inspector.field("error_message").asString() +
" at: '" + new String(inspector.field("offending_input").asData(), StandardCharsets.UTF_8) + "'");
@@ -417,10 +420,36 @@ public class SelectParser implements Parser {
private Item buildGeoLocation(String key, Inspector value) {
HashMap<Integer, Inspector> children = childMap(value);
- Preconditions.checkArgument(children.size() == 2, "Expected 2 arguments, got %s.", children.size());
+ Preconditions.checkArgument(children.size() == 4, "Expected 4 arguments, got %s.", children.size());
String field = children.get(0).asString();
- String location = children.get(1).asString();
- GeoLocationItem item = new GeoLocationItem(new Location(location), field);
+ var arg1 = children.get(1);
+ var arg2 = children.get(2);
+ var arg3 = children.get(3);
+ var loc = new Location();
+ double radius = -1;
+ if (arg3.type() == Type.STRING) {
+ radius = new ParseDistance(arg3.asString()).degrees;
+ } else if (arg3.type() == Type.LONG) {
+ radius = new ParseDistance(String.valueOf(arg3.asLong())).degrees;
+ } else {
+ throw new IllegalArgumentException("Invalid geoLocation radius type "+arg3.type()+" for "+arg3);
+ }
+ if (arg1.type() == Type.STRING && arg2.type() == Type.STRING) {
+ var coord_1 = new ParseDegree(true, children.get(1).asString());
+ var coord_2 = new ParseDegree(false, children.get(2).asString());
+ if (coord_1.foundLatitude && coord_2.foundLongitude) {
+ loc.setGeoCircle(coord_1.latitude, coord_2.longitude, radius);
+ } else if (coord_2.foundLatitude && coord_1.foundLongitude) {
+ loc.setGeoCircle(coord_2.latitude, coord_1.longitude, radius);
+ } else {
+ throw new IllegalArgumentException("Invalid geoLocation coordinates '"+coord_1+"' and '"+coord_2+"'");
+ }
+ } else if (arg1.type() == Type.DOUBLE && arg2.type() == Type.DOUBLE) {
+ loc.setGeoCircle(arg1.asDouble(), arg2.asDouble(), radius);
+ } else {
+ throw new IllegalArgumentException("Invalid geoLocation coordinate types "+arg1.type()+" and "+arg2.type());
+ }
+ var item = new GeoLocationItem(loc, field);
Inspector annotations = getAnnotations(value);
if (annotations != null){
annotations.traverse((ObjectTraverser) (annotation_name, annotation_value) -> {
diff --git a/container-search/src/main/java/com/yahoo/search/yql/VespaSerializer.java b/container-search/src/main/java/com/yahoo/search/yql/VespaSerializer.java
index 77250ecd439..22328fb026e 100644
--- a/container-search/src/main/java/com/yahoo/search/yql/VespaSerializer.java
+++ b/container-search/src/main/java/com/yahoo/search/yql/VespaSerializer.java
@@ -701,9 +701,12 @@ public class VespaSerializer {
destination.append("([{").append(annotations).append("}]");
}
destination.append(GEO_LOCATION).append('(');
- destination.append(item.getIndexName()).append(", ").append('"');
- escape(item.getIndexedString(), destination);
- destination.append('"').append(')');
+ destination.append(item.getIndexName()).append(", ");
+ var loc = item.getLocation();
+ destination.append(loc.degNS()).append(", ");
+ destination.append(loc.degEW()).append(", ");
+ destination.append('"').append(loc.degRadius()).append(" deg").append('"');
+ destination.append(')');
return false;
}
}
diff --git a/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java b/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java
index a0bb4efb70b..446e855cdce 100644
--- a/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java
+++ b/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java
@@ -19,6 +19,8 @@ import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
import com.yahoo.collections.LazyMap;
import com.yahoo.collections.LazySet;
+import com.yahoo.geo.ParseDegree;
+import com.yahoo.geo.ParseDistance;
import com.yahoo.language.Language;
import com.yahoo.language.detect.Detector;
import com.yahoo.language.process.Normalizer;
@@ -420,10 +422,20 @@ public class YqlParser implements Parser {
private Item buildGeoLocation(OperatorNode<ExpressionOperator> ast) {
List<OperatorNode<ExpressionOperator>> args = ast.getArgument(1);
- Preconditions.checkArgument(args.size() == 2, "Expected 2 arguments, got %s.", args.size());
+ Preconditions.checkArgument(args.size() == 4, "Expected 4 arguments, got %s.", args.size());
String field = fetchFieldRead(args.get(0));
- String location = fetchFieldRead(args.get(1));
- GeoLocationItem item = new GeoLocationItem(new Location(location), field);
+ var coord_1 = new ParseDegree(true, fetchFieldRead(args.get(1)));
+ var coord_2 = new ParseDegree(false, fetchFieldRead(args.get(2)));
+ var radius = new ParseDistance(fetchFieldRead(args.get(3)));
+ var loc = new Location();
+ if (coord_1.foundLatitude && coord_2.foundLongitude) {
+ loc.setGeoCircle(coord_1.latitude, coord_2.longitude, radius.degrees);
+ } else if (coord_2.foundLatitude && coord_1.foundLongitude) {
+ loc.setGeoCircle(coord_2.latitude, coord_1.longitude, radius.degrees);
+ } else {
+ throw new IllegalArgumentException("Invalid geoLocation coordinates '"+coord_1+"' and '"+coord_2+"'");
+ }
+ var item = new GeoLocationItem(loc, field);
String label = getAnnotation(ast, LABEL, String.class, null, "item label");
if (label != null) {
item.setLabel(label);
@@ -920,6 +932,8 @@ public class YqlParser implements Parser {
private static String fetchFieldRead(OperatorNode<ExpressionOperator> ast) {
switch (ast.getOperator()) {
+ case LITERAL:
+ return ast.getArgument(0).toString();
case READ_FIELD:
return ast.getArgument(1);
case PROPREF: