Skip to content

Commit

Permalink
Merge pull request #32279 from vespa-engine/bratseth/gram-root
Browse files Browse the repository at this point in the history
Make the gram root settable
  • Loading branch information
bratseth authored Aug 28, 2024
2 parents feb9ff2 + d0e2471 commit 4abdba0
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,16 @@
import com.yahoo.prelude.query.CompositeItem;
import com.yahoo.prelude.query.HasIndexItem;
import com.yahoo.prelude.query.Item;
import com.yahoo.prelude.query.NearItem;
import com.yahoo.prelude.query.ONearItem;
import com.yahoo.prelude.query.OrItem;
import com.yahoo.prelude.query.PhraseItem;
import com.yahoo.prelude.query.SegmentItem;
import com.yahoo.prelude.query.Substring;
import com.yahoo.prelude.query.TermItem;
import com.yahoo.prelude.query.WeakAndItem;
import com.yahoo.prelude.query.WordItem;
import com.yahoo.processing.request.CompoundName;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
import com.yahoo.search.Searcher;
Expand All @@ -44,6 +49,8 @@
@After(JUNIPER_TAG_REPLACING)
public class NGramSearcher extends Searcher {

private static final CompoundName gramMatch = CompoundName.from("gram.match");

private final GramSplitter gramSplitter;

private final CharacterClasses characterClasses;
Expand Down Expand Up @@ -151,7 +158,16 @@ protected CompositeItem createGramRoot(HasIndexItem term, Query query) {

/** Creates the root of the query subtree without access to the term being replaced. */
protected CompositeItem createGramRoot(Query query) {
return new AndItem();
return switch (query.properties().getString(gramMatch, "all")) {
case "all" -> new AndItem();
case "any" -> new OrItem();
case "weakAnd" -> new WeakAndItem();
case "phrase" -> new PhraseItem();
case "near" -> new NearItem();
case "onear" -> new ONearItem();
default -> throw new IllegalArgumentException("Invalid gram.match value '" + query.properties().getString(gramMatch) +
"'. Must be 'all', 'any', 'weakAnd', 'phrase', 'near' or 'onear'");
};
}

private void replaceItemByGrams(Item item, Item grams, int indexInParent) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,30 @@ void testNGramRewritingShortOnly() {
assertEquals("WEAKAND(100) gram3:en", q.getModel().getQueryTree().toString());
}

@Test
void testSettingGramMatching() {
assertEquals("WEAKAND(100) (AND gram2:en gram2:ng)", search("?query=gram2:eng"));
assertEquals("WEAKAND(100) (AND gram2:en gram2:ng)", search("?query=gram2:eng&gram.match=all"));
assertEquals("WEAKAND(100) (OR gram2:en gram2:ng)", search("?query=gram2:eng&gram.match=any"));
assertEquals("WEAKAND(100) (WEAKAND(100) gram2:en gram2:ng)", search("?query=gram2:eng&gram.match=weakAnd"));
assertEquals("WEAKAND(100) gram2:\"en ng\"", search("?query=gram2:eng&gram.match=phrase"));
assertEquals("WEAKAND(100) (NEAR(2) gram2:en gram2:ng)", search("?query=gram2:eng&gram.match=near"));
assertEquals("WEAKAND(100) (ONEAR(2) gram2:en gram2:ng)", search("?query=gram2:eng&gram.match=onear"));
try {
search("?query=gram2:eng&gram.match=invalid");
fail("Expected exception");
} catch (IllegalArgumentException e) {
assertEquals("Invalid gram.match value 'invalid'. Must be 'all', 'any', 'weakAnd', 'phrase', 'near' or 'onear'",
e.getMessage());
}
}

String search(String query) {
Query q = new Query(query);
createExecution().search(q);
return q.getModel().getQueryTree().toString();
}

@Test
void testNGramRewritingShortInMixes() {
Query q = new Query("?query=test:a+gram3:en");
Expand Down Expand Up @@ -335,19 +359,19 @@ void testNGramRecombining() {
Hit h1 = r.hits().get("hit1");
assertEquals("Should be untouched,\u001feven if containing \u001f",
h1.getField("test").toString());
assertTrue(h1.getField("test") instanceof String);
assertInstanceOf(String.class, h1.getField("test"));

assertEquals("Blue red Ed A", h1.getField("gram2").toString());
assertTrue(h1.getField("gram2") instanceof XMLString);
assertInstanceOf(XMLString.class, h1.getField("gram2"));

assertEquals("Blue red ed a\u001f",
h1.getField("gram3").toString(),
"Separators on borders work");
assertTrue(h1.getField("gram3") instanceof String);
assertInstanceOf(String.class, h1.getField("gram3"));

Hit h2 = r.hits().get("hit2");
assertEquals("katt i...morgen", h2.getField("gram3").toString());
assertTrue(h2.getField("gram3") instanceof JSONString);
assertInstanceOf(JSONString.class, h2.getField("gram3"));

Hit h3 = r.hits().get("hit3");
assertEquals("\u001ffin\u001f \u001fen\u001f \u001fa\u001f", h3.getField("gram2").toString());
Expand Down

0 comments on commit 4abdba0

Please sign in to comment.