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:
Noble Paul 2015-09-29 13:31:35 +00:00
parent a8d08f8247
commit 155f5a5dad
3 changed files with 115 additions and 73 deletions

View File

@ -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
---------------------- ----------------------

View File

@ -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;

View File

@ -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,