diff options
Diffstat (limited to 'container-search/src/main/java/com/yahoo/search/querytransform/WeakAndReplacementSearcher.java')
-rw-r--r-- | container-search/src/main/java/com/yahoo/search/querytransform/WeakAndReplacementSearcher.java | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/querytransform/WeakAndReplacementSearcher.java b/container-search/src/main/java/com/yahoo/search/querytransform/WeakAndReplacementSearcher.java new file mode 100644 index 00000000000..058f6b93ae3 --- /dev/null +++ b/container-search/src/main/java/com/yahoo/search/querytransform/WeakAndReplacementSearcher.java @@ -0,0 +1,66 @@ +package com.yahoo.search.querytransform; + +import com.yahoo.prelude.query.*; +import com.yahoo.processing.request.CompoundName; +import com.yahoo.search.Query; +import com.yahoo.search.Result; +import com.yahoo.search.Searcher; +import com.yahoo.search.searchchain.Execution; + +/** + * Recursively replaces all instances of OrItems with WeakAndItems if the query property weakand.replace is true. + * Otherwise a noop searcher. + * + * @author karowan + */ +public class WeakAndReplacementSearcher extends Searcher { + private static final CompoundName WEAKAND_REPLACE = new CompoundName("weakAnd.replace"); + + @Override public Result search(Query query, Execution execution) { + if (!query.properties().getBoolean(WEAKAND_REPLACE)) { + return execution.search(query); + } + replaceOrItems(query); + return execution.search(query); + } + + /** + * Extracts the queryTree root and the wand.hits property to send to the recursive replacement function + * @param query the search query + */ + private void replaceOrItems(Query query) { + Item root = query.getModel().getQueryTree().getRoot(); + int hits = query.properties().getInteger("wand.hits", WeakAndItem.defaultN); + query.getModel().getQueryTree().setRoot(replaceOrItems(root, hits)); + if (root != query.getModel().getQueryTree().getRoot()) + query.trace("Replaced OR by WeakAnd", true, 2); + } + + + /** + * Recursively iterates over an Item to replace all instances of OrItems with WeakAndItems + * @param item the current item in the replacement iteration + * @param hits the wand.hits property from the request which is assigned to the N value of the new WeakAndItem + * @return The original item or a WeakAndItem replacement of an OrItem + */ + private Item replaceOrItems(Item item, int hits) { + if (!(item instanceof CompositeItem)) { + return item; + } + CompositeItem compositeItem = (CompositeItem) item; + if (compositeItem instanceof OrItem) { + WeakAndItem newItem = new WeakAndItem(hits); + newItem.setWeight(compositeItem.getWeight()); + compositeItem.items().forEach(newItem::addItem); + compositeItem = newItem; + } + for (int i = 0; i < compositeItem.getItemCount(); i++) { + Item subItem = compositeItem.getItem(i); + Item replacedItem = replaceOrItems(subItem, hits); + if (replacedItem != subItem) { + compositeItem.setItem(i, replacedItem); + } + } + return compositeItem; + } +} |