mirror of https://github.com/apache/lucene.git
SOLR-1071: spellcheck.extendedResults format change
git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@812714 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
19e0a7a794
commit
b3ffddf116
|
@ -47,6 +47,9 @@ a TokenStream (that may be or may not be a Tokenizer). This change is required
|
|||
to take advantage of the Token reuse improvements in lucene 2.9. For more
|
||||
information, see SOLR-1377.
|
||||
|
||||
If spellcheck.extendedResults=true, the response format for suggestions
|
||||
has changed, see SOLR-1071.
|
||||
|
||||
|
||||
Versions of Major Components
|
||||
----------------------------
|
||||
|
@ -535,6 +538,11 @@ Bug Fixes
|
|||
64. SOLR-1400: Properly handle zero-length tokens in TrimFilter. This
|
||||
was not a bug in any released version. (Peter Wolanin, gsingers)
|
||||
|
||||
65. SOLR-1071: spellcheck.extendedResults returns an invalid JSON response
|
||||
when count > 1. To fix, the extendedResults format was changed.
|
||||
(Uri Boness, yonik)
|
||||
|
||||
|
||||
Other Changes
|
||||
----------------------
|
||||
1. Upgraded to Lucene 2.4.0 (yonik)
|
||||
|
|
|
@ -201,17 +201,30 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
|||
suggestionList.add("numFound", theSuggestions.size());
|
||||
suggestionList.add("startOffset", inputToken.startOffset());
|
||||
suggestionList.add("endOffset", inputToken.endOffset());
|
||||
|
||||
// Logical structure of normal (non-extended) results:
|
||||
// "suggestion":["alt1","alt2"]
|
||||
//
|
||||
// Logical structure of the extended results:
|
||||
// "suggestion":[
|
||||
// {"word":"alt1","freq":7},
|
||||
// {"word":"alt2","freq":4}
|
||||
// ]
|
||||
if (extendedResults && hasFreqInfo) {
|
||||
suggestionList.add("origFreq", spellingResult.getTokenFrequency(inputToken));
|
||||
|
||||
ArrayList<SimpleOrderedMap> sugs = new ArrayList<SimpleOrderedMap>();
|
||||
suggestionList.add("suggestion", sugs);
|
||||
for (Map.Entry<String, Integer> suggEntry : theSuggestions.entrySet()) {
|
||||
SimpleOrderedMap<Object> suggestionItem = new SimpleOrderedMap<Object>();
|
||||
suggestionItem.add("frequency", suggEntry.getValue());
|
||||
suggestionItem.add("word", suggEntry.getKey());
|
||||
suggestionList.add("suggestion", suggestionItem);
|
||||
SimpleOrderedMap sugEntry = new SimpleOrderedMap();
|
||||
sugEntry.add("word",suggEntry.getKey());
|
||||
sugEntry.add("freq",suggEntry.getValue());
|
||||
sugs.add(sugEntry);
|
||||
}
|
||||
} else {
|
||||
suggestionList.add("suggestion", theSuggestions.keySet());
|
||||
}
|
||||
|
||||
if (collate == true ){//set aside the best suggestion for this token
|
||||
best.put(inputToken, theSuggestions.keySet().iterator().next());
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ package org.apache.solr.client.solrj.response;
|
|||
*/
|
||||
|
||||
import org.apache.solr.common.util.NamedList;
|
||||
import org.apache.solr.common.util.SimpleOrderedMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
|
@ -74,10 +73,8 @@ public class SpellCheckResponse {
|
|||
|
||||
public String getFirstSuggestion(String token) {
|
||||
Suggestion s = suggestionMap.get(token);
|
||||
if (s != null) {
|
||||
return s.getSuggestions().isEmpty() ? null : s.getSuggestions().get(0);
|
||||
}
|
||||
return null;
|
||||
if (s==null || s.getAlternatives().isEmpty()) return null;
|
||||
return s.getAlternatives().get(0);
|
||||
}
|
||||
|
||||
public String getCollatedResult() {
|
||||
|
@ -90,8 +87,8 @@ public class SpellCheckResponse {
|
|||
private int startOffset;
|
||||
private int endOffset;
|
||||
private int originalFrequency;
|
||||
private List<String> suggestions = new ArrayList<String>();
|
||||
private List<Integer> suggestionFrequencies = new ArrayList<Integer>();
|
||||
private List<String> alternatives = new ArrayList<String>();
|
||||
private List<Integer> alternativeFrequencies;
|
||||
|
||||
public Suggestion(String token, NamedList<Object> suggestion) {
|
||||
this.token = token;
|
||||
|
@ -107,14 +104,16 @@ public class SpellCheckResponse {
|
|||
} else if ("origFreq".equals(n)) {
|
||||
originalFrequency = (Integer) suggestion.getVal(i);
|
||||
} else if ("suggestion".equals(n)) {
|
||||
Object o = suggestion.getVal(i);
|
||||
if (o instanceof List) {
|
||||
List<String> list = (List<String>) o;
|
||||
suggestions.addAll(list);
|
||||
} else if (o instanceof SimpleOrderedMap) {
|
||||
SimpleOrderedMap map = (SimpleOrderedMap) o;
|
||||
suggestions.add((String) map.get("word"));
|
||||
suggestionFrequencies.add((Integer) map.get("frequency"));
|
||||
List list = (List)suggestion.getVal(i);
|
||||
if (list.size() > 0 && list.get(0) instanceof NamedList) {
|
||||
// extended results detected
|
||||
alternativeFrequencies = new ArrayList<Integer>();
|
||||
for (NamedList nl : (List<NamedList>)list) {
|
||||
alternatives.add((String)nl.get("word"));
|
||||
alternativeFrequencies.add((Integer)nl.get("freq"));
|
||||
}
|
||||
} else {
|
||||
alternatives.addAll(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -140,12 +139,27 @@ public class SpellCheckResponse {
|
|||
return originalFrequency;
|
||||
}
|
||||
|
||||
public List<String> getSuggestions() {
|
||||
return suggestions;
|
||||
/** The list of alternatives */
|
||||
public List<String> getAlternatives() {
|
||||
return alternatives;
|
||||
}
|
||||
|
||||
public List<Integer> getSuggestionFrequencies() {
|
||||
return suggestionFrequencies;
|
||||
/** The frequencies of the alternatives in the corpus, or null if this information was not returned */
|
||||
public List<Integer> getAlternativeFrequencies() {
|
||||
return alternativeFrequencies;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
/** @see #getAlternatives */
|
||||
public List<String> getSuggestions() {
|
||||
return alternatives;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
/** @see #getAlternativeFrequencies */
|
||||
public List<Integer> getSuggestionFrequencies() {
|
||||
return alternativeFrequencies;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ import org.apache.solr.common.SolrInputDocument;
|
|||
import org.apache.solr.common.params.CommonParams;
|
||||
import org.apache.solr.common.params.SpellingParams;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Test for SpellCheckComponent's response in Solrj
|
||||
*
|
||||
|
@ -67,7 +69,7 @@ public class TestSpellCheckResponse extends SolrExampleTestBase {
|
|||
query.set(SpellingParams.SPELLCHECK_BUILD, true);
|
||||
QueryRequest request = new QueryRequest(query);
|
||||
SpellCheckResponse response = request.process(server).getSpellCheckResponse();
|
||||
Assert.assertEquals("Incorrect spelling results", "samsung", response.getFirstSuggestion("samsang"));
|
||||
Assert.assertEquals("samsung", response.getFirstSuggestion("samsang"));
|
||||
}
|
||||
|
||||
public void testSpellCheckResponse_Extended() throws Exception {
|
||||
|
@ -85,7 +87,25 @@ public class TestSpellCheckResponse extends SolrExampleTestBase {
|
|||
query.set(SpellingParams.SPELLCHECK_EXTENDED_RESULTS, true);
|
||||
QueryRequest request = new QueryRequest(query);
|
||||
SpellCheckResponse response = request.process(server).getSpellCheckResponse();
|
||||
Assert.assertEquals("Incorrect spelling results", "samsung", response.getFirstSuggestion("samsang"));
|
||||
assertEquals("samsung", response.getFirstSuggestion("samsang"));
|
||||
|
||||
SpellCheckResponse.Suggestion sug = response.getSuggestion("samsang");
|
||||
List<SpellCheckResponse.Suggestion> sugs = response.getSuggestions();
|
||||
|
||||
assertEquals(sug.getAlternatives().size(), sug.getAlternativeFrequencies().size());
|
||||
assertEquals(sugs.get(0).getAlternatives().size(), sugs.get(0).getAlternativeFrequencies().size());
|
||||
|
||||
assertEquals("samsung", sug.getAlternatives().get(0));
|
||||
assertEquals("samsung", sugs.get(0).getAlternatives().get(0));
|
||||
|
||||
// basic test if fields were filled in
|
||||
assertTrue(sug.getEndOffset()>0);
|
||||
assertTrue(sug.getToken().length() > 0);
|
||||
assertTrue(sug.getNumFound() > 0);
|
||||
// assertTrue(sug.getOriginalFrequency() > 0);
|
||||
|
||||
// Hmmm... the API for SpellCheckResponse could be nicer:
|
||||
response.getSuggestions().get(0).getAlternatives().get(0);
|
||||
}
|
||||
|
||||
protected SolrServer getSolrServer() {
|
||||
|
|
|
@ -18,10 +18,7 @@
|
|||
package org.apache.solr.handler.component;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.solr.common.params.CommonParams;
|
||||
import org.apache.solr.common.params.MapSolrParams;
|
||||
|
@ -86,26 +83,19 @@ public class SpellCheckComponentTest extends AbstractSolrTestCase {
|
|||
handler.handleRequest(new LocalSolrQueryRequest(core, params), rsp);
|
||||
NamedList values = rsp.getValues();
|
||||
String cmdExec = (String) values.get("command");
|
||||
assertTrue("command is null and it shouldn't be", cmdExec != null);
|
||||
assertTrue(cmdExec + " is not equal to " + "build",
|
||||
cmdExec.equals("build") == true);
|
||||
assertEquals("build",cmdExec);
|
||||
NamedList spellCheck = (NamedList) values.get("spellcheck");
|
||||
assertTrue("spellCheck is null and it shouldn't be", spellCheck != null);
|
||||
NamedList suggestions = (NamedList) spellCheck.get("suggestions");
|
||||
assertTrue("suggestions is null and it shouldn't be", suggestions != null);
|
||||
NamedList blue = (NamedList) suggestions.get("bluo");
|
||||
assertTrue(blue.get("numFound") + " is not equal to " + "5", blue
|
||||
.get("numFound").toString().equals("5") == true);
|
||||
assertEquals(5,blue.get("numFound"));
|
||||
Collection<String> theSuggestion = (Collection<String>) blue.get("suggestion");
|
||||
assertTrue("theSuggestion is null and it shouldn't be: " + blue,
|
||||
theSuggestion != null);
|
||||
assertTrue("theSuggestion Size: " + theSuggestion.size() + " is not: " + 5,
|
||||
theSuggestion.size() == 5);
|
||||
assertEquals(5,theSuggestion.size());
|
||||
//we know there are at least 5, but now only get 3
|
||||
|
||||
params.remove(SpellCheckComponent.SPELLCHECK_COUNT);
|
||||
params.remove(SpellCheckComponent.SPELLCHECK_EXTENDED_RESULTS);
|
||||
params.remove(SpellCheckComponent.SPELLCHECK_BUILD);
|
||||
params.add(SpellCheckComponent.SPELLCHECK_COUNT, String.valueOf(3));
|
||||
params.add(SpellCheckComponent.SPELLCHECK_COUNT, "3");
|
||||
params.add(SpellCheckComponent.SPELLCHECK_EXTENDED_RESULTS, String.valueOf(true));
|
||||
params.add(SpellCheckComponent.SPELLCHECK_BUILD, "false");
|
||||
rsp = new SolrQueryResponse();
|
||||
|
@ -113,36 +103,17 @@ public class SpellCheckComponentTest extends AbstractSolrTestCase {
|
|||
values = rsp.getValues();
|
||||
|
||||
spellCheck = (NamedList) values.get("spellcheck");
|
||||
assertTrue("spellCheck is null and it shouldn't be", spellCheck != null);
|
||||
suggestions = (NamedList) spellCheck.get("suggestions");
|
||||
assertTrue("suggestions is null and it shouldn't be", suggestions != null);
|
||||
blue = (NamedList) suggestions.get("bluo");
|
||||
assertTrue(blue.get("numFound") + " is not equal to " + "3", blue
|
||||
.get("numFound").toString().equals("3") == true);
|
||||
SimpleOrderedMap theSuggestions;
|
||||
int idx = blue.indexOf("suggestion", 0);
|
||||
theSuggestions = (SimpleOrderedMap) blue.get("suggestion", idx);
|
||||
assertTrue("theSuggestion is null and it shouldn't be: " + blue,
|
||||
theSuggestions != null);
|
||||
assertTrue("theSuggestions Size: " + theSuggestions.size() + " is not: " + 2,
|
||||
theSuggestions.size() == 2);//the word and the frequency
|
||||
assertEquals(3, blue.get("numFound"));
|
||||
|
||||
idx = blue.indexOf("suggestion", idx + 1);
|
||||
theSuggestions = (SimpleOrderedMap) blue.get("suggestion", idx);
|
||||
assertTrue("theSuggestion is null and it shouldn't be: " + blue,
|
||||
theSuggestions != null);
|
||||
assertTrue("theSuggestions Size: " + theSuggestions.size() + " is not: " + 2,
|
||||
theSuggestions.size() == 2);//the word and the frequency
|
||||
List<SimpleOrderedMap> theSuggestions = (List<SimpleOrderedMap>)blue.get("suggestion");
|
||||
assertEquals(3, theSuggestions.size());
|
||||
|
||||
idx = blue.indexOf("suggestion", idx + 1);
|
||||
theSuggestions = (SimpleOrderedMap) blue.get("suggestion", idx);
|
||||
assertTrue("theSuggestion is null and it shouldn't be: " + blue,
|
||||
theSuggestions != null);
|
||||
assertTrue("theSuggestions Size: " + theSuggestions.size() + " is not: " + 2,
|
||||
theSuggestions.size() == 2);//the word and the frequency
|
||||
|
||||
idx = blue.indexOf("suggestion", idx + 1);
|
||||
assertTrue(idx + " does not equal: " + -1, idx == -1);
|
||||
for (SimpleOrderedMap sug : theSuggestions) {
|
||||
assertNotNull(sug.get("word"));
|
||||
assertNotNull(sug.get("freq"));
|
||||
}
|
||||
}
|
||||
|
||||
public void test() throws Exception {
|
||||
|
@ -169,19 +140,12 @@ public class SpellCheckComponentTest extends AbstractSolrTestCase {
|
|||
NamedList suggestions = (NamedList) spellCheck.get("suggestions");
|
||||
assertTrue("suggestions is null and it shouldn't be", suggestions != null);
|
||||
NamedList document = (NamedList) suggestions.get("documemt");
|
||||
assertTrue(document.get("numFound") + " is not equal to " + "1", document
|
||||
.get("numFound").toString().equals("1") == true);
|
||||
assertTrue(document.get("startOffset") + " is not equal to " + "0", document
|
||||
.get("startOffset").toString().equals("0") == true);
|
||||
assertTrue(document.get("endOffset") + " is not equal to " + "documemt".length(), document
|
||||
.get("endOffset").toString().equals(String.valueOf("documemt".length())) == true);
|
||||
assertEquals(1, document.get("numFound"));
|
||||
assertEquals(0, document.get("startOffset"));
|
||||
assertEquals(document.get("endOffset"), "documemt".length());
|
||||
Collection<String> theSuggestion = (Collection<String>) document.get("suggestion");
|
||||
assertTrue("theSuggestion is null and it shouldn't be: " + document,
|
||||
theSuggestion != null);
|
||||
assertTrue("theSuggestion Size: " + theSuggestion.size() + " is not: " + 1,
|
||||
theSuggestion.size() == 1);
|
||||
assertTrue(theSuggestion.iterator().next() + " is not equal to " + "document", theSuggestion.iterator().next().equals("document") == true);
|
||||
|
||||
assertEquals(1, theSuggestion.size());
|
||||
assertEquals("document", theSuggestion.iterator().next());
|
||||
}
|
||||
|
||||
|
||||
|
@ -203,12 +167,9 @@ public class SpellCheckComponentTest extends AbstractSolrTestCase {
|
|||
handler.handleRequest(new LocalSolrQueryRequest(core, params), rsp);
|
||||
NamedList values = rsp.getValues();
|
||||
NamedList spellCheck = (NamedList) values.get("spellcheck");
|
||||
assertTrue("spellCheck is null and it shouldn't be", spellCheck != null);
|
||||
NamedList suggestions = (NamedList) spellCheck.get("suggestions");
|
||||
assertTrue("suggestions is null and it shouldn't be", suggestions != null);
|
||||
String collation = (String) suggestions.get("collation");
|
||||
assertTrue("collation is null and it shouldn't be", collation != null);
|
||||
assertTrue(collation + " is not equal to " + "document", collation.equals("document") == true);
|
||||
assertEquals("document", collation);
|
||||
params.remove(CommonParams.Q);
|
||||
params.add(CommonParams.Q, "documemt lowerfilt:broen^4");
|
||||
handler = core.getRequestHandler("spellCheckCompRH");
|
||||
|
@ -217,12 +178,9 @@ public class SpellCheckComponentTest extends AbstractSolrTestCase {
|
|||
handler.handleRequest(new LocalSolrQueryRequest(core, params), rsp);
|
||||
values = rsp.getValues();
|
||||
spellCheck = (NamedList) values.get("spellcheck");
|
||||
assertTrue("spellCheck is null and it shouldn't be", spellCheck != null);
|
||||
suggestions = (NamedList) spellCheck.get("suggestions");
|
||||
assertTrue("suggestions is null and it shouldn't be", suggestions != null);
|
||||
collation = (String) suggestions.get("collation");
|
||||
assertTrue("collation is null and it shouldn't be", collation != null);
|
||||
assertTrue(collation + " is not equal to " + "document lowerfilt:brown^4", collation.equals("document lowerfilt:brown^4") == true);
|
||||
assertEquals("document lowerfilt:brown^4", collation);
|
||||
|
||||
params.remove(CommonParams.Q);
|
||||
params.add(CommonParams.Q, "documemtsss broens");
|
||||
|
@ -232,15 +190,9 @@ public class SpellCheckComponentTest extends AbstractSolrTestCase {
|
|||
handler.handleRequest(new LocalSolrQueryRequest(core, params), rsp);
|
||||
values = rsp.getValues();
|
||||
spellCheck = (NamedList) values.get("spellcheck");
|
||||
assertTrue("spellCheck is null and it shouldn't be", spellCheck != null);
|
||||
suggestions = (NamedList) spellCheck.get("suggestions");
|
||||
assertTrue("suggestions is null and it shouldn't be", suggestions != null);
|
||||
collation = (String) suggestions.get("collation");
|
||||
assertTrue("collation is null and it shouldn't be", collation != null);
|
||||
System.out.println("Collation: " + collation);
|
||||
assertTrue(collation + " is not equal to " + "document brown", collation.equals("document brown") == true);
|
||||
|
||||
|
||||
assertEquals("document brown",collation);
|
||||
}
|
||||
|
||||
public void testCorrectSpelling() throws Exception {
|
||||
|
|
Loading…
Reference in New Issue