mirror of https://github.com/apache/lucene.git
SOLR-8104: Config API does not work for spellchecker
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1705858 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
a8d08f8247
commit
155f5a5dad
|
@ -217,6 +217,9 @@ Bug Fixes
|
||||||
|
|
||||||
* SOLR-8077: Replication can still cause index corruption. (Mark Miller)
|
* SOLR-8077: Replication can still cause index corruption. (Mark Miller)
|
||||||
|
|
||||||
|
* SOLR-8104: Config API does not work for spellchecker (noble)
|
||||||
|
|
||||||
|
|
||||||
Optimizations
|
Optimizations
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ import org.slf4j.LoggerFactory;
|
||||||
* <p>
|
* <p>
|
||||||
* Refer to http://wiki.apache.org/solr/SpellCheckComponent for more details
|
* Refer to http://wiki.apache.org/solr/SpellCheckComponent for more details
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @since solr 1.3
|
* @since solr 1.3
|
||||||
*/
|
*/
|
||||||
public class SpellCheckComponent extends SearchComponent implements SolrCoreAware, SpellingParams {
|
public class SpellCheckComponent extends SearchComponent implements SolrCoreAware, SpellingParams {
|
||||||
|
@ -95,7 +95,7 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected NamedList initParams;
|
protected NamedList initParams;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Key is the dictionary, value is the SpellChecker for that dictionary name
|
* Key is the dictionary, value is the SpellChecker for that dictionary name
|
||||||
|
@ -140,7 +140,7 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
String q = params.get(SPELLCHECK_Q);
|
String q = params.get(SPELLCHECK_Q);
|
||||||
SolrSpellChecker spellChecker = getSpellChecker(params);
|
SolrSpellChecker spellChecker = getSpellChecker(params);
|
||||||
Collection<Token> tokens = null;
|
Collection<Token> tokens = null;
|
||||||
|
|
||||||
if (q != null) {
|
if (q != null) {
|
||||||
//we have a spell check param, tokenize it with the query analyzer applicable for this spellchecker
|
//we have a spell check param, tokenize it with the query analyzer applicable for this spellchecker
|
||||||
tokens = getTokens(q, spellChecker.getQueryAnalyzer());
|
tokens = getTokens(q, spellChecker.getQueryAnalyzer());
|
||||||
|
@ -155,16 +155,16 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
if (spellChecker != null) {
|
if (spellChecker != null) {
|
||||||
int count = params.getInt(SPELLCHECK_COUNT, 1);
|
int count = params.getInt(SPELLCHECK_COUNT, 1);
|
||||||
boolean onlyMorePopular = params.getBool(SPELLCHECK_ONLY_MORE_POPULAR, DEFAULT_ONLY_MORE_POPULAR);
|
boolean onlyMorePopular = params.getBool(SPELLCHECK_ONLY_MORE_POPULAR, DEFAULT_ONLY_MORE_POPULAR);
|
||||||
boolean extendedResults = params.getBool(SPELLCHECK_EXTENDED_RESULTS, false);
|
boolean extendedResults = params.getBool(SPELLCHECK_EXTENDED_RESULTS, false);
|
||||||
boolean collate = params.getBool(SPELLCHECK_COLLATE, false);
|
boolean collate = params.getBool(SPELLCHECK_COLLATE, false);
|
||||||
float accuracy = params.getFloat(SPELLCHECK_ACCURACY, Float.MIN_VALUE);
|
float accuracy = params.getFloat(SPELLCHECK_ACCURACY, Float.MIN_VALUE);
|
||||||
int alternativeTermCount = params.getInt(SpellingParams.SPELLCHECK_ALTERNATIVE_TERM_COUNT, 0);
|
int alternativeTermCount = params.getInt(SpellingParams.SPELLCHECK_ALTERNATIVE_TERM_COUNT, 0);
|
||||||
Integer maxResultsForSuggest = params.getInt(SpellingParams.SPELLCHECK_MAX_RESULTS_FOR_SUGGEST);
|
Integer maxResultsForSuggest = params.getInt(SpellingParams.SPELLCHECK_MAX_RESULTS_FOR_SUGGEST);
|
||||||
ModifiableSolrParams customParams = new ModifiableSolrParams();
|
ModifiableSolrParams customParams = new ModifiableSolrParams();
|
||||||
for (String checkerName : getDictionaryNames(params)) {
|
for (String checkerName : getDictionaryNames(params)) {
|
||||||
customParams.add(getCustomParams(checkerName, params));
|
customParams.add(getCustomParams(checkerName, params));
|
||||||
}
|
}
|
||||||
|
|
||||||
Integer hitsInteger = (Integer) rb.rsp.getToLog().get("hits");
|
Integer hitsInteger = (Integer) rb.rsp.getToLog().get("hits");
|
||||||
long hits = 0;
|
long hits = 0;
|
||||||
if (hitsInteger == null) {
|
if (hitsInteger == null) {
|
||||||
|
@ -180,7 +180,7 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
} else if (alternativeTermCount > 0) {
|
} else if (alternativeTermCount > 0) {
|
||||||
suggestMode = SuggestMode.SUGGEST_ALWAYS;
|
suggestMode = SuggestMode.SUGGEST_ALWAYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexReader reader = rb.req.getSearcher().getIndexReader();
|
IndexReader reader = rb.req.getSearcher().getIndexReader();
|
||||||
SpellingOptions options = new SpellingOptions(tokens, reader, count,
|
SpellingOptions options = new SpellingOptions(tokens, reader, count,
|
||||||
alternativeTermCount, suggestMode, extendedResults, accuracy,
|
alternativeTermCount, suggestMode, extendedResults, accuracy,
|
||||||
|
@ -190,21 +190,21 @@ 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 response = new SimpleOrderedMap();
|
NamedList response = new SimpleOrderedMap();
|
||||||
NamedList suggestions = toNamedList(shardRequest, spellingResult, q, extendedResults);
|
NamedList suggestions = toNamedList(shardRequest, spellingResult, q, extendedResults);
|
||||||
response.add("suggestions", suggestions);
|
response.add("suggestions", suggestions);
|
||||||
|
|
||||||
if (extendedResults) {
|
if (extendedResults) {
|
||||||
response.add("correctlySpelled", isCorrectlySpelled);
|
response.add("correctlySpelled", isCorrectlySpelled);
|
||||||
}
|
}
|
||||||
if (collate) {
|
if (collate) {
|
||||||
addCollationsToResponse(params, spellingResult, rb, q, response, spellChecker.isSuggestionsMayOverlap());
|
addCollationsToResponse(params, spellingResult, rb, q, response, spellChecker.isSuggestionsMayOverlap());
|
||||||
}
|
}
|
||||||
if (shardRequest) {
|
if (shardRequest) {
|
||||||
addOriginalTermsToResponse(response, tokens);
|
addOriginalTermsToResponse(response, tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
rb.rsp.add("spellcheck", response);
|
rb.rsp.add("spellcheck", response);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -213,7 +213,7 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected void addCollationsToResponse(SolrParams params, SpellingResult spellingResult, ResponseBuilder rb, String q,
|
protected void addCollationsToResponse(SolrParams params, SpellingResult spellingResult, ResponseBuilder rb, String q,
|
||||||
NamedList response, boolean suggestionsMayOverlap) {
|
NamedList response, boolean suggestionsMayOverlap) {
|
||||||
|
@ -261,7 +261,7 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
}
|
}
|
||||||
response.add("collations", collationList);
|
response.add("collations", collationList);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addOriginalTermsToResponse(NamedList response, Collection<Token> originalTerms) {
|
private void addOriginalTermsToResponse(NamedList response, Collection<Token> originalTerms) {
|
||||||
List<String> originalTermStr = new ArrayList<String>();
|
List<String> originalTermStr = new ArrayList<String>();
|
||||||
for(Token t : originalTerms) {
|
for(Token t : originalTerms) {
|
||||||
|
@ -294,7 +294,7 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
public void modifyRequest(ResponseBuilder rb, SearchComponent who, ShardRequest sreq) {
|
public void modifyRequest(ResponseBuilder rb, SearchComponent who, ShardRequest sreq) {
|
||||||
SolrParams params = rb.req.getParams();
|
SolrParams params = rb.req.getParams();
|
||||||
if (!params.getBool(COMPONENT_NAME, false)) return;
|
if (!params.getBool(COMPONENT_NAME, false)) return;
|
||||||
int purpose = rb.grouping() ? ShardRequest.PURPOSE_GET_TOP_GROUPS : ShardRequest.PURPOSE_GET_TOP_IDS;
|
int purpose = rb.grouping() ? ShardRequest.PURPOSE_GET_TOP_GROUPS : ShardRequest.PURPOSE_GET_TOP_IDS;
|
||||||
if ((sreq.purpose & purpose) != 0) {
|
if ((sreq.purpose & purpose) != 0) {
|
||||||
// fetch at least 5 suggestions from each shard
|
// fetch at least 5 suggestions from each shard
|
||||||
int count = sreq.params.getInt(SPELLCHECK_COUNT, 1);
|
int count = sreq.params.getInt(SPELLCHECK_COUNT, 1);
|
||||||
|
@ -318,7 +318,7 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
boolean collationExtendedResults = params.getBool(SPELLCHECK_COLLATE_EXTENDED_RESULTS, false);
|
boolean collationExtendedResults = params.getBool(SPELLCHECK_COLLATE_EXTENDED_RESULTS, false);
|
||||||
int maxCollationTries = params.getInt(SPELLCHECK_MAX_COLLATION_TRIES, 0);
|
int maxCollationTries = params.getInt(SPELLCHECK_MAX_COLLATION_TRIES, 0);
|
||||||
int maxCollations = params.getInt(SPELLCHECK_MAX_COLLATIONS, 1);
|
int maxCollations = params.getInt(SPELLCHECK_MAX_COLLATIONS, 1);
|
||||||
Integer maxResultsForSuggest = params.getInt(SpellingParams.SPELLCHECK_MAX_RESULTS_FOR_SUGGEST);
|
Integer maxResultsForSuggest = params.getInt(SpellingParams.SPELLCHECK_MAX_RESULTS_FOR_SUGGEST);
|
||||||
int count = rb.req.getParams().getInt(SPELLCHECK_COUNT, 1);
|
int count = rb.req.getParams().getInt(SPELLCHECK_COUNT, 1);
|
||||||
int numSug = Math.max(count, AbstractLuceneSpellChecker.DEFAULT_SUGGESTION_COUNT);
|
int numSug = Math.max(count, AbstractLuceneSpellChecker.DEFAULT_SUGGESTION_COUNT);
|
||||||
|
|
||||||
|
@ -329,11 +329,11 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
origQuery = params.get(CommonParams.Q);
|
origQuery = params.get(CommonParams.Q);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long hits = rb.grouping() ? rb.totalHitCount : rb.getNumberDocumentsFound();
|
long hits = rb.grouping() ? rb.totalHitCount : rb.getNumberDocumentsFound();
|
||||||
boolean isCorrectlySpelled = hits > (maxResultsForSuggest==null ? 0 : maxResultsForSuggest);
|
boolean isCorrectlySpelled = hits > (maxResultsForSuggest==null ? 0 : maxResultsForSuggest);
|
||||||
|
|
||||||
SpellCheckMergeData mergeData = new SpellCheckMergeData();
|
SpellCheckMergeData mergeData = new SpellCheckMergeData();
|
||||||
if (maxResultsForSuggest==null || !isCorrectlySpelled) {
|
if (maxResultsForSuggest==null || !isCorrectlySpelled) {
|
||||||
for (ShardRequest sreq : rb.finished) {
|
for (ShardRequest sreq : rb.finished) {
|
||||||
for (ShardResponse srsp : sreq.responses) {
|
for (ShardResponse srsp : sreq.responses) {
|
||||||
|
@ -359,23 +359,23 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
|
|
||||||
// all shard responses have been collected
|
// all shard responses have been collected
|
||||||
// create token and get top suggestions
|
// create token and get top suggestions
|
||||||
SolrSpellChecker checker = getSpellChecker(rb.req.getParams());
|
SolrSpellChecker checker = getSpellChecker(rb.req.getParams());
|
||||||
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);
|
NamedList suggestions = toNamedList(false, result, origQuery, extendedResults);
|
||||||
response.add("suggestions", suggestions);
|
response.add("suggestions", suggestions);
|
||||||
|
|
||||||
if (extendedResults) {
|
if (extendedResults) {
|
||||||
response.add("correctlySpelled", isCorrectlySpelled);
|
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();
|
NamedList collations = new NamedList();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < maxCollations && i < sortedCollations.length) {
|
while (i < maxCollations && i < sortedCollations.length) {
|
||||||
|
@ -392,16 +392,16 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
collations.add("collation", collation.getCollationQuery());
|
collations.add("collation", collation.getCollationQuery());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
response.add("collations", collations);
|
response.add("collations", collations);
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
SpellCheckResponse spellCheckResp = new SpellCheckResponse(nl);
|
SpellCheckResponse spellCheckResp = new SpellCheckResponse(nl);
|
||||||
Iterable<Object> originalTermStrings = (Iterable<Object>) nl.get("originalTerms");
|
Iterable<Object> originalTermStrings = (Iterable<Object>) nl.get("originalTerms");
|
||||||
if(originalTermStrings!=null) {
|
if(originalTermStrings!=null) {
|
||||||
mergeData.originalTerms = new HashSet<>();
|
mergeData.originalTerms = new HashSet<>();
|
||||||
|
@ -423,14 +423,14 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
if (o != null) origFreq += o;
|
if (o != null) origFreq += o;
|
||||||
origFreq += suggestion.getOriginalFrequency();
|
origFreq += suggestion.getOriginalFrequency();
|
||||||
mergeData.origVsFreq.put(suggestion.getToken(), origFreq);
|
mergeData.origVsFreq.put(suggestion.getToken(), origFreq);
|
||||||
|
|
||||||
//# shards reporting
|
//# shards reporting
|
||||||
Integer origShards = mergeData.origVsShards.get(suggestion.getToken());
|
Integer origShards = mergeData.origVsShards.get(suggestion.getToken());
|
||||||
if(origShards==null) {
|
if(origShards==null) {
|
||||||
mergeData.origVsShards.put(suggestion.getToken(), 1);
|
mergeData.origVsShards.put(suggestion.getToken(), 1);
|
||||||
} else {
|
} else {
|
||||||
mergeData.origVsShards.put(suggestion.getToken(), ++origShards);
|
mergeData.origVsShards.put(suggestion.getToken(), ++origShards);
|
||||||
}
|
}
|
||||||
|
|
||||||
// find best suggestions
|
// find best suggestions
|
||||||
for (int i = 0; i < suggestion.getNumFound(); i++) {
|
for (int i = 0; i < suggestion.getNumFound(); i++) {
|
||||||
|
@ -451,7 +451,7 @@ 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;
|
||||||
|
@ -480,7 +480,7 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
collations.put(coll.getCollationQuery(), coll);
|
collations.put(coll.getCollationQuery(), coll);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
NamedList expandedCollation = (NamedList) o;
|
NamedList expandedCollation = (NamedList) o;
|
||||||
SpellCheckCollation coll = new SpellCheckCollation();
|
SpellCheckCollation coll = new SpellCheckCollation();
|
||||||
coll.setCollationQuery((String) expandedCollation.get("collationQuery"));
|
coll.setCollationQuery((String) expandedCollation.get("collationQuery"));
|
||||||
coll.setHits((Integer) expandedCollation.get("hits"));
|
coll.setHits((Integer) expandedCollation.get("hits"));
|
||||||
|
@ -514,7 +514,7 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
FlagsAttribute flagsAtt = ts.addAttribute(FlagsAttribute.class);
|
FlagsAttribute flagsAtt = ts.addAttribute(FlagsAttribute.class);
|
||||||
PayloadAttribute payloadAtt = ts.addAttribute(PayloadAttribute.class);
|
PayloadAttribute payloadAtt = ts.addAttribute(PayloadAttribute.class);
|
||||||
PositionIncrementAttribute posIncAtt = ts.addAttribute(PositionIncrementAttribute.class);
|
PositionIncrementAttribute posIncAtt = ts.addAttribute(PositionIncrementAttribute.class);
|
||||||
|
|
||||||
while (ts.incrementToken()){
|
while (ts.incrementToken()){
|
||||||
Token token = new Token();
|
Token token = new Token();
|
||||||
token.copyBuffer(termAtt.buffer(), 0, termAtt.length());
|
token.copyBuffer(termAtt.buffer(), 0, termAtt.length());
|
||||||
|
@ -547,7 +547,7 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
return ssc;
|
return ssc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDictionaryNameAsSingleString(String[] dictName) {
|
private String getDictionaryNameAsSingleString(String[] dictName) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (String dn : dictName) {
|
for (String dn : dictName) {
|
||||||
|
@ -604,7 +604,7 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
suggestionList.add("numFound", theSuggestions.size());
|
suggestionList.add("numFound", theSuggestions.size());
|
||||||
suggestionList.add("startOffset", inputToken.startOffset());
|
suggestionList.add("startOffset", inputToken.startOffset());
|
||||||
suggestionList.add("endOffset", inputToken.endOffset());
|
suggestionList.add("endOffset", inputToken.endOffset());
|
||||||
|
|
||||||
// Logical structure of normal (non-extended) results:
|
// Logical structure of normal (non-extended) results:
|
||||||
// "suggestion":["alt1","alt2"]
|
// "suggestion":["alt1","alt2"]
|
||||||
//
|
//
|
||||||
|
@ -616,7 +616,7 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
if (extendedResults && hasFreqInfo) {
|
if (extendedResults && hasFreqInfo) {
|
||||||
suggestionList.add("origFreq", spellingResult
|
suggestionList.add("origFreq", spellingResult
|
||||||
.getTokenFrequency(inputToken));
|
.getTokenFrequency(inputToken));
|
||||||
|
|
||||||
ArrayList<SimpleOrderedMap> sugs = new ArrayList<>();
|
ArrayList<SimpleOrderedMap> sugs = new ArrayList<>();
|
||||||
suggestionList.add("suggestion", sugs);
|
suggestionList.add("suggestion", sugs);
|
||||||
for (Map.Entry<String,Integer> suggEntry : theSuggestions.entrySet()) {
|
for (Map.Entry<String,Integer> suggEntry : theSuggestions.entrySet()) {
|
||||||
|
@ -628,7 +628,7 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
} else {
|
} else {
|
||||||
suggestionList.add("suggestion", theSuggestions.keySet());
|
suggestionList.add("suggestion", theSuggestions.keySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasFreqInfo) {
|
if (hasFreqInfo) {
|
||||||
Integer tokenFrequency = spellingResult.getTokenFrequency(inputToken);
|
Integer tokenFrequency = spellingResult.getTokenFrequency(inputToken);
|
||||||
if (tokenFrequency==null || tokenFrequency == 0) {
|
if (tokenFrequency==null || tokenFrequency == 0) {
|
||||||
|
@ -648,45 +648,21 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
boolean hasDefault = false;
|
boolean hasDefault = false;
|
||||||
for (int i = 0; i < initParams.size(); i++) {
|
for (int i = 0; i < initParams.size(); i++) {
|
||||||
if (initParams.getName(i).equals("spellchecker")) {
|
if (initParams.getName(i).equals("spellchecker")) {
|
||||||
NamedList spellchecker = (NamedList) initParams.getVal(i);
|
Object cfg = initParams.getVal(i);
|
||||||
String className = (String) spellchecker.get("classname");
|
if (cfg instanceof NamedList) {
|
||||||
// TODO: this is a little bit sneaky: warn if class isnt supplied
|
addSpellChecker(core, hasDefault, (NamedList) cfg);
|
||||||
// so that it's mandatory in a future release?
|
} else if (cfg instanceof Map) {
|
||||||
if (className == null)
|
System.out.println("##mapspellchecker");//todo nocommit
|
||||||
className = IndexBasedSpellChecker.class.getName();
|
addSpellChecker(core, hasDefault, new NamedList((Map) cfg));
|
||||||
SolrResourceLoader loader = core.getResourceLoader();
|
} else if (cfg instanceof List) {
|
||||||
SolrSpellChecker checker = loader.newInstance(className, SolrSpellChecker.class);
|
for (Object o : (List) cfg) {
|
||||||
if (checker != null) {
|
if (o instanceof Map) {
|
||||||
String dictionary = checker.init(spellchecker, core);
|
addSpellChecker(core, hasDefault, new NamedList((Map) o));
|
||||||
if (dictionary != null) {
|
|
||||||
boolean isDefault = dictionary.equals(SolrSpellChecker.DEFAULT_DICTIONARY_NAME);
|
|
||||||
if (isDefault == true && hasDefault == false){
|
|
||||||
hasDefault = true;
|
|
||||||
} else if (isDefault == true && hasDefault == true){
|
|
||||||
throw new RuntimeException("More than one dictionary is missing name.");
|
|
||||||
}
|
|
||||||
spellCheckers.put(dictionary, checker);
|
|
||||||
} else {
|
|
||||||
if (hasDefault == false){
|
|
||||||
spellCheckers.put(SolrSpellChecker.DEFAULT_DICTIONARY_NAME, checker);
|
|
||||||
hasDefault = true;
|
|
||||||
} else {
|
|
||||||
throw new RuntimeException("More than one dictionary is missing name.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Register event listeners for this SpellChecker
|
|
||||||
core.registerFirstSearcherListener(new SpellCheckerListener(core, checker, false, false));
|
|
||||||
boolean buildOnCommit = Boolean.parseBoolean((String) spellchecker.get("buildOnCommit"));
|
|
||||||
boolean buildOnOptimize = Boolean.parseBoolean((String) spellchecker.get("buildOnOptimize"));
|
|
||||||
if (buildOnCommit || buildOnOptimize) {
|
|
||||||
LOG.info("Registering newSearcher listener for spellchecker: " + checker.getDictionaryName());
|
|
||||||
core.registerNewSearcherListener(new SpellCheckerListener(core, checker, buildOnCommit, buildOnOptimize));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new RuntimeException("Can't load spell checker: " + className);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, QueryConverter> queryConverters = new HashMap<>();
|
Map<String, QueryConverter> queryConverters = new HashMap<>();
|
||||||
core.initPlugins(queryConverters,QueryConverter.class);
|
core.initPlugins(queryConverters,QueryConverter.class);
|
||||||
|
@ -711,6 +687,47 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean addSpellChecker(SolrCore core, boolean hasDefault, NamedList spellchecker) {
|
||||||
|
String className = (String) spellchecker.get("classname");
|
||||||
|
if (className == null) className = (String) spellchecker.get("class");
|
||||||
|
// TODO: this is a little bit sneaky: warn if class isnt supplied
|
||||||
|
// so that it's mandatory in a future release?
|
||||||
|
if (className == null)
|
||||||
|
className = IndexBasedSpellChecker.class.getName();
|
||||||
|
SolrResourceLoader loader = core.getResourceLoader();
|
||||||
|
SolrSpellChecker checker = loader.newInstance(className, SolrSpellChecker.class);
|
||||||
|
if (checker != null) {
|
||||||
|
String dictionary = checker.init(spellchecker, core);
|
||||||
|
if (dictionary != null) {
|
||||||
|
boolean isDefault = dictionary.equals(SolrSpellChecker.DEFAULT_DICTIONARY_NAME);
|
||||||
|
if (isDefault && !hasDefault) {
|
||||||
|
hasDefault = true;
|
||||||
|
} else if (isDefault && hasDefault) {
|
||||||
|
throw new RuntimeException("More than one dictionary is missing name.");
|
||||||
|
}
|
||||||
|
spellCheckers.put(dictionary, checker);
|
||||||
|
} else {
|
||||||
|
if (!hasDefault) {
|
||||||
|
spellCheckers.put(SolrSpellChecker.DEFAULT_DICTIONARY_NAME, checker);
|
||||||
|
hasDefault = true;
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("More than one dictionary is missing name.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Register event listeners for this SpellChecker
|
||||||
|
core.registerFirstSearcherListener(new SpellCheckerListener(core, checker, false, false));
|
||||||
|
boolean buildOnCommit = Boolean.parseBoolean((String) spellchecker.get("buildOnCommit"));
|
||||||
|
boolean buildOnOptimize = Boolean.parseBoolean((String) spellchecker.get("buildOnOptimize"));
|
||||||
|
if (buildOnCommit || buildOnOptimize) {
|
||||||
|
LOG.info("Registering newSearcher listener for spellchecker: " + checker.getDictionaryName());
|
||||||
|
core.registerNewSearcherListener(new SpellCheckerListener(core, checker, buildOnCommit, buildOnOptimize));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Can't load spell checker: " + className);
|
||||||
|
}
|
||||||
|
return hasDefault;
|
||||||
|
}
|
||||||
|
|
||||||
private static class SpellCheckerListener implements SolrEventListener {
|
private static class SpellCheckerListener implements SolrEventListener {
|
||||||
private final SolrCore core;
|
private final SolrCore core;
|
||||||
private final SolrSpellChecker checker;
|
private final SolrSpellChecker checker;
|
||||||
|
|
|
@ -387,6 +387,28 @@ public class TestSolrConfigHandler extends RestTestBase {
|
||||||
assertNotNull("no object /config/initParams : "+ TestBlobHandler.getAsString(map) , l);
|
assertNotNull("no object /config/initParams : "+ TestBlobHandler.getAsString(map) , l);
|
||||||
assertEquals( 1, l.size());
|
assertEquals( 1, l.size());
|
||||||
assertEquals( "val", ((Map)l.get(0)).get("key") );
|
assertEquals( "val", ((Map)l.get(0)).get("key") );
|
||||||
|
|
||||||
|
|
||||||
|
payload = "{\n" +
|
||||||
|
" 'add-searchcomponent': {\n" +
|
||||||
|
" 'name': 'myspellcheck',\n" +
|
||||||
|
" 'class': 'solr.SpellCheckComponent',\n" +
|
||||||
|
" 'queryAnalyzerFieldType': 'text_general',\n" +
|
||||||
|
" 'spellchecker': {\n" +
|
||||||
|
" 'name': 'default',\n" +
|
||||||
|
" 'field': '_text_',\n" +
|
||||||
|
" 'class': 'solr.DirectSolrSpellChecker'\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}";
|
||||||
|
runConfigCommand(writeHarness, "/config?wt=json", payload);
|
||||||
|
map = testForResponseElement(writeHarness,
|
||||||
|
testServerBaseUrl,
|
||||||
|
"/config?wt=json",
|
||||||
|
cloudSolrClient,
|
||||||
|
Arrays.asList("config", "searchComponent","myspellcheck", "spellchecker", "class"),
|
||||||
|
"solr.DirectSolrSpellChecker",
|
||||||
|
10);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map testForResponseElement(RestTestHarness harness,
|
public static Map testForResponseElement(RestTestHarness harness,
|
||||||
|
|
Loading…
Reference in New Issue