Skip to content

Commit

Permalink
MultiSuggester respects InfixLookup's highlight option
Browse files Browse the repository at this point in the history
  • Loading branch information
anthonygroves committed Jun 6, 2019
1 parent 736ad08 commit aea951e
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 16 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>ifpress</groupId>
<artifactId>ifpress-solr-plugin</artifactId>
<version>1.3.11-SNAPSHOT</version>
<version>1.4.1</version>
<name>ifpress solr plugin</name>
<description>Contains plugins to be installed in the solr server</description>
<dependencies>
Expand Down
1 change: 0 additions & 1 deletion solr/collection1/conf/solrconfig.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1049,7 +1049,6 @@
<float name="threshold">0.0</float>
<!-- true => NPE now that we have NRT support??. For production, schedule a rebuild nightly instead -->
<str name="buildOnCommit">false</str>
<bool name="highlight">false</bool>
<lst name="fields">
<lst name="field">
<str name="name">fulltext_t</str>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,14 @@
import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.spell.HighFrequencyDictionary;
import org.apache.lucene.search.spell.SuggestMode;
import org.apache.lucene.search.suggest.Lookup;
import org.apache.lucene.search.suggest.analyzing.AnalyzingInfixSuggester;
import org.apache.lucene.search.suggest.analyzing.AnalyzingSuggester;
import org.apache.lucene.search.suggest.fst.WFSTCompletionLookup;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefBuilder;
import org.apache.lucene.util.CharsRef;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.CloseHook;
Expand Down Expand Up @@ -517,9 +522,51 @@ public void preClose(SolrCore c) {

}

/*
A copy of the getSuggestions() method from Solr's Suggest class (org.apache.solr.spelling.suggest).
The only modification is the last 'for' loop, where the LookupResult's highlightedKey is used if it exists.
This overrides Suggest's use of only the non-highlighted key always being used, which does not respect the
highlights from the AnalyzingInfixSuggester class (or a relative class) as of Solr 4.10.3.
https://intranet.oreilly.com/jira/browse/SPIDR-1126
*/
private SpellingResult getSuggestionsWithHighlights(SpellingOptions options) throws IOException {
SpellingResult res = new SpellingResult();
if (lookup == null) {
return res;
}

CharsRef scratch = new CharsRef();
for (Token t : options.tokens) {
scratch.chars = t.buffer();
scratch.offset = 0;
scratch.length = t.length();
boolean onlyMorePopular = (options.suggestMode == SuggestMode.SUGGEST_MORE_POPULAR) &&
!(lookup instanceof WFSTCompletionLookup) &&
!(lookup instanceof AnalyzingSuggester);
List<Lookup.LookupResult> suggestions = lookup.lookup(scratch, onlyMorePopular, options.count);

if (suggestions == null) {
continue;
}

if (options.suggestMode != SuggestMode.SUGGEST_MORE_POPULAR) {
Collections.sort(suggestions);
}

// Suggestions should use LookupResult's highlightedKey if not null, otherwise default to using LookupResult's key.
String lookupKey;
for (Lookup.LookupResult lr : suggestions) {
lookupKey = lr.highlightKey != null ? lr.highlightKey.toString() : lr.key.toString();
res.add(t, lookupKey, (int)lr.value);
}
}
return res;
}

@Override
public SpellingResult getSuggestions(SpellingOptions options) throws IOException {
SpellingResult result = super.getSuggestions(options);
SpellingResult result = getSuggestionsWithHighlights(options);
if (options.extendedResults) {
for (Map.Entry<?, LinkedHashMap<String, Integer>> suggestion : result.getSuggestions().entrySet()) {
Object token = suggestion.getKey();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ public class MultiSuggesterTest extends SolrTest {
private static final String TEXT = "Now is the time time for all good people to come to the aid of their dawning intentional community";
private static final String TITLE = "The Dawning of a New Era";

/*
This test suite uses highlighted suggestions by default to ensure that suggestion highlighting regression is caught.
To get non-highlighted suggestions, must add <bool name="highlight">false</bool> to the spellchecker block in solrconfig.xml.
*/

private String unhighlight(String highlightedString) {
return highlightedString.replaceAll("</?b>", "");
}

private Suggestion assertSuggestionCount(String prefix, int count, String suggester) throws SolrServerException, IOException {
SolrQuery q = new SolrQuery(prefix);
q.setRequestHandler("/suggest/" + suggester);
Expand Down Expand Up @@ -55,13 +64,13 @@ private void assertSuggestions() throws SolrServerException, IOException {
Suggestion suggestion = assertSuggestionCount("t", 8, "all");
// TITLE occurs once in a high-weighted field; t1-t4, etc each occur twice, t5 once, their/time occur once
// 'the' and 'to' occur too many times and get excluded
assertEquals (TITLE, suggestion.getAlternatives().get(0));
assertEquals ("<b>T</b>he Dawning of a New Era", suggestion.getAlternatives().get(0));
for (int i = 1; i <=5; i++) {
String sugg = suggestion.getAlternatives().get(i);
String sugg = unhighlight(suggestion.getAlternatives().get(i));
assertTrue (sugg + " does not match t[1-5]", sugg.matches("t[1-5]"));
}
assertTrue (suggestion.getAlternatives().get(6).matches("their|time"));
assertTrue (suggestion.getAlternatives().get(7).matches("their|time"));
assertTrue (unhighlight(suggestion.getAlternatives().get(6)).matches("their|time"));
assertTrue (unhighlight(suggestion.getAlternatives().get(7)).matches("their|time"));
assertNotEquals(suggestion.getAlternatives().get(6), suggestion.getAlternatives().get(7));
}

Expand Down Expand Up @@ -145,7 +154,7 @@ public void testSegmentLongSuggestion() throws Exception {
// them
assertEquals(1, suggestion.getNumFound());

assertEquals(AAAA, suggestion.getAlternatives().get(0));
assertEquals(AAAA, unhighlight(suggestion.getAlternatives().get(0)));
}

@Test
Expand All @@ -172,13 +181,13 @@ public void testExtendedResultFormat() throws Exception {
assertNotNull("no spell check reponse found", scr);
suggestion = scr.getSuggestion(suggestQueryString);
assertNotNull(suggestion.getAlternativeFrequencies());
assertEquals("The Dawning of a New Era", suggestion.getAlternatives().get(0));
assertEquals("<b>T</b>he Dawning of a New Era", suggestion.getAlternatives().get(0));
// The title field is analyzed, so the weight is computed as
// #occurrences/#docs(w/title) * field-weight
// = 1 / 10 * 11 * 10000000 = 11000000
assertEquals(11000000, suggestion.getAlternativeFrequencies().get(0).intValue());
int last = suggestion.getNumFound() - 1;
assertTrue(suggestion.getAlternatives().get(last).matches("their|time"));
assertTrue(unhighlight(suggestion.getAlternatives().get(last)).matches("their|time"));
assertTrue(suggestion.getAlternativeFrequencies().get(last) > 0);
}

Expand All @@ -195,7 +204,7 @@ public void testMultipleTokenQuery() throws Exception {
Suggestion suggestion = scr.getSuggestion(suggestQueryString);
assertNotNull("no suggestion found for 'the da'", suggestion);
assertEquals(1, suggestion.getNumFound());
assertEquals(TITLE, suggestion.getAlternatives().get(0));
assertEquals("<b>The</b> <b>Da</b>wning of a New Era", suggestion.getAlternatives().get(0));
}

@Test
Expand All @@ -217,7 +226,7 @@ public void testBuildStartsFresh() throws Exception {
rebuildSuggester();
insertTestDocuments(TITLE_FIELD);
Suggestion suggestion = assertSuggestionCount("a2", 1, "all");
assertEquals("a2 document", suggestion.getAlternatives().get(0));
assertEquals("<b>a2</b> document", suggestion.getAlternatives().get(0));
// solr.deleteById("/doc/2");
solr.deleteByQuery("*:*");
solr.commit();
Expand All @@ -241,12 +250,12 @@ public void testEliminateDuplicates() throws Exception {
solr.add(doc);
solr.commit();
Suggestion suggestion = assertSuggestionCount("dawn", 2, "all");
assertEquals ("The Dawning of a New Era", suggestion.getAlternatives().get(0));
assertEquals ("dawning", suggestion.getAlternatives().get(1));
assertEquals ("The <b>Dawn</b>ing of a New Era", suggestion.getAlternatives().get(0));
assertEquals ("<b>dawn</b>ing", suggestion.getAlternatives().get(1));
// test rebuilding using a dictionary:
rebuildSuggester();
assertEquals ("The Dawning of a New Era", suggestion.getAlternatives().get(0));
assertEquals ("dawning", suggestion.getAlternatives().get(1));
assertEquals ("The <b>Dawn</b>ing of a New Era", suggestion.getAlternatives().get(0));
assertEquals ("<b>dawn</b>ing", suggestion.getAlternatives().get(1));
}

@Test
Expand Down

0 comments on commit aea951e

Please sign in to comment.