summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@verizonmedia.com>2019-08-26 09:57:11 +0200
committerJon Bratseth <bratseth@verizonmedia.com>2019-08-26 09:57:11 +0200
commitba19f25e9c707e04f5f027376756d02d4c483cce (patch)
treeda38514883f22cb8eee5ddcc25a5199b619a6f5d
parent78133f8c95b11b460aa4fd9ad89bd00bb716c6f8 (diff)
Supoprt and'ing two not's
-rw-r--r--container-search/abi-spec.json1
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/NotItem.java10
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/QueryTree.java47
-rw-r--r--container-search/src/test/java/com/yahoo/search/query/QueryTreeTest.java18
4 files changed, 56 insertions, 20 deletions
diff --git a/container-search/abi-spec.json b/container-search/abi-spec.json
index 6c68260df32..164794243ec 100644
--- a/container-search/abi-spec.json
+++ b/container-search/abi-spec.json
@@ -872,6 +872,7 @@
"public java.lang.String getName()",
"public void addItem(com.yahoo.prelude.query.Item)",
"public void addNegativeItem(com.yahoo.prelude.query.Item)",
+ "public java.util.List negativeItems()",
"public com.yahoo.prelude.query.Item getPositiveItem()",
"public com.yahoo.prelude.query.Item setPositiveItem(com.yahoo.prelude.query.Item)",
"public void addPositiveItem(com.yahoo.prelude.query.Item)",
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/NotItem.java b/container-search/src/main/java/com/yahoo/prelude/query/NotItem.java
index 702d90bec94..ab1e1b4bd33 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/NotItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/NotItem.java
@@ -3,14 +3,15 @@ package com.yahoo.prelude.query;
import com.yahoo.protect.Validator;
+import java.util.Collections;
import java.util.Iterator;
-
+import java.util.List;
/**
- * <p>A composite item where the first item is positive and the following
+ * A composite item where the first item is positive and the following
* items are negative items which should be excluded from the result.
*
- * @author bratseth
+ * @author bratseth
*/
// TODO: Handle nulls by creating nullItem or checking in encode/toString
public class NotItem extends CompositeItem {
@@ -42,6 +43,9 @@ public class NotItem extends CompositeItem {
addItem(negative);
}
+ /** Returns the negative items of this: All child items except the first */
+ public List<Item> negativeItems() { return items().subList(1, getItemCount()); }
+
/**
* Returns the positive item (the first subitem),
* or null if no positive items has been added
diff --git a/container-search/src/main/java/com/yahoo/search/query/QueryTree.java b/container-search/src/main/java/com/yahoo/search/query/QueryTree.java
index 6eba6ae4837..1bf176e2131 100644
--- a/container-search/src/main/java/com/yahoo/search/query/QueryTree.java
+++ b/container-search/src/main/java/com/yahoo/search/query/QueryTree.java
@@ -114,31 +114,44 @@ public class QueryTree extends CompositeItem {
* @return the resulting root item in this
*/
public Item and(Item item) {
- if (isEmpty()) {
- setRoot(item);
+ Item result = and(getRoot(), item);
+ setRoot(result);
+ return result;
+ }
+
+ private Item and(Item a, Item b) {
+ if (a == null || a instanceof NullItem) {
+ return b;
}
- else if (getRoot() instanceof NotItem && item instanceof NotItem) {
- throw new IllegalArgumentException("Can't AND two NOTs"); // TODO: Complete
+ else if (a instanceof NotItem && b instanceof NotItem) {
+ NotItem notItemA = (NotItem)a;
+ NotItem notItemB = (NotItem)b;
+ NotItem combined = new NotItem();
+ combined.addPositiveItem(and(notItemA.getPositiveItem(), notItemB.getPositiveItem()));
+ notItemA.negativeItems().forEach(item -> combined.addNegativeItem(item));
+ notItemB.negativeItems().forEach(item -> combined.addNegativeItem(item));
+ return combined;
}
- else if (getRoot() instanceof NotItem){
- NotItem notItem = (NotItem)getRoot();
- notItem.addPositiveItem(item);
+ else if (a instanceof NotItem){
+ NotItem notItem = (NotItem)a;
+ notItem.addPositiveItem(b);
+ return a;
}
- else if (item instanceof NotItem){
- NotItem notItem = (NotItem)item;
- notItem.addPositiveItem(getRoot());
- setRoot(notItem);
+ else if (b instanceof NotItem){
+ NotItem notItem = (NotItem)b;
+ notItem.addPositiveItem(a);
+ return notItem;
}
- else if (getRoot() instanceof AndItem) {
- ((AndItem) getRoot()).addItem(item);
+ else if (a instanceof AndItem) {
+ ((AndItem)a).addItem(b);
+ return a;
}
else {
AndItem andItem = new AndItem();
- andItem.addItem(getRoot());
- andItem.addItem(item);
- setRoot(andItem);
+ andItem.addItem(a);
+ andItem.addItem(b);
+ return andItem;
}
- return getRoot();
}
/** Returns a flattened list of all positive query terms under the given item */
diff --git a/container-search/src/test/java/com/yahoo/search/query/QueryTreeTest.java b/container-search/src/test/java/com/yahoo/search/query/QueryTreeTest.java
index f929e54fd2d..c55c9531e49 100644
--- a/container-search/src/test/java/com/yahoo/search/query/QueryTreeTest.java
+++ b/container-search/src/test/java/com/yahoo/search/query/QueryTreeTest.java
@@ -23,4 +23,22 @@ public class QueryTreeTest {
new QueryTree(new WordItem("a")).and(not).toString());
}
+ @Test
+ public void addNotToNot() {
+ NotItem not1 = new NotItem();
+ not1.addPositiveItem(new WordItem("p1"));
+ not1.addNegativeItem(new WordItem("n1.1"));
+ not1.addNegativeItem(new WordItem("n1.2"));
+
+ NotItem not2 = new NotItem();
+ not2.addPositiveItem(new WordItem("p2"));
+ not2.addNegativeItem(new WordItem("n2.1"));
+ not2.addNegativeItem(new WordItem("n2.2"));
+
+ QueryTree tree = new QueryTree(not1);
+ tree.and(not2);
+
+ assertEquals("+(AND p1 p2) -n1.1 -n1.2 -n2.1 -n2.2", tree.toString());
+ }
+
}