summaryrefslogtreecommitdiffstats
path: root/container-search
diff options
context:
space:
mode:
authorArne Juul <arnej@verizonmedia.com>2020-07-08 06:18:16 +0000
committerArne Juul <arnej@verizonmedia.com>2020-07-15 15:39:19 +0000
commit911f614fbab51de142cbea19f2c1aed9160c132d (patch)
treeda7534ce0c4f1af828b5d63772bbc253135a713e /container-search
parent570ede74b98309d245d960592acf69185f11749f (diff)
minimal YQL support
Diffstat (limited to 'container-search')
-rw-r--r--container-search/abi-spec.json48
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/Location.java6
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/GeoLocationItem.java (renamed from container-search/src/main/java/com/yahoo/prelude/query/LocationItem.java)17
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/SelectParser.java24
-rw-r--r--container-search/src/main/java/com/yahoo/search/yql/VespaSerializer.java20
-rw-r--r--container-search/src/main/java/com/yahoo/search/yql/YqlParser.java20
6 files changed, 101 insertions, 34 deletions
diff --git a/container-search/abi-spec.json b/container-search/abi-spec.json
index 8728e525f88..98cc7c5165d 100644
--- a/container-search/abi-spec.json
+++ b/container-search/abi-spec.json
@@ -527,6 +527,30 @@
],
"fields": []
},
+ "com.yahoo.prelude.query.GeoLocationItem": {
+ "superClass": "com.yahoo.prelude.query.TermItem",
+ "interfaces": [],
+ "attributes": [
+ "public"
+ ],
+ "methods": [
+ "public void <init>(com.yahoo.prelude.Location)",
+ "public void <init>(com.yahoo.prelude.Location, java.lang.String)",
+ "public java.lang.String getRawWord()",
+ "public com.yahoo.prelude.query.Item$ItemType getItemType()",
+ "public java.lang.String getName()",
+ "public java.lang.String stringValue()",
+ "public void setValue(java.lang.String)",
+ "public int hashCode()",
+ "public boolean equals(java.lang.Object)",
+ "public java.lang.String getIndexedString()",
+ "protected void encodeThis(java.nio.ByteBuffer)",
+ "public int getNumWords()",
+ "public boolean isStemmed()",
+ "public boolean isWords()"
+ ],
+ "fields": []
+ },
"com.yahoo.prelude.query.HasIndexItem": {
"superClass": "java.lang.Object",
"interfaces": [],
@@ -805,30 +829,6 @@
"public static final com.yahoo.prelude.query.Limit POSITIVE_INFINITY"
]
},
- "com.yahoo.prelude.query.LocationItem": {
- "superClass": "com.yahoo.prelude.query.TermItem",
- "interfaces": [],
- "attributes": [
- "public"
- ],
- "methods": [
- "public void <init>(com.yahoo.prelude.Location)",
- "public void <init>(com.yahoo.prelude.Location, java.lang.String)",
- "public java.lang.String getRawWord()",
- "public com.yahoo.prelude.query.Item$ItemType getItemType()",
- "public java.lang.String getName()",
- "public java.lang.String stringValue()",
- "public void setValue(java.lang.String)",
- "public int hashCode()",
- "public boolean equals(java.lang.Object)",
- "public java.lang.String getIndexedString()",
- "protected void encodeThis(java.nio.ByteBuffer)",
- "public int getNumWords()",
- "public boolean isStemmed()",
- "public boolean isWords()"
- ],
- "fields": []
- },
"com.yahoo.prelude.query.MarkerWordItem": {
"superClass": "com.yahoo.prelude.query.WordItem",
"interfaces": [],
diff --git a/container-search/src/main/java/com/yahoo/prelude/Location.java b/container-search/src/main/java/com/yahoo/prelude/Location.java
index 908bf835e3c..dc98284df22 100644
--- a/container-search/src/main/java/com/yahoo/prelude/Location.java
+++ b/container-search/src/main/java/com/yahoo/prelude/Location.java
@@ -9,7 +9,7 @@ import java.util.StringTokenizer;
/**
* Location data for a geographical query.
*
- * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a>
+ * @author Steinar Knutsen
* @author arnej27959
*/
public class Location {
@@ -247,6 +247,10 @@ public class Location {
}
}
+ public Location clone() {
+ return new Location(toString());
+ }
+
public String toString() {
StringBuilder ser = new StringBuilder();
if (attribute != null) {
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/LocationItem.java b/container-search/src/main/java/com/yahoo/prelude/query/GeoLocationItem.java
index cf45712088b..8007bb823f2 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/LocationItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/GeoLocationItem.java
@@ -11,30 +11,31 @@ import java.nio.ByteBuffer;
*
* @author arnej
*/
-public class LocationItem extends TermItem {
+public class GeoLocationItem extends TermItem {
private Location location;
/**
*/
- public LocationItem(Location location) {
+ public GeoLocationItem(Location location) {
super(location.getAttribute(), false);
- this.location = location;
+ this.location = location.clone();
if (! location.hasAttribute()) {
throw new IllegalArgumentException("missing attribute on location: "+location);
}
+ location.setAttribute(null);
setNormalizable(false);
}
/**
*/
- public LocationItem(Location location, String indexName) {
+ public GeoLocationItem(Location location, String indexName) {
super(indexName, false);
- this.location = location;
+ this.location = location.clone();
if (location.hasAttribute() && ! location.getAttribute().equals(indexName)) {
throw new IllegalArgumentException("inconsistent attribute on location: "+location+" versus indexName: "+indexName);
}
- this.location.setAttribute(indexName);
+ location.setAttribute(null);
setNormalizable(false);
}
@@ -55,6 +56,7 @@ public class LocationItem extends TermItem {
@Override
public String stringValue() {
+ location.setAttribute(null);
return location.toString();
}
@@ -71,13 +73,14 @@ public class LocationItem extends TermItem {
@Override
public boolean equals(Object object) {
if ( ! super.equals(object)) return false;
- LocationItem other = (LocationItem) object; // Ensured by superclass
+ GeoLocationItem other = (GeoLocationItem) object; // Ensured by superclass
if ( ! location.equals(other.location)) return false;
return true;
}
@Override
public String getIndexedString() {
+ location.setAttribute(null);
return location.toString();
}
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 9910eb9532d..4ae2e4ceddd 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
@@ -6,6 +6,7 @@ import com.yahoo.collections.LazyMap;
import com.yahoo.language.Language;
import com.yahoo.language.process.Normalizer;
import com.yahoo.prelude.IndexFacts;
+import com.yahoo.prelude.Location;
import com.yahoo.prelude.query.AndItem;
import com.yahoo.prelude.query.BoolItem;
import com.yahoo.prelude.query.CompositeItem;
@@ -15,6 +16,7 @@ import com.yahoo.prelude.query.ExactStringItem;
import com.yahoo.prelude.query.IntItem;
import com.yahoo.prelude.query.Item;
import com.yahoo.prelude.query.Limit;
+import com.yahoo.prelude.query.GeoLocationItem;
import com.yahoo.prelude.query.NearItem;
import com.yahoo.prelude.query.NearestNeighborItem;
import com.yahoo.prelude.query.NotItem;
@@ -99,6 +101,7 @@ public class SelectParser implements Parser {
private static final String DOT_PRODUCT = "dotProduct";
private static final String EQUIV = "equiv";
private static final String FILTER = "filter";
+ private static final String GEO_LOCATION = "geoLocation";
private static final String HIT_LIMIT = "hitLimit";
private static final String HNSW_EXPLORE_ADDITIONAL_HITS = "hnsw.exploreAdditionalHits";
private static final String IMPLICIT_TRANSFORMS = "implicitTransforms";
@@ -135,7 +138,7 @@ public class SelectParser implements Parser {
private static final String CONTAINS = "contains";
private static final String MATCHES = "matches";
private static final String CALL = "call";
- private static final List<String> FUNCTION_CALLS = Arrays.asList(WAND, WEIGHTED_SET, DOT_PRODUCT, NEAREST_NEIGHBOR, PREDICATE, RANK, WEAK_AND);
+ private static final List<String> FUNCTION_CALLS = Arrays.asList(WAND, WEIGHTED_SET, DOT_PRODUCT, GEO_LOCATION, NEAREST_NEIGHBOR, PREDICATE, RANK, WEAK_AND);
public SelectParser(ParserEnvironment environment) {
indexFacts = environment.getIndexFacts();
@@ -264,6 +267,8 @@ public class SelectParser implements Parser {
return buildWeightedSet(key, value);
case DOT_PRODUCT:
return buildDotProduct(key, value);
+ case GEO_LOCATION:
+ return buildGeoLocation(key, value);
case NEAREST_NEIGHBOR:
return buildNearestNeighbor(key, value);
case PREDICATE:
@@ -410,6 +415,23 @@ public class SelectParser implements Parser {
return orItem;
}
+ 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());
+ String field = children.get(0).asString();
+ String location = children.get(1).asString();
+ GeoLocationItem item = new GeoLocationItem(new Location(location), field);
+ Inspector annotations = getAnnotations(value);
+ if (annotations != null){
+ annotations.traverse((ObjectTraverser) (annotation_name, annotation_value) -> {
+ if (LABEL.equals(annotation_name)) {
+ item.setLabel(annotation_value.asString());
+ }
+ });
+ }
+ return item;
+ }
+
private Item buildNearestNeighbor(String key, Inspector value) {
HashMap<Integer, Inspector> children = childMap(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 dd52b9e19b8..77250ecd439 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
@@ -16,6 +16,7 @@ import static com.yahoo.search.yql.YqlParser.DOT_PRODUCT;
import static com.yahoo.search.yql.YqlParser.END_ANCHOR;
import static com.yahoo.search.yql.YqlParser.EQUIV;
import static com.yahoo.search.yql.YqlParser.FILTER;
+import static com.yahoo.search.yql.YqlParser.GEO_LOCATION;
import static com.yahoo.search.yql.YqlParser.HIT_LIMIT;
import static com.yahoo.search.yql.YqlParser.IMPLICIT_TRANSFORMS;
import static com.yahoo.search.yql.YqlParser.LABEL;
@@ -72,6 +73,7 @@ import com.yahoo.prelude.query.ExactStringItem;
import com.yahoo.prelude.query.IndexedItem;
import com.yahoo.prelude.query.IntItem;
import com.yahoo.prelude.query.Item;
+import com.yahoo.prelude.query.GeoLocationItem;
import com.yahoo.prelude.query.MarkerWordItem;
import com.yahoo.prelude.query.NearItem;
import com.yahoo.prelude.query.NearestNeighborItem;
@@ -689,6 +691,23 @@ public class VespaSerializer {
}
+ private static class GeoLocationSerializer extends Serializer<GeoLocationItem> {
+ @Override
+ void onExit(StringBuilder destination, GeoLocationItem item) { }
+ @Override
+ boolean serialize(StringBuilder destination, GeoLocationItem item) {
+ String annotations = leafAnnotations(item);
+ if (annotations.length() > 0) {
+ destination.append("([{").append(annotations).append("}]");
+ }
+ destination.append(GEO_LOCATION).append('(');
+ destination.append(item.getIndexName()).append(", ").append('"');
+ escape(item.getIndexedString(), destination);
+ destination.append('"').append(')');
+ return false;
+ }
+ }
+
private static class NearestNeighborSerializer extends Serializer<NearestNeighborItem> {
@Override
@@ -1163,6 +1182,7 @@ public class VespaSerializer {
dispatchBuilder.put(EquivItem.class, new EquivSerializer());
dispatchBuilder.put(ExactStringItem.class, new WordSerializer());
dispatchBuilder.put(IntItem.class, new NumberSerializer());
+ dispatchBuilder.put(GeoLocationItem.class, new GeoLocationSerializer());
dispatchBuilder.put(BoolItem.class, new BoolSerializer());
dispatchBuilder.put(MarkerWordItem.class, new WordSerializer()); // gotcha
dispatchBuilder.put(NearItem.class, new NearSerializer());
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 7d17fe4f09d..a0bb4efb70b 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
@@ -24,6 +24,7 @@ import com.yahoo.language.detect.Detector;
import com.yahoo.language.process.Normalizer;
import com.yahoo.language.process.Segmenter;
import com.yahoo.prelude.IndexFacts;
+import com.yahoo.prelude.Location;
import com.yahoo.prelude.query.AndItem;
import com.yahoo.prelude.query.AndSegmentItem;
import com.yahoo.prelude.query.BoolItem;
@@ -34,6 +35,7 @@ import com.yahoo.prelude.query.ExactStringItem;
import com.yahoo.prelude.query.IntItem;
import com.yahoo.prelude.query.Item;
import com.yahoo.prelude.query.Limit;
+import com.yahoo.prelude.query.GeoLocationItem;
import com.yahoo.prelude.query.NearItem;
import com.yahoo.prelude.query.NearestNeighborItem;
import com.yahoo.prelude.query.NotItem;
@@ -149,6 +151,7 @@ public class YqlParser implements Parser {
static final String DOT_PRODUCT = "dotProduct";
static final String EQUIV = "equiv";
static final String FILTER = "filter";
+ static final String GEO_LOCATION = "geoLocation";
static final String HIT_LIMIT = "hitLimit";
static final String HNSW_EXPLORE_ADDITIONAL_HITS = "hnsw.exploreAdditionalHits";
static final String IMPLICIT_TRANSFORMS = "implicitTransforms";
@@ -372,6 +375,8 @@ public class YqlParser implements Parser {
return buildWeightedSet(ast);
case DOT_PRODUCT:
return buildDotProduct(ast);
+ case GEO_LOCATION:
+ return buildGeoLocation(ast);
case NEAREST_NEIGHBOR:
return buildNearestNeighbor(ast);
case PREDICATE:
@@ -413,6 +418,19 @@ public class YqlParser implements Parser {
return fillWeightedSet(ast, args.get(1), new DotProductItem(getIndex(args.get(0))));
}
+ 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());
+ String field = fetchFieldRead(args.get(0));
+ String location = fetchFieldRead(args.get(1));
+ GeoLocationItem item = new GeoLocationItem(new Location(location), field);
+ String label = getAnnotation(ast, LABEL, String.class, null, "item label");
+ if (label != null) {
+ item.setLabel(label);
+ }
+ return item;
+ }
+
private Item buildNearestNeighbor(OperatorNode<ExpressionOperator> ast) {
List<OperatorNode<ExpressionOperator>> args = ast.getArgument(1);
Preconditions.checkArgument(args.size() == 2, "Expected 2 arguments, got %s.", args.size());
@@ -438,7 +456,7 @@ public class YqlParser implements Parser {
item.setAllowApproximate(allowApproximate);
String label = getAnnotation(ast, LABEL, String.class, null, "item label");
if (label != null) {
- item.setLabel(label);
+ item.setLabel(label);
}
return item;
}