mirror of https://github.com/apache/lucene.git
SOLR-3029: Spellcheck response format changes
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1617572 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
94d1b7f5a6
commit
b5e18c6ccb
|
@ -48,6 +48,11 @@ Upgrading from Solr 4.x
|
||||||
|
|
||||||
* getAnalyzer() in IndexSchema and FieldType that was deprecated in Solr 4.9 has
|
* getAnalyzer() in IndexSchema and FieldType that was deprecated in Solr 4.9 has
|
||||||
been removed. Use getIndexAnalyzer() instead. See SOLR-6022 for more information.
|
been removed. Use getIndexAnalyzer() instead. See SOLR-6022 for more information.
|
||||||
|
|
||||||
|
* The spellcheck response format has changed, affecting xml and json clients. In
|
||||||
|
particular, the "correctlySpelled" and "collations" subsections have been moved outside
|
||||||
|
the "suggestions" subsection, and now are directly under "spellcheck".
|
||||||
|
See SOLR-3029 for more information.
|
||||||
|
|
||||||
Detailed Change List
|
Detailed Change List
|
||||||
----------------------
|
----------------------
|
||||||
|
@ -87,6 +92,8 @@ Other Changes
|
||||||
|
|
||||||
* SOLR-6215: TrieDateField should directly extend TrieField instead of
|
* SOLR-6215: TrieDateField should directly extend TrieField instead of
|
||||||
forwarding to a wrapped TrieField. (Steve Rowe)
|
forwarding to a wrapped TrieField. (Steve Rowe)
|
||||||
|
|
||||||
|
* SOLR-3029: Changes to spellcheck response format (Nalini Kartha via James Dyer)
|
||||||
|
|
||||||
================== 4.10.0 =================
|
================== 4.10.0 =================
|
||||||
|
|
||||||
|
|
|
@ -190,13 +190,20 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
spellingResult = new SpellingResult();
|
spellingResult = new SpellingResult();
|
||||||
}
|
}
|
||||||
boolean isCorrectlySpelled = hits > (maxResultsForSuggest==null ? 0 : maxResultsForSuggest);
|
boolean isCorrectlySpelled = hits > (maxResultsForSuggest==null ? 0 : maxResultsForSuggest);
|
||||||
NamedList suggestions = toNamedList(shardRequest, spellingResult, q,
|
|
||||||
extendedResults, collate, isCorrectlySpelled);
|
|
||||||
if (collate) {
|
|
||||||
addCollationsToResponse(params, spellingResult, rb, q, suggestions, spellChecker.isSuggestionsMayOverlap());
|
|
||||||
}
|
|
||||||
NamedList response = new SimpleOrderedMap();
|
NamedList response = new SimpleOrderedMap();
|
||||||
|
|
||||||
|
NamedList suggestions = toNamedList(shardRequest, spellingResult, q, extendedResults);
|
||||||
response.add("suggestions", suggestions);
|
response.add("suggestions", suggestions);
|
||||||
|
|
||||||
|
if (extendedResults) {
|
||||||
|
response.add("correctlySpelled", isCorrectlySpelled);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (collate) {
|
||||||
|
addCollationsToResponse(params, spellingResult, rb, q, response, spellChecker.isSuggestionsMayOverlap());
|
||||||
|
}
|
||||||
|
|
||||||
rb.rsp.add("spellcheck", response);
|
rb.rsp.add("spellcheck", response);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -232,9 +239,10 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
//even in cases when the internal rank is the same.
|
//even in cases when the internal rank is the same.
|
||||||
Collections.sort(collations);
|
Collections.sort(collations);
|
||||||
|
|
||||||
|
NamedList collationList = new NamedList();
|
||||||
for (SpellCheckCollation collation : collations) {
|
for (SpellCheckCollation collation : collations) {
|
||||||
if (collationExtendedResults) {
|
if (collationExtendedResults) {
|
||||||
NamedList extendedResult = new NamedList();
|
NamedList extendedResult = new SimpleOrderedMap();
|
||||||
extendedResult.add("collationQuery", collation.getCollationQuery());
|
extendedResult.add("collationQuery", collation.getCollationQuery());
|
||||||
extendedResult.add("hits", collation.getHits());
|
extendedResult.add("hits", collation.getHits());
|
||||||
extendedResult.add("misspellingsAndCorrections", collation.getMisspellingsAndCorrections());
|
extendedResult.add("misspellingsAndCorrections", collation.getMisspellingsAndCorrections());
|
||||||
|
@ -242,15 +250,15 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
{
|
{
|
||||||
extendedResult.add("collationInternalRank", collation.getInternalRank());
|
extendedResult.add("collationInternalRank", collation.getInternalRank());
|
||||||
}
|
}
|
||||||
response.add("collation", extendedResult);
|
collationList.add("collation", extendedResult);
|
||||||
} else {
|
} else {
|
||||||
response.add("collation", collation.getCollationQuery());
|
collationList.add("collation", collation.getCollationQuery());
|
||||||
if(maxCollationTries>0 && shard)
|
if (maxCollationTries>0 && shard) {
|
||||||
{
|
collationList.add("collationInternalRank", collation.getInternalRank());
|
||||||
response.add("collationInternalRank", collation.getInternalRank());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
response.add("collations", collationList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -346,35 +354,45 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
SpellingResult result = checker.mergeSuggestions(mergeData, numSug, count, extendedResults);
|
SpellingResult result = checker.mergeSuggestions(mergeData, numSug, count, extendedResults);
|
||||||
|
|
||||||
NamedList response = new SimpleOrderedMap();
|
NamedList response = new SimpleOrderedMap();
|
||||||
NamedList suggestions = toNamedList(false, result, origQuery,
|
|
||||||
extendedResults, collate, isCorrectlySpelled);
|
NamedList suggestions = toNamedList(false, result, origQuery, extendedResults);
|
||||||
|
response.add("suggestions", suggestions);
|
||||||
|
|
||||||
|
if (extendedResults) {
|
||||||
|
response.add("correctlySpelled", isCorrectlySpelled);
|
||||||
|
}
|
||||||
|
|
||||||
if (collate) {
|
if (collate) {
|
||||||
SpellCheckCollation[] sortedCollations = mergeData.collations.values()
|
SpellCheckCollation[] sortedCollations = mergeData.collations.values()
|
||||||
.toArray(new SpellCheckCollation[mergeData.collations.size()]);
|
.toArray(new SpellCheckCollation[mergeData.collations.size()]);
|
||||||
Arrays.sort(sortedCollations);
|
Arrays.sort(sortedCollations);
|
||||||
|
|
||||||
|
NamedList collations = new NamedList();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < maxCollations && i < sortedCollations.length) {
|
while (i < maxCollations && i < sortedCollations.length) {
|
||||||
SpellCheckCollation collation = sortedCollations[i];
|
SpellCheckCollation collation = sortedCollations[i];
|
||||||
i++;
|
i++;
|
||||||
if (collationExtendedResults) {
|
if (collationExtendedResults) {
|
||||||
NamedList extendedResult = new NamedList();
|
SimpleOrderedMap extendedResult = new SimpleOrderedMap();
|
||||||
extendedResult.add("collationQuery", collation.getCollationQuery());
|
extendedResult.add("collationQuery", collation.getCollationQuery());
|
||||||
extendedResult.add("hits", collation.getHits());
|
extendedResult.add("hits", collation.getHits());
|
||||||
extendedResult.add("misspellingsAndCorrections", collation
|
extendedResult.add("misspellingsAndCorrections", collation
|
||||||
.getMisspellingsAndCorrections());
|
.getMisspellingsAndCorrections());
|
||||||
suggestions.add("collation", extendedResult);
|
collations.add("collation", extendedResult);
|
||||||
} else {
|
} else {
|
||||||
suggestions.add("collation", collation.getCollationQuery());
|
collations.add("collation", collation.getCollationQuery());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
response.add("collations", collations);
|
||||||
}
|
}
|
||||||
|
|
||||||
response.add("suggestions", suggestions);
|
|
||||||
rb.rsp.add("spellcheck", response);
|
rb.rsp.add("spellcheck", response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void collectShardSuggestions(NamedList nl, SpellCheckMergeData mergeData) {
|
private void collectShardSuggestions(NamedList nl, SpellCheckMergeData mergeData) {
|
||||||
|
System.out.println(nl);
|
||||||
SpellCheckResponse spellCheckResp = new SpellCheckResponse(nl);
|
SpellCheckResponse spellCheckResp = new SpellCheckResponse(nl);
|
||||||
for (SpellCheckResponse.Suggestion suggestion : spellCheckResp.getSuggestions()) {
|
for (SpellCheckResponse.Suggestion suggestion : spellCheckResp.getSuggestions()) {
|
||||||
mergeData.origVsSuggestion.put(suggestion.getToken(), suggestion);
|
mergeData.origVsSuggestion.put(suggestion.getToken(), suggestion);
|
||||||
|
@ -422,10 +440,10 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void collectShardCollations(SpellCheckMergeData mergeData, NamedList spellCheckResponse, int maxCollationTries) {
|
private void collectShardCollations(SpellCheckMergeData mergeData, NamedList spellCheckResponse, int maxCollationTries) {
|
||||||
Map<String, SpellCheckCollation> collations = mergeData.collations;
|
Map<String, SpellCheckCollation> collations = mergeData.collations;
|
||||||
NamedList suggestions = (NamedList) spellCheckResponse.get("suggestions");
|
NamedList collationHolder = (NamedList) spellCheckResponse.get("collations");
|
||||||
if(suggestions != null) {
|
if(collationHolder != null) {
|
||||||
List<Object> collationList = suggestions.getAll("collation");
|
List<Object> collationList = collationHolder.getAll("collation");
|
||||||
List<Object> collationRankList = suggestions.getAll("collationInternalRank");
|
List<Object> collationRankList = collationHolder.getAll("collationInternalRank");
|
||||||
int i=0;
|
int i=0;
|
||||||
if(collationList != null) {
|
if(collationList != null) {
|
||||||
for(Object o : collationList)
|
for(Object o : collationList)
|
||||||
|
@ -542,8 +560,7 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
}
|
}
|
||||||
|
|
||||||
protected NamedList toNamedList(boolean shardRequest,
|
protected NamedList toNamedList(boolean shardRequest,
|
||||||
SpellingResult spellingResult, String origQuery, boolean extendedResults,
|
SpellingResult spellingResult, String origQuery, boolean extendedResults) {
|
||||||
boolean collate, boolean correctlySpelled) {
|
|
||||||
NamedList result = new NamedList();
|
NamedList result = new NamedList();
|
||||||
Map<Token,LinkedHashMap<String,Integer>> suggestions = spellingResult
|
Map<Token,LinkedHashMap<String,Integer>> suggestions = spellingResult
|
||||||
.getSuggestions();
|
.getSuggestions();
|
||||||
|
@ -606,10 +623,6 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
result.add(tokenString, suggestionList);
|
result.add(tokenString, suggestionList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extendedResults) {
|
|
||||||
result.add("correctlySpelled", correctlySpelled);
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,7 +122,8 @@ public class DistributedSpellCheckComponentTest extends BaseDistributedSearchTes
|
||||||
index(id, "22", "lowerfilt", "The quote red fox jumped over the lazy brown dogs.");
|
index(id, "22", "lowerfilt", "The quote red fox jumped over the lazy brown dogs.");
|
||||||
index(id, "23", "lowerfilt", "The quote red fox jumped over the lazy brown dogs.");
|
index(id, "23", "lowerfilt", "The quote red fox jumped over the lazy brown dogs.");
|
||||||
index(id, "24", "lowerfilt", "The quote red fox jumped over the lazy brown dogs.");
|
index(id, "24", "lowerfilt", "The quote red fox jumped over the lazy brown dogs.");
|
||||||
index(id, "25", "lowerfilt", "rod fix");
|
index(id, "25", "lowerfilt", "The quicker red fox jumped over the lazy brown dogs.");
|
||||||
|
index(id, "26", "lowerfilt", "rod fix");
|
||||||
commit();
|
commit();
|
||||||
|
|
||||||
handle.clear();
|
handle.clear();
|
||||||
|
@ -173,7 +174,7 @@ public class DistributedSpellCheckComponentTest extends BaseDistributedSearchTes
|
||||||
collate, "true", maxCollationTries, "0", maxCollations, "1", collateExtended, "false"));
|
collate, "true", maxCollationTries, "0", maxCollations, "1", collateExtended, "false"));
|
||||||
|
|
||||||
//Test context-sensitive collate
|
//Test context-sensitive collate
|
||||||
query(buildRequest("lowerfilt:(\"quote red fox\")",
|
query(buildRequest("lowerfilt:(\"quick red fox\")",
|
||||||
false, requestHandlerName, random().nextBoolean(), extended, "true", count, "10",
|
false, requestHandlerName, random().nextBoolean(), extended, "true", count, "10",
|
||||||
collate, "true", maxCollationTries, "10", maxCollations, "1", collateExtended, "false",
|
collate, "true", maxCollationTries, "10", maxCollations, "1", collateExtended, "false",
|
||||||
altTermCount, "5", maxResults, "10"));
|
altTermCount, "5", maxResults, "10"));
|
||||||
|
|
|
@ -111,16 +111,16 @@ public class SpellCheckComponentTest extends SolrTestCaseJ4 {
|
||||||
@Test
|
@Test
|
||||||
public void testCollate() throws Exception {
|
public void testCollate() throws Exception {
|
||||||
assertJQ(req("json.nl","map", "qt",rh, SpellCheckComponent.COMPONENT_NAME, "true", SpellingParams.SPELLCHECK_BUILD, "true", "q","documemt", SpellingParams.SPELLCHECK_COLLATE, "true")
|
assertJQ(req("json.nl","map", "qt",rh, SpellCheckComponent.COMPONENT_NAME, "true", SpellingParams.SPELLCHECK_BUILD, "true", "q","documemt", SpellingParams.SPELLCHECK_COLLATE, "true")
|
||||||
,"/spellcheck/suggestions/collation=='document'"
|
,"/spellcheck/collations/collation=='document'"
|
||||||
);
|
);
|
||||||
assertJQ(req("json.nl","map", "qt",rh, SpellCheckComponent.COMPONENT_NAME, "true", "q","documemt lowerfilt:broen^4", SpellingParams.SPELLCHECK_COLLATE, "true")
|
assertJQ(req("json.nl","map", "qt",rh, SpellCheckComponent.COMPONENT_NAME, "true", "q","documemt lowerfilt:broen^4", SpellingParams.SPELLCHECK_COLLATE, "true")
|
||||||
,"/spellcheck/suggestions/collation=='document lowerfilt:brown^4'"
|
,"/spellcheck/collations/collation=='document lowerfilt:brown^4'"
|
||||||
);
|
);
|
||||||
assertJQ(req("json.nl","map", "qt",rh, SpellCheckComponent.COMPONENT_NAME, "true", "q","documemtsss broens", SpellingParams.SPELLCHECK_COLLATE, "true")
|
assertJQ(req("json.nl","map", "qt",rh, SpellCheckComponent.COMPONENT_NAME, "true", "q","documemtsss broens", SpellingParams.SPELLCHECK_COLLATE, "true")
|
||||||
,"/spellcheck/suggestions/collation=='document brown'"
|
,"/spellcheck/collations/collation=='document brown'"
|
||||||
);
|
);
|
||||||
assertJQ(req("json.nl","map", "qt",rh, SpellCheckComponent.COMPONENT_NAME, "true", "q","pixma", SpellingParams.SPELLCHECK_COLLATE, "true")
|
assertJQ(req("json.nl","map", "qt",rh, SpellCheckComponent.COMPONENT_NAME, "true", "q","pixma", SpellingParams.SPELLCHECK_COLLATE, "true")
|
||||||
,"/spellcheck/suggestions/collation=='pixmaa'"
|
,"/spellcheck/collations/collation=='pixmaa'"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,15 +130,15 @@ public class SpellCheckComponentTest extends SolrTestCaseJ4 {
|
||||||
// Make sure correct spellings are signaled in the response
|
// Make sure correct spellings are signaled in the response
|
||||||
assertJQ(req("json.nl","map", "qt",rh, SpellCheckComponent.COMPONENT_NAME, "true",
|
assertJQ(req("json.nl","map", "qt",rh, SpellCheckComponent.COMPONENT_NAME, "true",
|
||||||
"q","lowerfilt:lazy lowerfilt:brown", SpellingParams.SPELLCHECK_EXTENDED_RESULTS, "true")
|
"q","lowerfilt:lazy lowerfilt:brown", SpellingParams.SPELLCHECK_EXTENDED_RESULTS, "true")
|
||||||
,"/spellcheck/suggestions=={'correctlySpelled':true}"
|
,"/spellcheck/correctlySpelled==true"
|
||||||
);
|
);
|
||||||
assertJQ(req("json.nl","map", "qt",rh, SpellCheckComponent.COMPONENT_NAME, "true", "spellcheck.dictionary", "direct_lowerfilt",
|
assertJQ(req("json.nl","map", "qt",rh, SpellCheckComponent.COMPONENT_NAME, "true", "spellcheck.dictionary", "direct_lowerfilt",
|
||||||
"q","lowerfilt:lazy lowerfilt:brown", SpellingParams.SPELLCHECK_EXTENDED_RESULTS, "true")
|
"q","lowerfilt:lazy lowerfilt:brown", SpellingParams.SPELLCHECK_EXTENDED_RESULTS, "true")
|
||||||
,"/spellcheck/suggestions=={'correctlySpelled':true}"
|
,"/spellcheck/correctlySpelled==true"
|
||||||
);
|
);
|
||||||
assertJQ(req("json.nl","map", "qt",rh, SpellCheckComponent.COMPONENT_NAME, "true", "spellcheck.dictionary", "direct_lowerfilt",
|
assertJQ(req("json.nl","map", "qt",rh, SpellCheckComponent.COMPONENT_NAME, "true", "spellcheck.dictionary", "direct_lowerfilt",
|
||||||
"q","lakkle", SpellingParams.SPELLCHECK_EXTENDED_RESULTS, "true")
|
"q","lakkle", SpellingParams.SPELLCHECK_EXTENDED_RESULTS, "true")
|
||||||
,"/spellcheck/suggestions/correctlySpelled==false"
|
,"/spellcheck/correctlySpelled==false"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ public class SpellCheckComponentTest extends SolrTestCaseJ4 {
|
||||||
NamedList spellCheck = (NamedList) values.get("spellcheck");
|
NamedList spellCheck = (NamedList) values.get("spellcheck");
|
||||||
NamedList suggestions = (NamedList) spellCheck.get("suggestions");
|
NamedList suggestions = (NamedList) spellCheck.get("suggestions");
|
||||||
assertTrue(suggestions.get("suggestion")==null);
|
assertTrue(suggestions.get("suggestion")==null);
|
||||||
assertTrue((Boolean) suggestions.get("correctlySpelled")==false);
|
assertTrue((Boolean) spellCheck.get("correctlySpelled")==false);
|
||||||
|
|
||||||
params.remove(SpellingParams.SPELLCHECK_DICT);
|
params.remove(SpellingParams.SPELLCHECK_DICT);
|
||||||
params.add(SpellingParams.SPELLCHECK_DICT, "threshold_direct");
|
params.add(SpellingParams.SPELLCHECK_DICT, "threshold_direct");
|
||||||
|
@ -255,7 +255,6 @@ public class SpellCheckComponentTest extends SolrTestCaseJ4 {
|
||||||
spellCheck = (NamedList) values.get("spellcheck");
|
spellCheck = (NamedList) values.get("spellcheck");
|
||||||
suggestions = (NamedList) spellCheck.get("suggestions");
|
suggestions = (NamedList) spellCheck.get("suggestions");
|
||||||
assertTrue(suggestions.get("suggestion")==null);
|
assertTrue(suggestions.get("suggestion")==null);
|
||||||
|
assertTrue((Boolean) spellCheck.get("correctlySpelled")==false);
|
||||||
assertTrue((Boolean) suggestions.get("correctlySpelled")==false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ public class DirectSolrSpellCheckerTest extends SolrTestCaseJ4 {
|
||||||
"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='fox']/int[@name='origFreq']=1",
|
"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='fox']/int[@name='origFreq']=1",
|
||||||
"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='fox']/arr[@name='suggestion']/lst/str[@name='word']='foo'",
|
"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='fox']/arr[@name='suggestion']/lst/str[@name='word']='foo'",
|
||||||
"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='fox']/arr[@name='suggestion']/lst/int[@name='freq']=2",
|
"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='fox']/arr[@name='suggestion']/lst/int[@name='freq']=2",
|
||||||
"//lst[@name='spellcheck']/lst[@name='suggestions']/bool[@name='correctlySpelled']='true'"
|
"//lst[@name='spellcheck']/bool[@name='correctlySpelled']='true'"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,8 +118,8 @@ public class SpellCheckCollatorTest extends SolrTestCaseJ4 {
|
||||||
req.close();
|
req.close();
|
||||||
NamedList values = rsp.getValues();
|
NamedList values = rsp.getValues();
|
||||||
NamedList spellCheck = (NamedList) values.get("spellcheck");
|
NamedList spellCheck = (NamedList) values.get("spellcheck");
|
||||||
NamedList suggestions = (NamedList) spellCheck.get("suggestions");
|
NamedList collationHolder = (NamedList) spellCheck.get("collations");
|
||||||
List<String> collations = suggestions.getAll("collation");
|
List<String> collations = collationHolder.getAll("collation");
|
||||||
assertTrue(collations.size()==1);
|
assertTrue(collations.size()==1);
|
||||||
String collation = collations.iterator().next();
|
String collation = collations.iterator().next();
|
||||||
assertTrue("Incorrect collation: " + collation,"lowerfilt:(hyphenated-word)".equals(collation));
|
assertTrue("Incorrect collation: " + collation,"lowerfilt:(hyphenated-word)".equals(collation));
|
||||||
|
@ -138,8 +138,8 @@ public class SpellCheckCollatorTest extends SolrTestCaseJ4 {
|
||||||
req.close();
|
req.close();
|
||||||
NamedList values = rsp.getValues();
|
NamedList values = rsp.getValues();
|
||||||
NamedList spellCheck = (NamedList) values.get("spellcheck");
|
NamedList spellCheck = (NamedList) values.get("spellcheck");
|
||||||
NamedList suggestions = (NamedList) spellCheck.get("suggestions");
|
NamedList collationHolder = (NamedList) spellCheck.get("collations");
|
||||||
List<String> collations = suggestions.getAll("collation");
|
List<String> collations = collationHolder.getAll("collation");
|
||||||
assertTrue(collations.size()==1);
|
assertTrue(collations.size()==1);
|
||||||
String collation = collations.iterator().next();
|
String collation = collations.iterator().next();
|
||||||
assertTrue("Incorrect collation: " + collation,"hyphenated-word".equals(collation));
|
assertTrue("Incorrect collation: " + collation,"hyphenated-word".equals(collation));
|
||||||
|
@ -163,7 +163,7 @@ public class SpellCheckCollatorTest extends SolrTestCaseJ4 {
|
||||||
"mm", "1",
|
"mm", "1",
|
||||||
CommonParams.Q, "partisian politcal mashine"
|
CommonParams.Q, "partisian politcal mashine"
|
||||||
),
|
),
|
||||||
"//lst[@name='spellcheck']/lst[@name='suggestions']/str[@name='collation']='parisian political machine'"
|
"//lst[@name='spellcheck']/lst[@name='collations']/str[@name='collation']='parisian political machine'"
|
||||||
);
|
);
|
||||||
assertQ(
|
assertQ(
|
||||||
req(
|
req(
|
||||||
|
@ -180,7 +180,7 @@ public class SpellCheckCollatorTest extends SolrTestCaseJ4 {
|
||||||
SpellingParams.SPELLCHECK_COLLATE_PARAM_OVERRIDE + "mm", "100%",
|
SpellingParams.SPELLCHECK_COLLATE_PARAM_OVERRIDE + "mm", "100%",
|
||||||
CommonParams.Q, "partisian politcal mashine"
|
CommonParams.Q, "partisian politcal mashine"
|
||||||
),
|
),
|
||||||
"//lst[@name='spellcheck']/lst[@name='suggestions']/str[@name='collation']='partisan political machine'"
|
"//lst[@name='spellcheck']/lst[@name='collations']/str[@name='collation']='partisan political machine'"
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -212,8 +212,8 @@ public class SpellCheckCollatorTest extends SolrTestCaseJ4 {
|
||||||
req.close();
|
req.close();
|
||||||
NamedList values = rsp.getValues();
|
NamedList values = rsp.getValues();
|
||||||
NamedList spellCheck = (NamedList) values.get("spellcheck");
|
NamedList spellCheck = (NamedList) values.get("spellcheck");
|
||||||
NamedList suggestions = (NamedList) spellCheck.get("suggestions");
|
NamedList collationHolder = (NamedList) spellCheck.get("collations");
|
||||||
List<String> collations = suggestions.getAll("collation");
|
List<String> collations = collationHolder.getAll("collation");
|
||||||
assertTrue(collations.size() > 0);
|
assertTrue(collations.size() > 0);
|
||||||
for(String collation : collations) {
|
for(String collation : collations) {
|
||||||
assertTrue(!collation.equals("lowerfilt:(+faith +hope +loaves)"));
|
assertTrue(!collation.equals("lowerfilt:(+faith +hope +loaves)"));
|
||||||
|
@ -247,8 +247,8 @@ public class SpellCheckCollatorTest extends SolrTestCaseJ4 {
|
||||||
req.close();
|
req.close();
|
||||||
NamedList values = rsp.getValues();
|
NamedList values = rsp.getValues();
|
||||||
NamedList spellCheck = (NamedList) values.get("spellcheck");
|
NamedList spellCheck = (NamedList) values.get("spellcheck");
|
||||||
NamedList suggestions = (NamedList) spellCheck.get("suggestions");
|
NamedList collationHolder = (NamedList) spellCheck.get("collations");
|
||||||
String singleCollation = (String) suggestions.get("collation");
|
String singleCollation = (String) collationHolder.get("collation");
|
||||||
assertNull(singleCollation);
|
assertNull(singleCollation);
|
||||||
|
|
||||||
//SpellCheckCompRH1 has "lowerfilt1" defined in the "qf" param. It will find "peace" from "peac" because
|
//SpellCheckCompRH1 has "lowerfilt1" defined in the "qf" param. It will find "peace" from "peac" because
|
||||||
|
@ -262,8 +262,8 @@ public class SpellCheckCollatorTest extends SolrTestCaseJ4 {
|
||||||
req.close();
|
req.close();
|
||||||
values = rsp.getValues();
|
values = rsp.getValues();
|
||||||
spellCheck = (NamedList) values.get("spellcheck");
|
spellCheck = (NamedList) values.get("spellcheck");
|
||||||
suggestions = (NamedList) spellCheck.get("suggestions");
|
collationHolder = (NamedList) spellCheck.get("collations");
|
||||||
singleCollation = (String) suggestions.get("collation");
|
singleCollation = (String) collationHolder.get("collation");
|
||||||
assertEquals(singleCollation, "peace");
|
assertEquals(singleCollation, "peace");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,8 +294,8 @@ public class SpellCheckCollatorTest extends SolrTestCaseJ4 {
|
||||||
req.close();
|
req.close();
|
||||||
NamedList values = rsp.getValues();
|
NamedList values = rsp.getValues();
|
||||||
NamedList spellCheck = (NamedList) values.get("spellcheck");
|
NamedList spellCheck = (NamedList) values.get("spellcheck");
|
||||||
NamedList suggestions = (NamedList) spellCheck.get("suggestions");
|
NamedList collationHolder = (NamedList) spellCheck.get("collations");
|
||||||
String singleCollation = (String) suggestions.get("collation");
|
String singleCollation = (String) collationHolder.get("collation");
|
||||||
assertEquals("lowerfilt:(+faith +homer +loaves)", singleCollation);
|
assertEquals("lowerfilt:(+faith +homer +loaves)", singleCollation);
|
||||||
|
|
||||||
// Testing backwards-compatible response format but will only return a
|
// Testing backwards-compatible response format but will only return a
|
||||||
|
@ -311,8 +311,8 @@ public class SpellCheckCollatorTest extends SolrTestCaseJ4 {
|
||||||
req.close();
|
req.close();
|
||||||
values = rsp.getValues();
|
values = rsp.getValues();
|
||||||
spellCheck = (NamedList) values.get("spellcheck");
|
spellCheck = (NamedList) values.get("spellcheck");
|
||||||
suggestions = (NamedList) spellCheck.get("suggestions");
|
collationHolder = (NamedList) spellCheck.get("collations");
|
||||||
singleCollation = (String) suggestions.get("collation");
|
singleCollation = (String) collationHolder.get("collation");
|
||||||
assertEquals("lowerfilt:(+faith +hope +loaves)", singleCollation);
|
assertEquals("lowerfilt:(+faith +hope +loaves)", singleCollation);
|
||||||
|
|
||||||
// Testing returning multiple collations if more than one valid
|
// Testing returning multiple collations if more than one valid
|
||||||
|
@ -329,8 +329,8 @@ public class SpellCheckCollatorTest extends SolrTestCaseJ4 {
|
||||||
req.close();
|
req.close();
|
||||||
values = rsp.getValues();
|
values = rsp.getValues();
|
||||||
spellCheck = (NamedList) values.get("spellcheck");
|
spellCheck = (NamedList) values.get("spellcheck");
|
||||||
suggestions = (NamedList) spellCheck.get("suggestions");
|
collationHolder = (NamedList) spellCheck.get("collations");
|
||||||
List<String> collations = suggestions.getAll("collation");
|
List<String> collations = collationHolder.getAll("collation");
|
||||||
assertTrue(collations.size() == 2);
|
assertTrue(collations.size() == 2);
|
||||||
for (String multipleCollation : collations) {
|
for (String multipleCollation : collations) {
|
||||||
assertTrue(multipleCollation.equals("lowerfilt:(+faith +hope +love)")
|
assertTrue(multipleCollation.equals("lowerfilt:(+faith +hope +love)")
|
||||||
|
@ -348,8 +348,8 @@ public class SpellCheckCollatorTest extends SolrTestCaseJ4 {
|
||||||
req.close();
|
req.close();
|
||||||
values = rsp.getValues();
|
values = rsp.getValues();
|
||||||
spellCheck = (NamedList) values.get("spellcheck");
|
spellCheck = (NamedList) values.get("spellcheck");
|
||||||
suggestions = (NamedList) spellCheck.get("suggestions");
|
collationHolder = (NamedList) spellCheck.get("collations");
|
||||||
List<NamedList> expandedCollationList = suggestions.getAll("collation");
|
List<NamedList> expandedCollationList = collationHolder.getAll("collation");
|
||||||
Set<String> usedcollations = new HashSet<>();
|
Set<String> usedcollations = new HashSet<>();
|
||||||
assertTrue(expandedCollationList.size() == 2);
|
assertTrue(expandedCollationList.size() == 2);
|
||||||
for (NamedList expandedCollation : expandedCollationList) {
|
for (NamedList expandedCollation : expandedCollationList) {
|
||||||
|
@ -402,8 +402,8 @@ public class SpellCheckCollatorTest extends SolrTestCaseJ4 {
|
||||||
req.close();
|
req.close();
|
||||||
NamedList values = rsp.getValues();
|
NamedList values = rsp.getValues();
|
||||||
NamedList spellCheck = (NamedList) values.get("spellcheck");
|
NamedList spellCheck = (NamedList) values.get("spellcheck");
|
||||||
NamedList suggestions = (NamedList) spellCheck.get("suggestions");
|
NamedList collationHolder = (NamedList) spellCheck.get("collations");
|
||||||
List<String> collations = suggestions.getAll("collation");
|
List<String> collations = collationHolder.getAll("collation");
|
||||||
assertTrue(collations.size() == 1);
|
assertTrue(collations.size() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,10 +434,10 @@ public class SpellCheckCollatorTest extends SolrTestCaseJ4 {
|
||||||
/* DirectSolrSpellChecker won't suggest if the edit distance > 2, so we can't test for this one...
|
/* DirectSolrSpellChecker won't suggest if the edit distance > 2, so we can't test for this one...
|
||||||
"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='heathrow']/arr[@name='suggestion']/lst/str[@name='word']='hearth'",
|
"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='heathrow']/arr[@name='suggestion']/lst/str[@name='word']='hearth'",
|
||||||
*/
|
*/
|
||||||
"//lst[@name='spellcheck']/lst[@name='suggestions']/bool[@name='correctlySpelled']='false'",
|
"//lst[@name='spellcheck']/bool[@name='correctlySpelled']='false'",
|
||||||
"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='collation']/str[@name='collationQuery']='teststop:(flew AND from AND heathrow)'",
|
"//lst[@name='spellcheck']/lst[@name='collations']/lst[@name='collation']/str[@name='collationQuery']='teststop:(flew AND from AND heathrow)'",
|
||||||
"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='collation']/int[@name='hits']=1",
|
"//lst[@name='spellcheck']/lst[@name='collations']/lst[@name='collation']/int[@name='hits']=1",
|
||||||
"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='collation']/lst[@name='misspellingsAndCorrections']/str[@name='form']='from'"
|
"//lst[@name='spellcheck']/lst[@name='collations']/lst[@name='collation']/lst[@name='misspellingsAndCorrections']/str[@name='form']='from'"
|
||||||
);
|
);
|
||||||
|
|
||||||
assertQ(
|
assertQ(
|
||||||
|
@ -458,10 +458,10 @@ public class SpellCheckCollatorTest extends SolrTestCaseJ4 {
|
||||||
),
|
),
|
||||||
"//result[@numFound=1]",
|
"//result[@numFound=1]",
|
||||||
"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='june']/arr[@name='suggestion']/lst/str[@name='word']='jane'",
|
"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='june']/arr[@name='suggestion']/lst/str[@name='word']='jane'",
|
||||||
"//lst[@name='spellcheck']/lst[@name='suggestions']/bool[@name='correctlySpelled']='false'",
|
"//lst[@name='spellcheck']/bool[@name='correctlySpelled']='false'",
|
||||||
"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='collation']/str[@name='collationQuery']='teststop:(jane AND customs)'",
|
"//lst[@name='spellcheck']/lst[@name='collations']/lst[@name='collation']/str[@name='collationQuery']='teststop:(jane AND customs)'",
|
||||||
"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='collation']/int[@name='hits']=1",
|
"//lst[@name='spellcheck']/lst[@name='collations']/lst[@name='collation']/int[@name='hits']=1",
|
||||||
"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='collation']/lst[@name='misspellingsAndCorrections']/str[@name='june']='jane'"
|
"//lst[@name='spellcheck']/lst[@name='collations']/lst[@name='collation']/lst[@name='misspellingsAndCorrections']/str[@name='june']='jane'"
|
||||||
);
|
);
|
||||||
//SOLR-5090, alternativeTermCount==0 was being evaluated, sometimes would throw NPE
|
//SOLR-5090, alternativeTermCount==0 was being evaluated, sometimes would throw NPE
|
||||||
assertQ(req("q", "teststop:(june customs)", "mm", "2", "qt",
|
assertQ(req("q", "teststop:(june customs)", "mm", "2", "qt",
|
||||||
|
@ -477,7 +477,7 @@ public class SpellCheckCollatorTest extends SolrTestCaseJ4 {
|
||||||
@Test
|
@Test
|
||||||
public void testEstimatedHitCounts() throws Exception {
|
public void testEstimatedHitCounts() throws Exception {
|
||||||
final String xpathPrefix =
|
final String xpathPrefix =
|
||||||
"//lst[@name='spellcheck']/lst[@name='suggestions']/lst[@name='collation']/";
|
"//lst[@name='spellcheck']/lst[@name='collations']/lst[@name='collation']/";
|
||||||
final SolrParams reusedParams = params
|
final SolrParams reusedParams = params
|
||||||
(SpellCheckComponent.COMPONENT_NAME, "true",
|
(SpellCheckComponent.COMPONENT_NAME, "true",
|
||||||
SpellCheckComponent.SPELLCHECK_DICT, "direct",
|
SpellCheckComponent.SPELLCHECK_DICT, "direct",
|
||||||
|
@ -559,8 +559,8 @@ public class SpellCheckCollatorTest extends SolrTestCaseJ4 {
|
||||||
req.close();
|
req.close();
|
||||||
NamedList values = rsp.getValues();
|
NamedList values = rsp.getValues();
|
||||||
NamedList spellCheck = (NamedList) values.get("spellcheck");
|
NamedList spellCheck = (NamedList) values.get("spellcheck");
|
||||||
NamedList suggestions = (NamedList) spellCheck.get("suggestions");
|
NamedList collationList = (NamedList) spellCheck.get("collations");
|
||||||
List<String> collations = suggestions.getAll("collation");
|
List<?> collations = (List<?>) collationList.getAll("collation");
|
||||||
assertTrue(collations.size() == 2);
|
assertTrue(collations.size() == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ public class QueryResponse extends SolrResponseBase
|
||||||
private NamedList<Object> _facetInfo = null;
|
private NamedList<Object> _facetInfo = null;
|
||||||
private NamedList<Object> _debugInfo = null;
|
private NamedList<Object> _debugInfo = null;
|
||||||
private NamedList<Object> _highlightingInfo = null;
|
private NamedList<Object> _highlightingInfo = null;
|
||||||
private NamedList<NamedList<Object>> _spellInfo = null;
|
private NamedList<Object> _spellInfo = null;
|
||||||
private NamedList<Object> _statsInfo = null;
|
private NamedList<Object> _statsInfo = null;
|
||||||
private NamedList<NamedList<Number>> _termsInfo = null;
|
private NamedList<NamedList<Number>> _termsInfo = null;
|
||||||
private String _cursorMarkNext = null;
|
private String _cursorMarkNext = null;
|
||||||
|
@ -136,7 +136,7 @@ public class QueryResponse extends SolrResponseBase
|
||||||
extractHighlightingInfo( _highlightingInfo );
|
extractHighlightingInfo( _highlightingInfo );
|
||||||
}
|
}
|
||||||
else if ( "spellcheck".equals( n ) ) {
|
else if ( "spellcheck".equals( n ) ) {
|
||||||
_spellInfo = (NamedList<NamedList<Object>>) res.getVal( i );
|
_spellInfo = (NamedList<Object>) res.getVal( i );
|
||||||
extractSpellCheckInfo( _spellInfo );
|
extractSpellCheckInfo( _spellInfo );
|
||||||
}
|
}
|
||||||
else if ( "stats".equals( n ) ) {
|
else if ( "stats".equals( n ) ) {
|
||||||
|
@ -154,7 +154,7 @@ public class QueryResponse extends SolrResponseBase
|
||||||
if(_facetInfo != null) extractFacetInfo( _facetInfo );
|
if(_facetInfo != null) extractFacetInfo( _facetInfo );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void extractSpellCheckInfo(NamedList<NamedList<Object>> spellInfo) {
|
private void extractSpellCheckInfo(NamedList<Object> spellInfo) {
|
||||||
_spellResponse = new SpellCheckResponse(spellInfo);
|
_spellResponse = new SpellCheckResponse(spellInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,56 +35,61 @@ public class SpellCheckResponse {
|
||||||
private List<Suggestion> suggestions = new ArrayList<>();
|
private List<Suggestion> suggestions = new ArrayList<>();
|
||||||
Map<String, Suggestion> suggestionMap = new LinkedHashMap<>();
|
Map<String, Suggestion> suggestionMap = new LinkedHashMap<>();
|
||||||
|
|
||||||
public SpellCheckResponse(NamedList<NamedList<Object>> spellInfo) {
|
public SpellCheckResponse(NamedList<Object> spellInfo) {
|
||||||
NamedList<Object> sugg = spellInfo.get("suggestions");
|
@SuppressWarnings("unchecked")
|
||||||
|
NamedList<Object> sugg = (NamedList<Object>) spellInfo.get("suggestions");
|
||||||
if (sugg == null) {
|
if (sugg == null) {
|
||||||
correctlySpelled = true;
|
correctlySpelled = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < sugg.size(); i++) {
|
for (int i = 0; i < sugg.size(); i++) {
|
||||||
String n = sugg.getName(i);
|
String n = sugg.getName(i);
|
||||||
if ("correctlySpelled".equals(n)) {
|
@SuppressWarnings("unchecked")
|
||||||
correctlySpelled = (Boolean) sugg.getVal(i);
|
Suggestion s = new Suggestion(n, (NamedList<Object>) sugg.getVal(i));
|
||||||
} else if ("collationInternalRank".equals(n)){
|
suggestionMap.put(n, s);
|
||||||
//continue;
|
suggestions.add(s);
|
||||||
} else if ("collation".equals(n)) {
|
}
|
||||||
List<Object> collationInfo = sugg.getAll(n);
|
|
||||||
collations = new ArrayList<>(collationInfo.size());
|
Boolean correctlySpelled = (Boolean) spellInfo.get("correctlySpelled");
|
||||||
for (Object o : collationInfo) {
|
if (correctlySpelled != null) {
|
||||||
if (o instanceof String) {
|
this.correctlySpelled = correctlySpelled;
|
||||||
collations.add(new Collation()
|
}
|
||||||
.setCollationQueryString((String) o));
|
|
||||||
} else if (o instanceof NamedList) {
|
@SuppressWarnings("unchecked")
|
||||||
@SuppressWarnings("unchecked")
|
NamedList<Object> coll = (NamedList<Object>) spellInfo.get("collations");
|
||||||
NamedList<Object> expandedCollation = (NamedList<Object>) o;
|
if (coll != null) {
|
||||||
String collationQuery
|
// The 'collationInternalRank' values are ignored so we only care 'collation's.
|
||||||
= (String) expandedCollation.get("collationQuery");
|
List<Object> collationInfo = coll.getAll("collation");
|
||||||
int hits = (Integer) expandedCollation.get("hits");
|
collations = new ArrayList<>(collationInfo.size());
|
||||||
@SuppressWarnings("unchecked")
|
for (Object o : collationInfo) {
|
||||||
NamedList<String> misspellingsAndCorrections
|
if (o instanceof String) {
|
||||||
= (NamedList<String>) expandedCollation.get("misspellingsAndCorrections");
|
collations.add(new Collation()
|
||||||
|
.setCollationQueryString((String) o));
|
||||||
|
} else if (o instanceof NamedList) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
NamedList<Object> expandedCollation = (NamedList<Object>) o;
|
||||||
|
String collationQuery
|
||||||
|
= (String) expandedCollation.get("collationQuery");
|
||||||
|
int hits = (Integer) expandedCollation.get("hits");
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
NamedList<String> misspellingsAndCorrections
|
||||||
|
= (NamedList<String>) expandedCollation.get("misspellingsAndCorrections");
|
||||||
|
|
||||||
Collation collation = new Collation();
|
Collation collation = new Collation();
|
||||||
collation.setCollationQueryString(collationQuery);
|
collation.setCollationQueryString(collationQuery);
|
||||||
collation.setNumberOfHits(hits);
|
collation.setNumberOfHits(hits);
|
||||||
|
|
||||||
for (int ii = 0; ii < misspellingsAndCorrections.size(); ii++) {
|
for (int ii = 0; ii < misspellingsAndCorrections.size(); ii++) {
|
||||||
String misspelling = misspellingsAndCorrections.getName(ii);
|
String misspelling = misspellingsAndCorrections.getName(ii);
|
||||||
String correction = misspellingsAndCorrections.getVal(ii);
|
String correction = misspellingsAndCorrections.getVal(ii);
|
||||||
collation.addMisspellingsAndCorrection(new Correction(
|
collation.addMisspellingsAndCorrection(new Correction(
|
||||||
misspelling, correction));
|
misspelling, correction));
|
||||||
}
|
|
||||||
collations.add(collation);
|
|
||||||
} else {
|
|
||||||
throw new AssertionError(
|
|
||||||
"Should get Lists of Strings or List of NamedLists here.");
|
|
||||||
}
|
}
|
||||||
|
collations.add(collation);
|
||||||
|
} else {
|
||||||
|
throw new AssertionError(
|
||||||
|
"Should get Lists of Strings or List of NamedLists here.");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Suggestion s = new Suggestion(n, (NamedList<Object>) sugg.getVal(i));
|
|
||||||
suggestionMap.put(n, s);
|
|
||||||
suggestions.add(s);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue