diff options
author | Jon Bratseth <bratseth@vespa.ai> | 2023-09-08 16:20:47 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@vespa.ai> | 2023-09-08 16:20:47 +0200 |
commit | cbf103929d33dc697cd5fac94adfba36ed501dc9 (patch) | |
tree | deb10b43ce721d4e764a4392e0386ed2ddce1129 /container-search/src/main/java/com | |
parent | 4dd974027190e5f378556ebd4816fc1e7ebe7b21 (diff) |
Synonym expansions
Diffstat (limited to 'container-search/src/main/java/com')
7 files changed, 59 insertions, 36 deletions
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 30c02944f19..407e763c1e5 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 @@ -311,6 +311,10 @@ public abstract class CompositeItem extends Item { return getItemCount() == 1 ? Optional.of(getItem(0)) : Optional.empty(); } + public boolean acceptsItemsOfType(ItemType itemType) { + return true; + } + /** Handles mutator calls correctly */ private static class ListIteratorWrapper implements ListIterator<Item> { diff --git a/container-search/src/main/java/com/yahoo/prelude/query/EquivItem.java b/container-search/src/main/java/com/yahoo/prelude/query/EquivItem.java index 43258db8963..de317ac317e 100644 --- a/container-search/src/main/java/com/yahoo/prelude/query/EquivItem.java +++ b/container-search/src/main/java/com/yahoo/prelude/query/EquivItem.java @@ -86,6 +86,11 @@ public class EquivItem extends CompositeTaggableItem { acceptsChildrenOfType(item.getItemType())); } + @Override + public boolean acceptsItemsOfType(ItemType itemType) { + return acceptsChildrenOfType(itemType); + } + /** Returns true if this accepts child items of the given type */ public static boolean acceptsChildrenOfType(ItemType itemType) { return itemType == ItemType.WORD || 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 379dfd6bb30..09be603740f 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 @@ -93,6 +93,15 @@ public class PhraseItem extends CompositeIndexedItem { } @Override + public boolean acceptsItemsOfType(ItemType itemType) { + return itemType == ItemType.WORD || + itemType == ItemType.WORD_ALTERNATIVES || + itemType == ItemType.INT || + itemType == ItemType.EXACT || + itemType == ItemType.PHRASE; + } + + @Override public void addItem(int index, Item item) { if (item instanceof WordItem || item instanceof PhraseSegmentItem) { addIndexedItem(index, (IndexedItem) item); @@ -115,8 +124,7 @@ public class PhraseItem extends CompositeIndexedItem { return setIndexedItem(index, (IndexedItem) item); } else if (item instanceof IntItem) { return setIndexedItem(index, convertIntToWord(item)); - } else if (item instanceof PhraseItem) { - PhraseItem phrase = (PhraseItem) item; + } else if (item instanceof PhraseItem phrase) { Iterator<Item> i = phrase.getItemIterator(); // we assume we don't try to add empty phrases IndexedItem firstItem = (IndexedItem) i.next(); diff --git a/container-search/src/main/java/com/yahoo/prelude/semantics/engine/Evaluation.java b/container-search/src/main/java/com/yahoo/prelude/semantics/engine/Evaluation.java index d5ed89b0724..76f42bf0d9f 100644 --- a/container-search/src/main/java/com/yahoo/prelude/semantics/engine/Evaluation.java +++ b/container-search/src/main/java/com/yahoo/prelude/semantics/engine/Evaluation.java @@ -199,9 +199,8 @@ public class Evaluation { CompositeItem converted; if (item instanceof AndSegmentItem) { converted = new AndItem(); - } else if (item instanceof PhraseSegmentItem) { + } else if (item instanceof PhraseSegmentItem old) { PhraseItem p = new PhraseItem(); - PhraseSegmentItem old = (PhraseSegmentItem) item; p.setIndexName(old.getIndexName()); converted = p; } else { @@ -250,7 +249,7 @@ public class Evaluation { * @param index the index at which to insert these into the parent * @param desiredParentType the desired type of the composite which contains items when this returns */ - public void insertItems(List<Item> items, CompositeItem parent, int index, TermType desiredParentType) { + public void insertItems(List<Item> items, CompositeItem parent, int index, TermType desiredParentType, boolean replacing) { if (isEmpty(parent)) { if (items.size() == 1 && desiredParentType.hasItemClass(items.get(0).getClass())) { query.getModel().getQueryTree().setRoot(items.get(0)); @@ -286,7 +285,7 @@ public class Evaluation { addItem(parent, index, items.get(0), desiredParentType); } else { - insertWithDesiredParentType(items, parent, desiredParentType); + insertWithDesiredParentType(items, index, parent, desiredParentType, replacing); } } @@ -329,36 +328,50 @@ public class Evaluation { /** A special purpose check used to simplify the above */ private boolean equalIndexNameIfParentIsPhrase(List<Item> items, CompositeItem parent) { - if ( ! (parent instanceof PhraseItem)) return true; - var phrase = (PhraseItem)parent; + if ( ! (parent instanceof PhraseItem phrase)) return true; for (Item item : items) { - if ( ! (item instanceof IndexedItem)) continue; - var indexedItem = (IndexedItem)item; + if ( ! (item instanceof IndexedItem indexedItem)) continue; if (! indexedItem.getIndexName().equals(phrase.getIndexName())) return false; } return true; } - private void insertWithDesiredParentType(List<Item> items, CompositeItem parent, TermType desiredParentType) { + private void insertWithDesiredParentType(List<Item> items, int index, CompositeItem parent, TermType desiredParentType, boolean replacing) { CompositeItem parentsParent = parent.getParent(); CompositeItem newParent = newParent(desiredParentType); - if (! (parentsParent instanceof QueryTree) && parentsParent.getItemType() == newParent.getItemType()) { // Collapse + if (parentsParent != null && (! (parentsParent instanceof QueryTree) && parentsParent.getItemType() == newParent.getItemType())) { // Collapse newParent = parentsParent; } for (Item item : items) newParent.addItem(item); - if (desiredParentType == TermType.EQUIV || desiredParentType == TermType.PHRASE) { // insert new parent below the current - parent.addItem(newParent); + Item current = parent; + if (parent instanceof QueryTree && parent.getItemCount() > 0) + current = parent.getItem(0); + if (current instanceof CompositeItem && !replacing) { // insert new parent below the current + if (parent.getItemCount() > index) { + var combinedItem = combineItems(newParent, parent.getItem(index), desiredParentType); + parent.setItem(index, combinedItem); + } + else{ + parent.addItem(newParent); + } + } + else if (newParent.acceptsItemsOfType(current.getItemType())) { // insert new parent above the current + newParent.addItem(current); + if (newParent != parentsParent) { // Insert new parent as root or child of old parent's parent + if (parentsParent != null) + parentsParent.setItem(parentsParent.getItemIndex(current), newParent); + else + parent.setItem(0, newParent); + } } - else { // insert new parent above the current - newParent.addItem(parent); - if (newParent != parentsParent) // Insert new parent as root or child of old parent's parent - parentsParent.setItem(parentsParent.getItemIndex(parent), newParent); + else { + ((CompositeItem)current).addItem(newParent); // not an acceptable child -> composite } } @@ -369,8 +382,7 @@ public class Evaluation { private Item combineItems(Item first, Item second, TermType termType) { if (first instanceof NullItem) { return second; - } else if (first instanceof NotItem) { - NotItem notItem = (NotItem)first; + } else if (first instanceof NotItem notItem) { if (termType == TermType.NOT) { notItem.addNegativeItem(second); } @@ -380,8 +392,7 @@ public class Evaluation { } return notItem; } - else if (first instanceof CompositeItem) { - CompositeItem composite = (CompositeItem)first; + else if (first instanceof CompositeItem composite) { CompositeItem combined = createType(termType); if (combined.getClass().equals(composite.getClass())) { composite.addItem(second); @@ -419,6 +430,9 @@ public class Evaluation { phrase.setIndexName(index); return phrase; } + else if ((item instanceof CompositeItem) && ((CompositeItem)item).getItemCount() == 1) { + return makeEquivCompatible(((CompositeItem)item).getItem(0)); + } else { return item; // Compatible, or can't be made so } diff --git a/container-search/src/main/java/com/yahoo/prelude/semantics/engine/RuleEvaluation.java b/container-search/src/main/java/com/yahoo/prelude/semantics/engine/RuleEvaluation.java index efb02034db9..214dec3920c 100644 --- a/container-search/src/main/java/com/yahoo/prelude/semantics/engine/RuleEvaluation.java +++ b/container-search/src/main/java/com/yahoo/prelude/semantics/engine/RuleEvaluation.java @@ -270,8 +270,8 @@ public class RuleEvaluation { * @param index the index at which to insert this into the parent * @param termType the kind of item to index, this decides the resulting structure */ - public void insertItems(List<Item> items, CompositeItem parent, int index, TermType termType) { - evaluation.insertItems(items, parent, index, termType); + public void insertItems(List<Item> items, CompositeItem parent, int index, TermType termType, boolean replacing) { + evaluation.insertItems(items, parent, index, termType, replacing); } /** Returns a read-only view of the items of this */ diff --git a/container-search/src/main/java/com/yahoo/prelude/semantics/rule/LiteralPhraseProduction.java b/container-search/src/main/java/com/yahoo/prelude/semantics/rule/LiteralPhraseProduction.java index af7aab23b85..aafb740de1d 100644 --- a/container-search/src/main/java/com/yahoo/prelude/semantics/rule/LiteralPhraseProduction.java +++ b/container-search/src/main/java/com/yahoo/prelude/semantics/rule/LiteralPhraseProduction.java @@ -50,16 +50,8 @@ public class LiteralPhraseProduction extends TermProduction { for (String term : terms) newPhrase.addItem(new WordItem(term)); - if (replacing) { - Match matched = e.getNonreferencedMatch(0); - insertMatch(e, matched, List.of(newPhrase), offset); - } - else { - newPhrase.setWeight(getWeight()); - if (e.getTraceLevel() >= 6) - e.trace(6, "Adding '" + newPhrase + "'"); - e.addItems(List.of(newPhrase), getTermType()); - } + Match matched = e.getNonreferencedMatch(0); + insertMatch(e, matched, List.of(newPhrase), offset); } public String toInnerTermString() { diff --git a/container-search/src/main/java/com/yahoo/prelude/semantics/rule/TermProduction.java b/container-search/src/main/java/com/yahoo/prelude/semantics/rule/TermProduction.java index 41d15bc9262..932908a32dc 100644 --- a/container-search/src/main/java/com/yahoo/prelude/semantics/rule/TermProduction.java +++ b/container-search/src/main/java/com/yahoo/prelude/semantics/rule/TermProduction.java @@ -58,7 +58,7 @@ public abstract class TermProduction extends Production { } /** - * Inserts newItem at the position of this match + * Inserts newItems at the position of this match * TODO: Move to ruleevaluation */ protected void insertMatch(RuleEvaluation e, Match matched, List<Item> newItems, int offset) { @@ -73,7 +73,7 @@ public abstract class TermProduction extends Production { insertPosition = matched.getParent().getItemCount(); } - e.insertItems(newItems, matched.getParent(), insertPosition, getTermType()); + e.insertItems(newItems, matched.getParent(), insertPosition, getTermType(), replacing); if (e.getTraceLevel() >= 6) e.trace(6, "Inserted items '" + newItems + "' at position " + insertPosition + " producing " + e.getEvaluation().getQuery().getModel().getQueryTree()); |