diff options
author | Jon Bratseth <bratseth@verizonmedia.com> | 2019-08-26 09:57:11 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@verizonmedia.com> | 2019-08-26 09:57:11 +0200 |
commit | ba19f25e9c707e04f5f027376756d02d4c483cce (patch) | |
tree | da38514883f22cb8eee5ddcc25a5199b619a6f5d | |
parent | 78133f8c95b11b460aa4fd9ad89bd00bb716c6f8 (diff) |
Supoprt and'ing two not's
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()); + } + } |