summaryrefslogtreecommitdiffstats
path: root/container-search
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2019-06-28 13:54:27 +0200
committerGitHub <noreply@github.com>2019-06-28 13:54:27 +0200
commita71b139ba48f64787d1a37aae636f76b0f0bc550 (patch)
tree80d711fb3f226f28b04a07481edb47b6fa19d885 /container-search
parentb1f7cfdf97851cdd20c0a00ee26fae0264ea77c2 (diff)
parente1010883fb684c1e941cf2d49778c86e179ecb9e (diff)
Merge pull request #9918 from vespa-engine/balder/collapse-single-child-under-sameElement
A single element under sameElement operator can be pulled out to avoi…
Diffstat (limited to 'container-search')
-rw-r--r--container-search/abi-spec.json7
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/CompositeItem.java10
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/NonReducibleCompositeItem.java6
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/PhraseItem.java8
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/PhraseSegmentItem.java11
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/QueryCanonicalizer.java13
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/SameElementItem.java11
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/querytransform/QueryRewrite.java3
-rw-r--r--container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java2
9 files changed, 60 insertions, 11 deletions
diff --git a/container-search/abi-spec.json b/container-search/abi-spec.json
index 8f9dc33e944..cc06710480d 100644
--- a/container-search/abi-spec.json
+++ b/container-search/abi-spec.json
@@ -436,6 +436,7 @@
"public void lock()",
"public boolean isLocked()",
"public int getTermCount()",
+ "public java.util.Optional extractSingleChild()",
"public bridge synthetic com.yahoo.prelude.query.Item clone()",
"public bridge synthetic java.lang.Object clone()"
],
@@ -854,7 +855,8 @@
"abstract"
],
"methods": [
- "public void <init>()"
+ "public void <init>()",
+ "public java.util.Optional extractSingleChild()"
],
"fields": []
},
@@ -944,6 +946,7 @@
"public void addItem(com.yahoo.prelude.query.Item)",
"public void addItem(int, com.yahoo.prelude.query.Item)",
"public com.yahoo.prelude.query.Item setItem(int, com.yahoo.prelude.query.Item)",
+ "public java.util.Optional extractSingleChild()",
"public com.yahoo.prelude.query.WordItem getWordItem(int)",
"public com.yahoo.prelude.query.BlockItem getBlockItem(int)",
"protected void encodeThis(java.nio.ByteBuffer)",
@@ -974,6 +977,7 @@
"public void setIndexName(java.lang.String)",
"public void setWeight(int)",
"public void addItem(com.yahoo.prelude.query.Item)",
+ "public java.util.Optional extractSingleChild()",
"public com.yahoo.prelude.query.WordItem getWordItem(int)",
"protected void encodeThis(java.nio.ByteBuffer)",
"public int encode(java.nio.ByteBuffer)",
@@ -1239,6 +1243,7 @@
"protected void appendHeadingString(java.lang.StringBuilder)",
"protected void appendBodyString(java.lang.StringBuilder)",
"protected void adding(com.yahoo.prelude.query.Item)",
+ "public java.util.Optional extractSingleChild()",
"public com.yahoo.prelude.query.Item$ItemType getItemType()",
"public java.lang.String getName()",
"public java.lang.String getFieldName()"
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/CompositeItem.java b/container-search/src/main/java/com/yahoo/prelude/query/CompositeItem.java
index 907eabe60ce..64f759dcf9c 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/CompositeItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/CompositeItem.java
@@ -13,6 +13,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
+import java.util.Optional;
/**
@@ -379,4 +380,13 @@ public abstract class CompositeItem extends Item {
return terms;
}
+ /**
+ * Will return its single child if itself can safely be omitted.
+ *
+ * @return a valid Item or empty Optional if it can not be done
+ */
+ public Optional<Item> extractSingleChild() {
+ return getItemCount() == 1 ? Optional.of(getItem(0)) : Optional.empty();
+ }
+
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/NonReducibleCompositeItem.java b/container-search/src/main/java/com/yahoo/prelude/query/NonReducibleCompositeItem.java
index 84aa177369a..97d724953ea 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/NonReducibleCompositeItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/NonReducibleCompositeItem.java
@@ -1,6 +1,8 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.prelude.query;
+import java.util.Optional;
+
/**
* A composite item which specifies semantics which are not maintained
* if an instance with a single child is replaced by the single child.
@@ -12,4 +14,8 @@ package com.yahoo.prelude.query;
* @author bratseth
*/
public abstract class NonReducibleCompositeItem extends CompositeItem {
+ @Override
+ public Optional<Item> extractSingleChild() {
+ return Optional.empty();
+ }
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/PhraseItem.java b/container-search/src/main/java/com/yahoo/prelude/query/PhraseItem.java
index 26da5eec7eb..4de0af1f408 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/PhraseItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/PhraseItem.java
@@ -5,6 +5,7 @@ import com.yahoo.prelude.query.textualrepresentation.Discloser;
import java.nio.ByteBuffer;
import java.util.Iterator;
+import java.util.Optional;
/**
* A term which contains a phrase - a collection of word terms
@@ -127,6 +128,13 @@ public class PhraseItem extends CompositeIndexedItem {
}
}
+ @Override
+ public Optional<Item> extractSingleChild() {
+ Optional<Item> extracted = super.extractSingleChild();
+ extracted.ifPresent(e -> e.setWeight(this.getWeight()));
+ return extracted;
+ }
+
private void addIndexedItem(IndexedItem word) {
word.setIndexName(this.getIndexName());
super.addItem((Item) word);
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/PhraseSegmentItem.java b/container-search/src/main/java/com/yahoo/prelude/query/PhraseSegmentItem.java
index a19a6e53963..53a57a968f5 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/PhraseSegmentItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/PhraseSegmentItem.java
@@ -5,6 +5,7 @@ import com.yahoo.prelude.query.textualrepresentation.Discloser;
import java.nio.ByteBuffer;
import java.util.Iterator;
+import java.util.Optional;
/**
@@ -55,10 +56,12 @@ public class PhraseSegmentItem extends IndexedSegmentItem {
super(rawWord, current, isFromQuery, stemmed, substring);
}
+ @Override
public ItemType getItemType() {
return ItemType.PHRASE;
}
+ @Override
public String getName() {
return "SPHRASE";
}
@@ -87,6 +90,7 @@ public class PhraseSegmentItem extends IndexedSegmentItem {
*
* @throws IllegalArgumentException if the given item is not a WordItem or PhraseItem
*/
+ @Override
public void addItem(Item item) {
if (item instanceof WordItem) {
addWordItem((WordItem) item);
@@ -95,6 +99,13 @@ public class PhraseSegmentItem extends IndexedSegmentItem {
}
}
+ @Override
+ public Optional<Item> extractSingleChild() {
+ Optional<Item> extracted = super.extractSingleChild();
+ extracted.ifPresent(e -> e.setWeight(this.getWeight()));
+ return extracted;
+ }
+
private void addWordItem(WordItem word) {
word.setIndexName(this.getIndexName());
super.addItem(word);
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/QueryCanonicalizer.java b/container-search/src/main/java/com/yahoo/prelude/query/QueryCanonicalizer.java
index 31e69e5b7cd..88bae76b26d 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/QueryCanonicalizer.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/QueryCanonicalizer.java
@@ -4,7 +4,10 @@ package com.yahoo.prelude.query;
import com.yahoo.search.Query;
import com.yahoo.search.query.QueryTree;
-import java.util.*;
+import java.util.HashSet;
+import java.util.ListIterator;
+import java.util.Optional;
+import java.util.Set;
/**
* Query normalizer and sanity checker.
@@ -82,15 +85,11 @@ public class QueryCanonicalizer {
if (composite.getItemCount() == 0)
parentIterator.remove();
- if (composite.getItemCount() == 1 && ! (composite instanceof NonReducibleCompositeItem)) {
- if (composite instanceof PhraseItem || composite instanceof PhraseSegmentItem)
- composite.getItem(0).setWeight(composite.getWeight());
- parentIterator.set(composite.getItem(0));
- }
+ composite.extractSingleChild().ifPresent(extractedChild -> parentIterator.set(extractedChild));
return CanonicalizationResult.success();
}
-
+
private static void collapseLevels(CompositeItem composite) {
if (composite instanceof RankItem || composite instanceof NotItem) {
collapseLevels(composite, composite.getItemIterator()); // collapse the first item only
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/SameElementItem.java b/container-search/src/main/java/com/yahoo/prelude/query/SameElementItem.java
index aa446140da0..d2c19339298 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/SameElementItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/SameElementItem.java
@@ -6,6 +6,7 @@ import com.yahoo.protect.Validator;
import java.nio.ByteBuffer;
import java.util.Iterator;
+import java.util.Optional;
/**
* This represents a query where all terms are required to match in the same element id.
@@ -54,6 +55,16 @@ public class SameElementItem extends NonReducibleCompositeItem {
Validator.ensureNonEmpty("Struct fieldname", asTerm.getIndexName());
Validator.ensureNonEmpty("Query term", asTerm.getIndexedString());
}
+
+ @Override
+ public Optional<Item> extractSingleChild() {
+ if (getItemCount() == 1) {
+ WordItem child = (WordItem) getItem(0);
+ child.setIndexName(getFieldName() + "." + child.getIndexName());
+ return Optional.of(child);
+ }
+ return Optional.empty();
+ }
@Override
public ItemType getItemType() {
diff --git a/container-search/src/main/java/com/yahoo/prelude/querytransform/QueryRewrite.java b/container-search/src/main/java/com/yahoo/prelude/querytransform/QueryRewrite.java
index 2d941681f2a..84c793a6df1 100644
--- a/container-search/src/main/java/com/yahoo/prelude/querytransform/QueryRewrite.java
+++ b/container-search/src/main/java/com/yahoo/prelude/querytransform/QueryRewrite.java
@@ -6,7 +6,6 @@ import com.yahoo.prelude.query.CompositeItem;
import com.yahoo.prelude.query.EquivItem;
import com.yahoo.prelude.query.Item;
import com.yahoo.prelude.query.NearItem;
-import com.yahoo.prelude.query.NonReducibleCompositeItem;
import com.yahoo.prelude.query.NotItem;
import com.yahoo.prelude.query.NullItem;
import com.yahoo.prelude.query.OrItem;
@@ -215,7 +214,7 @@ public class QueryRewrite {
parent.setItem(i, newChild);
}
}
- return ((numChildren == 1) && !(parent instanceof NonReducibleCompositeItem)) ? parent.getItem(0) : item;
+ return parent.extractSingleChild().orElse(item);
}
private static Item rewriteSddocname(Item item) {
diff --git a/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java b/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java
index 70d50b23bed..00a17f963c6 100644
--- a/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java
@@ -303,7 +303,7 @@ public class YqlParserTestCase {
assertCanonicalParse("select foo from bar where baz contains sameElement(key contains \"a\", value.f2 = 10);",
"baz:{key:a value.f2:10}");
assertCanonicalParse("select foo from bar where baz contains sameElement(key contains \"a\");",
- "baz:{key:a}");
+ "baz.key:a");
}
@Test