You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by jd...@apache.org on 2012/06/04 19:55:26 UTC
svn commit: r1346058 [2/2] - in /lucene/dev/trunk/solr: ./
core/src/java/org/apache/solr/handler/component/
core/src/java/org/apache/solr/spelling/ core/src/test-files/solr/conf/
core/src/test/org/apache/solr/handler/component/ core/src/test/org/apache...
Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/spelling/SpellingQueryConverterTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/spelling/SpellingQueryConverterTest.java?rev=1346058&r1=1346057&r2=1346058&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/spelling/SpellingQueryConverterTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/spelling/SpellingQueryConverterTest.java Mon Jun 4 17:55:25 2012
@@ -23,7 +23,9 @@ import org.apache.lucene.util.LuceneTest
import org.apache.solr.common.util.NamedList;
import org.junit.Test;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
/**
@@ -126,4 +128,75 @@ public class SpellingQueryConverterTest
assertTrue("tokens is null and it shouldn't be", tokens != null);
assertEquals("tokens Size: " + tokens.size() + " is not 2", 2, tokens.size());
}
+
+ @Test
+ public void testRequiredOrProhibitedFlags() {
+ SpellingQueryConverter converter = new SpellingQueryConverter();
+ converter.init(new NamedList());
+ converter.setAnalyzer(new WhitespaceAnalyzer(TEST_VERSION_CURRENT));
+
+ {
+ List<Token> tokens = new ArrayList<Token>(converter.convert("aaa bbb ccc"));
+ assertTrue("Should have 3 tokens", tokens != null && tokens.size()==3);
+ assertTrue("token 1 should be optional", !hasRequiredFlag(tokens.get(0)) && !hasProhibitedFlag(tokens.get(0)));
+ assertTrue("token 2 should be optional", !hasRequiredFlag(tokens.get(1)) && !hasProhibitedFlag(tokens.get(1)));
+ assertTrue("token 3 should be optional", !hasRequiredFlag(tokens.get(2)) && !hasProhibitedFlag(tokens.get(2)));
+ }
+ {
+ List<Token> tokens = new ArrayList<Token>(converter.convert("+aaa bbb -ccc"));
+ assertTrue("Should have 3 tokens", tokens != null && tokens.size()==3);
+ assertTrue("token 1 should be required", hasRequiredFlag(tokens.get(0)) && !hasProhibitedFlag(tokens.get(0)));
+ assertTrue("token 2 should be optional", !hasRequiredFlag(tokens.get(1)) && !hasProhibitedFlag(tokens.get(1)));
+ assertTrue("token 3 should be prohibited", !hasRequiredFlag(tokens.get(2)) && hasProhibitedFlag(tokens.get(2)));
+ }
+ {
+ List<Token> tokens = new ArrayList<Token>(converter.convert("aaa AND bbb ccc"));
+ assertTrue("Should have 3 tokens", tokens != null && tokens.size()==3);
+ assertTrue("token 1 doesn't precede n.b.o.", !hasNBOFlag(tokens.get(0)) && hasInBooleanFlag(tokens.get(0)));
+ assertTrue("token 2 doesn't precede n.b.o.", !hasNBOFlag(tokens.get(1)) && hasInBooleanFlag(tokens.get(0)));
+ assertTrue("token 3 doesn't precede n.b.o.", !hasNBOFlag(tokens.get(2)) && hasInBooleanFlag(tokens.get(0)));
+ }
+ {
+ List<Token> tokens = new ArrayList<Token>(converter.convert("aaa OR bbb OR ccc"));
+ assertTrue("Should have 3 tokens", tokens != null && tokens.size()==3);
+ assertTrue("token 1 doesn't precede n.b.o.", !hasNBOFlag(tokens.get(0)) && hasInBooleanFlag(tokens.get(0)));
+ assertTrue("token 2 doesn't precede n.b.o.", !hasNBOFlag(tokens.get(1)) && hasInBooleanFlag(tokens.get(0)));
+ assertTrue("token 3 doesn't precede n.b.o.", !hasNBOFlag(tokens.get(2)) && hasInBooleanFlag(tokens.get(0)));
+ }
+ {
+ List<Token> tokens = new ArrayList<Token>(converter.convert("aaa AND bbb NOT ccc"));
+ assertTrue("Should have 3 tokens", tokens != null && tokens.size()==3);
+ assertTrue("token 1 doesn't precede n.b.o.", !hasNBOFlag(tokens.get(0)) && hasInBooleanFlag(tokens.get(0)));
+ assertTrue("token 2 precedes n.b.o.", hasNBOFlag(tokens.get(1)) && hasInBooleanFlag(tokens.get(0)));
+ assertTrue("token 3 doesn't precede n.b.o.", !hasNBOFlag(tokens.get(2)) && hasInBooleanFlag(tokens.get(0)));
+ }
+ {
+ List<Token> tokens = new ArrayList<Token>(converter.convert("aaa NOT bbb AND ccc"));
+ assertTrue("Should have 3 tokens", tokens != null && tokens.size()==3);
+ assertTrue("token 1 precedes n.b.o.", hasNBOFlag(tokens.get(0)) && hasInBooleanFlag(tokens.get(0)));
+ assertTrue("token 2 precedes n.b.o.", hasNBOFlag(tokens.get(1)) && hasInBooleanFlag(tokens.get(0)));
+ assertTrue("token 3 doesn't precedes n.b.o.", !hasNBOFlag(tokens.get(2)) && hasInBooleanFlag(tokens.get(0)));
+ }
+ {
+ List<Token> tokens = new ArrayList<Token>(converter.convert("aaa AND NOT bbb AND ccc"));
+ assertTrue("Should have 3 tokens", tokens != null && tokens.size()==3);
+ assertTrue("token 1 precedes n.b.o.", hasNBOFlag(tokens.get(0)) && hasInBooleanFlag(tokens.get(0)));
+ assertTrue("token 2 precedes n.b.o.", hasNBOFlag(tokens.get(1)) && hasInBooleanFlag(tokens.get(0)));
+ assertTrue("token 3 doesn't precedes n.b.o.", !hasNBOFlag(tokens.get(2)) && hasInBooleanFlag(tokens.get(0)));
+ }
+
+ }
+
+ private boolean hasRequiredFlag(Token t) {
+ return (t.getFlags() & QueryConverter.REQUIRED_TERM_FLAG) == QueryConverter.REQUIRED_TERM_FLAG;
+ }
+ private boolean hasProhibitedFlag(Token t) {
+ return (t.getFlags() & QueryConverter.PROHIBITED_TERM_FLAG) == QueryConverter.PROHIBITED_TERM_FLAG;
+ }
+ private boolean hasNBOFlag(Token t) {
+ return (t.getFlags() & QueryConverter.TERM_PRECEDES_NEW_BOOLEAN_OPERATOR_FLAG) == QueryConverter.TERM_PRECEDES_NEW_BOOLEAN_OPERATOR_FLAG;
+ }
+ private boolean hasInBooleanFlag(Token t) {
+ return (t.getFlags() & QueryConverter.TERM_IN_BOOLEAN_QUERY_FLAG) == QueryConverter.TERM_IN_BOOLEAN_QUERY_FLAG;
+ }
}
Added: lucene/dev/trunk/solr/core/src/test/org/apache/solr/spelling/WordBreakSolrSpellCheckerTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/spelling/WordBreakSolrSpellCheckerTest.java?rev=1346058&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/spelling/WordBreakSolrSpellCheckerTest.java (added)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/spelling/WordBreakSolrSpellCheckerTest.java Mon Jun 4 17:55:25 2012
@@ -0,0 +1,273 @@
+package org.apache.solr.spelling;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.analysis.Token;
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.handler.component.SpellCheckComponent;
+import org.apache.solr.search.SolrIndexSearcher;
+import org.apache.solr.util.RefCounted;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class WordBreakSolrSpellCheckerTest extends SolrTestCaseJ4 {
+
+ @BeforeClass
+ public static void beforeClass() throws Exception {
+ initCore("solrconfig-spellcheckcomponent.xml","schema.xml");
+ assertNull(h.validateUpdate(adoc("id", "0", "lowerfilt", "pain table paintablepine pi ne in able")));
+ assertNull(h.validateUpdate(adoc("id", "1", "lowerfilt", "paint able pineapple goodness in")));
+ assertNull(h.validateUpdate(adoc("id", "2", "lowerfilt", "pa in table pineapplegoodness")));
+ assertNull(h.validateUpdate(adoc("id", "3", "lowerfilt", "printable line in ample food mess")));
+ assertNull(h.validateUpdate(adoc("id", "4", "lowerfilt", "printable in pointable paint able")));
+ assertNull(h.validateUpdate(adoc("id", "5", "lowerfilt", "printable in puntable paint able ")));
+ assertNull(h.validateUpdate(adoc("id", "6", "lowerfilt", "paint able in pintable plantable")));
+ assertNull(h.validateUpdate(commit()));
+ //docfreq=7: in
+ //docfreq=5: able
+ //docfreq=4: paint
+ //docfreq=3: printable
+ //docfreq=2: table
+ //docfreq=1: {all others}
+ }
+
+ @Test
+ public void testStandAlone() throws Exception {
+ SolrCore core = h.getCore();
+ WordBreakSolrSpellChecker checker = new WordBreakSolrSpellChecker();
+ NamedList<String> params = new NamedList<String>();
+ params.add("field", "lowerfilt");
+ params.add(WordBreakSolrSpellChecker.PARAM_BREAK_WORDS, "true");
+ params.add(WordBreakSolrSpellChecker.PARAM_COMBINE_WORDS, "true");
+ params.add(WordBreakSolrSpellChecker.PARAM_MAX_CHANGES, "10");
+ checker.init(params, core);
+
+ RefCounted<SolrIndexSearcher> searcher = core.getSearcher();
+ QueryConverter qc = new SpellingQueryConverter();
+ qc.setAnalyzer(new MockAnalyzer(random()));
+ Collection<Token> tokens = qc.convert("paintable pine apple good ness");
+ SpellingOptions spellOpts = new SpellingOptions(tokens, searcher.get().getIndexReader(), 10);
+ SpellingResult result = checker.getSuggestions(spellOpts);
+ searcher.decref();
+
+ assertTrue(result != null && result.getSuggestions() != null);
+ assertTrue(result.getSuggestions().size()==6);
+
+ for(Map.Entry<Token, LinkedHashMap<String, Integer>> s : result.getSuggestions().entrySet()) {
+ Token orig = s.getKey();
+ String[] corr = s.getValue().keySet().toArray(new String[0]);
+ if(orig.toString().equals("paintable")) {
+ assertTrue(orig.startOffset()==0);
+ assertTrue(orig.endOffset()==9);
+ assertTrue(orig.length()==9);
+ assertTrue(corr.length==3);
+ assertTrue(corr[0].equals("paint able")); //1 op ; max doc freq=5
+ assertTrue(corr[1].equals("pain table")); //1 op ; max doc freq=2
+ assertTrue(corr[2].equals("pa in table")); //2 ops
+ } else if(orig.toString().equals("pine apple")) {
+ assertTrue(orig.startOffset()==10);
+ assertTrue(orig.endOffset()==20);
+ assertTrue(orig.length()==10);
+ assertTrue(corr.length==1);
+ assertTrue(corr[0].equals("pineapple"));
+ } else if(orig.toString().equals("paintable pine")) {
+ assertTrue(orig.startOffset()==0);
+ assertTrue(orig.endOffset()==14);
+ assertTrue(orig.length()==14);
+ assertTrue(corr.length==1);
+ assertTrue(corr[0].equals("paintablepine"));
+ } else if(orig.toString().equals("good ness")) {
+ assertTrue(orig.startOffset()==21);
+ assertTrue(orig.endOffset()==30);
+ assertTrue(orig.length()==9);
+ assertTrue(corr.length==1);
+ assertTrue(corr[0].equals("goodness"));
+ } else if(orig.toString().equals("pine apple good ness")) {
+ assertTrue(orig.startOffset()==10);
+ assertTrue(orig.endOffset()==30);
+ assertTrue(orig.length()==20);
+ assertTrue(corr.length==1);
+ assertTrue(corr[0].equals("pineapplegoodness"));
+ } else if(orig.toString().equals("pine")) {
+ assertTrue(orig.startOffset()==10);
+ assertTrue(orig.endOffset()==14);
+ assertTrue(orig.length()==4);
+ assertTrue(corr.length==1);
+ assertTrue(corr[0].equals("pi ne"));
+ } else {
+ fail("Unexpected original result: " + orig);
+ }
+ }
+ }
+ @Test
+ public void testInConjunction() throws Exception {
+ assertQ(req(
+ "q", "lowerfilt:(paintable pine apple good ness)",
+ "qt", "spellCheckWithWordbreak",
+ "indent", "true",
+ SpellCheckComponent.SPELLCHECK_BUILD, "true",
+ SpellCheckComponent.COMPONENT_NAME, "true",
+ SpellCheckComponent.SPELLCHECK_ACCURACY, ".75",
+ SpellCheckComponent.SPELLCHECK_EXTENDED_RESULTS, "true"),
+ "//lst[@name='suggestions']/lst[1]/@name='paintable'",
+ "//lst[@name='suggestions']/lst[2]/@name='pine'",
+ "//lst[@name='suggestions']/lst[3]/@name='apple'",
+ "//lst[@name='suggestions']/lst[4]/@name='good'",
+ "//lst[@name='suggestions']/lst[5]/@name='ness'",
+ "//lst[@name='paintable']/int[@name='numFound']=8",
+ "//lst[@name='paintable']/int[@name='startOffset']=11",
+ "//lst[@name='paintable']/int[@name='endOffset']=20",
+ "//lst[@name='paintable']/arr[@name='suggestion']/str[1]='printable'", //SolrSpellChecker result interleaved
+ "//lst[@name='paintable']/arr[@name='suggestion']/str[2]='paint able'", //1 op ; max doc freq=5
+ "//lst[@name='paintable']/arr[@name='suggestion']/str[3]='pintable'", //SolrSpellChecker result interleaved
+ "//lst[@name='paintable']/arr[@name='suggestion']/str[4]='pain table'", //1 op ; max doc freq=4
+ "//lst[@name='paintable']/arr[@name='suggestion']/str[5]='pointable'", //SolrSpellChecker result interleaved
+ "//lst[@name='paintable']/arr[@name='suggestion']/str[6]='pa in table'",//2 ops
+ "//lst[@name='paintable']/arr[@name='suggestion']/str[7]='plantable'", //SolrSpellChecker result interleaved
+ "//lst[@name='paintable']/arr[@name='suggestion']/str[8]='puntable'", //SolrSpellChecker result interleaved
+ "//lst[@name='pine']/int[@name='numFound']=2",
+ "//lst[@name='pine']/int[@name='startOffset']=21",
+ "//lst[@name='pine']/int[@name='endOffset']=25",
+ "//lst[@name='pine']/arr[@name='suggestion']/str[1]='line'",
+ "//lst[@name='pine']/arr[@name='suggestion']/str[2]='pi ne'",
+ "//lst[@name='apple']/int[@name='numFound']=1",
+ "//lst[@name='apple']/arr[@name='suggestion']/str[1]='ample'",
+ "//lst[@name='good']/int[@name='numFound']=1",
+ "//lst[@name='good']/arr[@name='suggestion']/str[1]='food'",
+ "//lst[@name='ness']/int[@name='numFound']=1",
+ "//lst[@name='ness']/arr[@name='suggestion']/str[1]='mess'",
+ "//lst[@name='pine apple']/int[@name='numFound']=1",
+ "//lst[@name='pine apple']/int[@name='startOffset']=21",
+ "//lst[@name='pine apple']/int[@name='endOffset']=31",
+ "//lst[@name='pine apple']/arr[@name='suggestion']/str[1]='pineapple'",
+ "//lst[@name='paintable pine']/int[@name='numFound']=1",
+ "//lst[@name='paintable pine']/int[@name='startOffset']=11",
+ "//lst[@name='paintable pine']/int[@name='endOffset']=25",
+ "//lst[@name='paintable pine']/arr[@name='suggestion']/str[1]='paintablepine'",
+ "//lst[@name='good ness']/int[@name='numFound']=1",
+ "//lst[@name='good ness']/int[@name='startOffset']=32",
+ "//lst[@name='good ness']/int[@name='endOffset']=41",
+ "//lst[@name='good ness']/arr[@name='suggestion']/str[1]='goodness'",
+ "//lst[@name='pine apple good ness']/int[@name='numFound']=1",
+ "//lst[@name='pine apple good ness']/int[@name='startOffset']=21",
+ "//lst[@name='pine apple good ness']/int[@name='endOffset']=41",
+ "//lst[@name='pine apple good ness']/arr[@name='suggestion']/str[1]='pineapplegoodness'"
+ );
+ }
+ @Test
+ public void testCollate() throws Exception {
+ assertQ(req(
+ "q", "lowerfilt:(paintable pine apple godness)",
+ "qt", "spellCheckWithWordbreak",
+ "indent", "true",
+ SpellCheckComponent.SPELLCHECK_BUILD, "true",
+ SpellCheckComponent.COMPONENT_NAME, "true",
+ SpellCheckComponent.SPELLCHECK_ACCURACY, ".75",
+ SpellCheckComponent.SPELLCHECK_EXTENDED_RESULTS, "true",
+ SpellCheckComponent.SPELLCHECK_COLLATE, "true",
+ SpellCheckComponent.SPELLCHECK_COLLATE_EXTENDED_RESULTS, "true",
+ SpellCheckComponent.SPELLCHECK_MAX_COLLATIONS, "10"),
+ "//lst[@name='collation'][1 ]/str[@name='collationQuery']='lowerfilt:(printable line ample goodness)'",
+ "//lst[@name='collation'][2 ]/str[@name='collationQuery']='lowerfilt:(paintablepine ample goodness)'",
+ "//lst[@name='collation'][3 ]/str[@name='collationQuery']='lowerfilt:(printable pineapple goodness)'",
+ "//lst[@name='collation'][4 ]/str[@name='collationQuery']='lowerfilt:((paint able) line ample goodness)'",
+ "//lst[@name='collation'][5 ]/str[@name='collationQuery']='lowerfilt:(printable (pi ne) ample goodness)'",
+ "//lst[@name='collation'][6 ]/str[@name='collationQuery']='lowerfilt:((paint able) pineapple goodness)'",
+ "//lst[@name='collation'][7 ]/str[@name='collationQuery']='lowerfilt:((paint able) (pi ne) ample goodness)'",
+ "//lst[@name='collation'][8 ]/str[@name='collationQuery']='lowerfilt:(pintable line ample goodness)'",
+ "//lst[@name='collation'][9 ]/str[@name='collationQuery']='lowerfilt:(pintable pineapple goodness)'",
+ "//lst[@name='collation'][10]/str[@name='collationQuery']='lowerfilt:(pintable (pi ne) ample goodness)'",
+ "//lst[@name='collation'][10]/lst[@name='misspellingsAndCorrections']/str[@name='paintable']='pintable'",
+ "//lst[@name='collation'][10]/lst[@name='misspellingsAndCorrections']/str[@name='pine']='pi ne'",
+ "//lst[@name='collation'][10]/lst[@name='misspellingsAndCorrections']/str[@name='apple']='ample'",
+ "//lst[@name='collation'][10]/lst[@name='misspellingsAndCorrections']/str[@name='godness']='goodness'"
+ );
+ assertQ(req(
+ "q", "lowerfilt:(pine AND apple)",
+ "qt", "spellCheckWithWordbreak",
+ "indent", "true",
+ SpellCheckComponent.COMPONENT_NAME, "true",
+ SpellCheckComponent.SPELLCHECK_ACCURACY, ".75",
+ SpellCheckComponent.SPELLCHECK_EXTENDED_RESULTS, "true",
+ SpellCheckComponent.SPELLCHECK_COLLATE, "true",
+ SpellCheckComponent.SPELLCHECK_COLLATE_EXTENDED_RESULTS, "true",
+ SpellCheckComponent.SPELLCHECK_MAX_COLLATIONS, "10"),
+ "//lst[@name='collation'][1 ]/str[@name='collationQuery']='lowerfilt:(line AND ample)'",
+ "//lst[@name='collation'][2 ]/str[@name='collationQuery']='lowerfilt:(pineapple)'",
+ "//lst[@name='collation'][3 ]/str[@name='collationQuery']='lowerfilt:((pi AND ne) AND ample)'"
+ );
+ assertQ(req(
+ "q", "lowerfilt:pine AND NOT lowerfilt:apple",
+ "qt", "spellCheckWithWordbreak",
+ "indent", "true",
+ SpellCheckComponent.COMPONENT_NAME, "true",
+ SpellCheckComponent.SPELLCHECK_ACCURACY, ".75",
+ SpellCheckComponent.SPELLCHECK_EXTENDED_RESULTS, "true",
+ SpellCheckComponent.SPELLCHECK_COLLATE, "true",
+ SpellCheckComponent.SPELLCHECK_COLLATE_EXTENDED_RESULTS, "true",
+ SpellCheckComponent.SPELLCHECK_MAX_COLLATIONS, "10"),
+ "//lst[@name='collation'][1 ]/str[@name='collationQuery']='lowerfilt:line AND NOT lowerfilt:ample'",
+ "//lst[@name='collation'][2 ]/str[@name='collationQuery']='lowerfilt:(pi AND ne) AND NOT lowerfilt:ample'"
+ );
+ assertQ(req(
+ "q", "lowerfilt:pine NOT lowerfilt:apple",
+ "qt", "spellCheckWithWordbreak",
+ "indent", "true",
+ SpellCheckComponent.COMPONENT_NAME, "true",
+ SpellCheckComponent.SPELLCHECK_ACCURACY, ".75",
+ SpellCheckComponent.SPELLCHECK_EXTENDED_RESULTS, "true",
+ SpellCheckComponent.SPELLCHECK_COLLATE, "true",
+ SpellCheckComponent.SPELLCHECK_COLLATE_EXTENDED_RESULTS, "true",
+ SpellCheckComponent.SPELLCHECK_MAX_COLLATIONS, "10"),
+ "//lst[@name='collation'][1 ]/str[@name='collationQuery']='lowerfilt:line NOT lowerfilt:ample'",
+ "//lst[@name='collation'][2 ]/str[@name='collationQuery']='lowerfilt:(pi AND ne) NOT lowerfilt:ample'"
+ );
+ assertQ(req(
+ "q", "lowerfilt:(+pine -apple)",
+ "qt", "spellCheckWithWordbreak",
+ "indent", "true",
+ SpellCheckComponent.COMPONENT_NAME, "true",
+ SpellCheckComponent.SPELLCHECK_ACCURACY, ".75",
+ SpellCheckComponent.SPELLCHECK_EXTENDED_RESULTS, "true",
+ SpellCheckComponent.SPELLCHECK_COLLATE, "true",
+ SpellCheckComponent.SPELLCHECK_COLLATE_EXTENDED_RESULTS, "true",
+ SpellCheckComponent.SPELLCHECK_MAX_COLLATIONS, "10"),
+ "//lst[@name='collation'][1 ]/str[@name='collationQuery']='lowerfilt:(+line -ample)'",
+ "//lst[@name='collation'][2 ]/str[@name='collationQuery']='lowerfilt:((+pi +ne) -ample)'"
+ );
+ assertQ(req(
+ "q", "lowerfilt:(+printableinpuntableplantable)",
+ "qt", "spellCheckWithWordbreak",
+ "indent", "true",
+ SpellCheckComponent.COMPONENT_NAME, "true",
+ SpellCheckComponent.SPELLCHECK_ACCURACY, "1",
+ SpellCheckComponent.SPELLCHECK_EXTENDED_RESULTS, "true",
+ SpellCheckComponent.SPELLCHECK_COLLATE, "true",
+ SpellCheckComponent.SPELLCHECK_COLLATE_EXTENDED_RESULTS, "true",
+ SpellCheckComponent.SPELLCHECK_MAX_COLLATIONS, "1"),
+ "//lst[@name='collation'][1 ]/str[@name='collationQuery']='lowerfilt:((+printable +in +puntable +plantable))'"
+ );
+ }
+}
Modified: lucene/dev/trunk/solr/example/solr/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/example/solr/conf/solrconfig.xml?rev=1346058&r1=1346057&r2=1346058&view=diff
==============================================================================
--- lucene/dev/trunk/solr/example/solr/conf/solrconfig.xml (original)
+++ lucene/dev/trunk/solr/example/solr/conf/solrconfig.xml Mon Jun 4 17:55:25 2012
@@ -881,10 +881,14 @@
<!-- Spell checking defaults -->
<str name="spellcheck">on</str>
+ <str name="spellcheck.extendedResults">false</str>
+ <str name="spellcheck.count">5</str>
+ <str name="spellcheck.alternativeTermCount">2</str>
+ <str name="spellcheck.maxResultsForSuggest">5</str>
<str name="spellcheck.collate">true</str>
- <str name="spellcheck.onlyMorePopular">false</str>
- <str name="spellcheck.extendedResults">false</str>
- <str name="spellcheck.count">3</str>
+ <str name="spellcheck.collateExtendedResults">true</str>
+ <str name="spellcheck.maxCollationTries">5</str>
+ <str name="spellcheck.maxCollations">3</str>
</lst>
<!-- append spellchecking to our list of components -->
@@ -1171,6 +1175,16 @@
<float name="thresholdTokenFrequency">.01</float>
-->
</lst>
+
+ <!-- a spellchecker that can break or combine words. See "/spell" handler below for usage -->
+ <lst name="spellchecker">
+ <str name="name">wordbreak</str>
+ <str name="classname">solr.WordBreakSolrSpellChecker</str>
+ <str name="field">name</str>
+ <str name="combineWords">true</str>
+ <str name="breakWords">true</str>
+ <int name="maxChanges">10</int>
+ </lst>
<!-- a spellchecker that uses a different distance measure -->
<!--
@@ -1226,9 +1240,21 @@
-->
<requestHandler name="/spell" class="solr.SearchHandler" startup="lazy">
<lst name="defaults">
- <str name="spellcheck.onlyMorePopular">false</str>
- <str name="spellcheck.extendedResults">false</str>
- <str name="spellcheck.count">1</str>
+ <!-- Solr will use suggestions from both the 'default' spellchecker
+ and from the 'wordbreak' spellchecker and combine them.
+ collations (re-written queries) can include a combination of
+ corrections from both spellcheckers -->
+ <str name="spellcheck.dictionary">default</str>
+ <str name="spellcheck.dictionary">wordbreak</str>
+ <str name="spellcheck">on</str>
+ <str name="spellcheck.extendedResults">true</str>
+ <str name="spellcheck.count">10</str>
+ <str name="spellcheck.alternativeTermCount">5</str>
+ <str name="spellcheck.maxResultsForSuggest">5</str>
+ <str name="spellcheck.collate">true</str>
+ <str name="spellcheck.collateExtendedResults">true</str>
+ <str name="spellcheck.maxCollationTries">10</str>
+ <str name="spellcheck.maxCollations">5</str>
</lst>
<arr name="last-components">
<str>spellcheck</str>