aboutsummaryrefslogtreecommitdiffstats
path: root/container-search/src/main/java/com
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@vespa.ai>2023-09-08 16:20:47 +0200
committerJon Bratseth <bratseth@vespa.ai>2023-09-08 16:20:47 +0200
commitcbf103929d33dc697cd5fac94adfba36ed501dc9 (patch)
treedeb10b43ce721d4e764a4392e0386ed2ddce1129 /container-search/src/main/java/com
parent4dd974027190e5f378556ebd4816fc1e7ebe7b21 (diff)
Synonym expansions
Diffstat (limited to 'container-search/src/main/java/com')
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/CompositeItem.java4
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/EquivItem.java5
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/PhraseItem.java12
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/semantics/engine/Evaluation.java54
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/semantics/engine/RuleEvaluation.java4
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/semantics/rule/LiteralPhraseProduction.java12
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/semantics/rule/TermProduction.java4
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());