mirror of https://github.com/apache/lucene.git
SOLR-622: SpellCheckComponent supports auto-loading indices on startup and optionally, (re)builds indices on newSearcher event, if configured in solrconfig.xml
git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@681604 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
258cb3e84d
commit
68083b3af4
|
@ -336,6 +336,10 @@ New Features
|
|||
data sources, processors and transformers for importing data. Supports full data imports as well as
|
||||
incremental (delta) indexing. See http://wiki.apache.org/solr/DataImportHandler for more details.
|
||||
(Noble Paul, shalin)
|
||||
|
||||
67. SOLR-622: SpellCheckComponent supports auto-loading indices on startup and optionally, (re)builds indices
|
||||
on newSearcher event, if configured in solrconfig.xml
|
||||
(shalin)
|
||||
|
||||
Changes in runtime behavior
|
||||
1. SOLR-559: use Lucene updateDocument, deleteDocuments methods. This
|
||||
|
|
|
@ -17,10 +17,24 @@
|
|||
|
||||
package org.apache.solr.handler.component;
|
||||
|
||||
import org.apache.lucene.analysis.Token;
|
||||
import org.apache.lucene.analysis.WhitespaceAnalyzer;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.lucene.analysis.Token;
|
||||
import org.apache.lucene.analysis.TokenStream;
|
||||
import org.apache.lucene.analysis.WhitespaceAnalyzer;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.common.params.CommonParams;
|
||||
|
@ -30,29 +44,21 @@ import org.apache.solr.common.util.NamedList;
|
|||
import org.apache.solr.common.util.SimpleOrderedMap;
|
||||
import org.apache.solr.core.SolrConfig;
|
||||
import org.apache.solr.core.SolrCore;
|
||||
import org.apache.solr.core.SolrEventListener;
|
||||
import org.apache.solr.core.SolrResourceLoader;
|
||||
import org.apache.solr.schema.FieldType;
|
||||
import org.apache.solr.schema.IndexSchema;
|
||||
import org.apache.solr.search.SolrIndexSearcher;
|
||||
import org.apache.solr.spelling.AbstractLuceneSpellChecker;
|
||||
import org.apache.solr.spelling.IndexBasedSpellChecker;
|
||||
import org.apache.solr.spelling.QueryConverter;
|
||||
import org.apache.solr.spelling.SolrSpellChecker;
|
||||
import org.apache.solr.spelling.SpellingResult;
|
||||
import org.apache.solr.spelling.QueryConverter;
|
||||
import org.apache.solr.util.RefCounted;
|
||||
import org.apache.solr.util.plugin.NamedListPluginLoader;
|
||||
import org.apache.solr.util.plugin.SolrCoreAware;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* A SearchComponent implementation which provides support for spell checking
|
||||
* and suggestions using the Lucene contributed SpellChecker.
|
||||
|
@ -263,6 +269,12 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
|||
throw new RuntimeException("More than one dictionary is missing name.");
|
||||
}
|
||||
}
|
||||
// Register event listeners for this SpellChecker
|
||||
core.registerFirstSearcherListener(new SpellCheckerListener(core, checker, true));
|
||||
if (Boolean.parseBoolean((String)spellchecker.get("buildOnCommit"))) {
|
||||
LOG.info("Registering newSearcher listener for spellchecker: " + checker.getDictionaryName());
|
||||
core.registerNewSearcherListener(new SpellCheckerListener(core, checker, false));
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Can't load spell checker: " + className);
|
||||
}
|
||||
|
@ -294,6 +306,47 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
|
|||
}
|
||||
}
|
||||
|
||||
private static class SpellCheckerListener implements SolrEventListener {
|
||||
private final SolrCore core;
|
||||
private final SolrSpellChecker checker;
|
||||
private final boolean firstSearcher;
|
||||
|
||||
public SpellCheckerListener(SolrCore core, SolrSpellChecker checker, boolean firstSearcher) {
|
||||
this.core = core;
|
||||
this.checker = checker;
|
||||
this.firstSearcher = firstSearcher;
|
||||
}
|
||||
|
||||
public void init(NamedList args) {
|
||||
}
|
||||
|
||||
public void newSearcher(SolrIndexSearcher newSearcher,
|
||||
SolrIndexSearcher currentSearcher) {
|
||||
if (firstSearcher) {
|
||||
try {
|
||||
LOG.info("Loading spell index for spellchecker: "
|
||||
+ checker.getDictionaryName());
|
||||
checker.reload();
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.SEVERE, "Exception in reloading spell check index for spellchecker: " + checker.getDictionaryName(), e);
|
||||
}
|
||||
} else {
|
||||
// newSearcher event
|
||||
try {
|
||||
LOG.info("Building spell index for spell checker: " + checker.getDictionaryName());
|
||||
checker.build(core, newSearcher);
|
||||
} catch (Exception e) {
|
||||
LOG.log(Level.SEVERE,
|
||||
"Exception in building spell check index for spellchecker: " + checker.getDictionaryName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void postCommit() {
|
||||
}
|
||||
}
|
||||
|
||||
// ///////////////////////////////////////////
|
||||
// / SolrInfoMBean
|
||||
// //////////////////////////////////////////
|
||||
|
|
|
@ -67,7 +67,7 @@ public class SpellCheckComponentTest extends AbstractSolrTestCase {
|
|||
assertU(adoc("id", "8", "lowerfilt", "blee"));
|
||||
assertU("commit", commit());
|
||||
}
|
||||
|
||||
|
||||
public void testExtendedResultsCount() throws Exception {
|
||||
SolrCore core = h.getCore();
|
||||
SearchComponent speller = core.getSearchComponent("spellcheck");
|
||||
|
@ -348,7 +348,19 @@ public class SpellCheckComponentTest extends AbstractSolrTestCase {
|
|||
fail("NullPointerException due to reload not initializing analyzers");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testRebuildOnCommit() throws Exception {
|
||||
SolrQueryRequest req = req("q", "lowerfilt:lucenejavt", "qt", "spellCheckCompRH", "spellcheck", "true");
|
||||
String response = h.query(req);
|
||||
assertFalse("No suggestions should be returned", response.contains("lucenejava"));
|
||||
|
||||
assertU(adoc("id", "11231", "lowerfilt", "lucenejava"));
|
||||
assertU("commit", commit());
|
||||
|
||||
assertQ(req, "//arr[@name='suggestion'][.='lucenejava']");
|
||||
}
|
||||
|
||||
// TODO: add more tests for various spelling options
|
||||
|
||||
}
|
||||
|
|
|
@ -326,6 +326,7 @@
|
|||
<str name="name">default</str>
|
||||
<str name="field">lowerfilt</str>
|
||||
<str name="spellcheckIndexDir">spellchecker1</str>
|
||||
<str name="buildOnCommit">true</str>
|
||||
</lst>
|
||||
<!-- Example of using different distance measure -->
|
||||
<lst name="spellchecker">
|
||||
|
|
Loading…
Reference in New Issue