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
|
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.
|
incremental (delta) indexing. See http://wiki.apache.org/solr/DataImportHandler for more details.
|
||||||
(Noble Paul, shalin)
|
(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
|
Changes in runtime behavior
|
||||||
1. SOLR-559: use Lucene updateDocument, deleteDocuments methods. This
|
1. SOLR-559: use Lucene updateDocument, deleteDocuments methods. This
|
||||||
|
|
|
@ -17,10 +17,24 @@
|
||||||
|
|
||||||
package org.apache.solr.handler.component;
|
package org.apache.solr.handler.component;
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Token;
|
import java.io.IOException;
|
||||||
import org.apache.lucene.analysis.WhitespaceAnalyzer;
|
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.Analyzer;
|
||||||
|
import org.apache.lucene.analysis.Token;
|
||||||
import org.apache.lucene.analysis.TokenStream;
|
import org.apache.lucene.analysis.TokenStream;
|
||||||
|
import org.apache.lucene.analysis.WhitespaceAnalyzer;
|
||||||
import org.apache.lucene.index.IndexReader;
|
import org.apache.lucene.index.IndexReader;
|
||||||
import org.apache.solr.common.SolrException;
|
import org.apache.solr.common.SolrException;
|
||||||
import org.apache.solr.common.params.CommonParams;
|
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.common.util.SimpleOrderedMap;
|
||||||
import org.apache.solr.core.SolrConfig;
|
import org.apache.solr.core.SolrConfig;
|
||||||
import org.apache.solr.core.SolrCore;
|
import org.apache.solr.core.SolrCore;
|
||||||
|
import org.apache.solr.core.SolrEventListener;
|
||||||
import org.apache.solr.core.SolrResourceLoader;
|
import org.apache.solr.core.SolrResourceLoader;
|
||||||
import org.apache.solr.schema.FieldType;
|
import org.apache.solr.schema.FieldType;
|
||||||
import org.apache.solr.schema.IndexSchema;
|
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.IndexBasedSpellChecker;
|
||||||
|
import org.apache.solr.spelling.QueryConverter;
|
||||||
import org.apache.solr.spelling.SolrSpellChecker;
|
import org.apache.solr.spelling.SolrSpellChecker;
|
||||||
import org.apache.solr.spelling.SpellingResult;
|
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.NamedListPluginLoader;
|
||||||
import org.apache.solr.util.plugin.SolrCoreAware;
|
import org.apache.solr.util.plugin.SolrCoreAware;
|
||||||
import org.w3c.dom.NodeList;
|
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
|
* A SearchComponent implementation which provides support for spell checking
|
||||||
* and suggestions using the Lucene contributed SpellChecker.
|
* 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.");
|
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 {
|
} else {
|
||||||
throw new RuntimeException("Can't load spell checker: " + className);
|
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
|
// / SolrInfoMBean
|
||||||
// //////////////////////////////////////////
|
// //////////////////////////////////////////
|
||||||
|
|
|
@ -67,7 +67,7 @@ public class SpellCheckComponentTest extends AbstractSolrTestCase {
|
||||||
assertU(adoc("id", "8", "lowerfilt", "blee"));
|
assertU(adoc("id", "8", "lowerfilt", "blee"));
|
||||||
assertU("commit", commit());
|
assertU("commit", commit());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testExtendedResultsCount() throws Exception {
|
public void testExtendedResultsCount() throws Exception {
|
||||||
SolrCore core = h.getCore();
|
SolrCore core = h.getCore();
|
||||||
SearchComponent speller = core.getSearchComponent("spellcheck");
|
SearchComponent speller = core.getSearchComponent("spellcheck");
|
||||||
|
@ -348,7 +348,19 @@ public class SpellCheckComponentTest extends AbstractSolrTestCase {
|
||||||
fail("NullPointerException due to reload not initializing analyzers");
|
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
|
// TODO: add more tests for various spelling options
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -326,6 +326,7 @@
|
||||||
<str name="name">default</str>
|
<str name="name">default</str>
|
||||||
<str name="field">lowerfilt</str>
|
<str name="field">lowerfilt</str>
|
||||||
<str name="spellcheckIndexDir">spellchecker1</str>
|
<str name="spellcheckIndexDir">spellchecker1</str>
|
||||||
|
<str name="buildOnCommit">true</str>
|
||||||
</lst>
|
</lst>
|
||||||
<!-- Example of using different distance measure -->
|
<!-- Example of using different distance measure -->
|
||||||
<lst name="spellchecker">
|
<lst name="spellchecker">
|
||||||
|
|
Loading…
Reference in New Issue