solr作为一种开源的搜索服务器

拼写检查功能,能在搜索时,提供一个较好用户体验,所以,主流的搜索引擎都有这个功能。在这之前,笔者先简单的说一下什么是拼写检查,其实很好理解,就是你输入的搜索词,可能是你输错了,也有可能在它的检索库里面根本不存在这个词,但是这时候它能给你返回,相似或相近的结果来帮助你校正。

举个例子,假如你在百度里面输入在在线电瓶,可能它的索引库里面就没有,但是它有可能返回在线电影,在线电视,在线观看等等一些词,这些,就用到拼写检查的功能了。

solr作为一种开源的搜索服务器,对拼写检查,也提供了良好的支持,那么下面笔者就来讲下关于solr4.3的拼写检查的配置,在这之前先说明一点,作为拼写检查用,为了提高校正的准确率,一般对校正的词,不要进行分词,所以用string就好了,拼写检查的配置主要是在solrconfig.xml里面配置.



1,拼写组件SpellCheckComponent配置
2,在SearchHandler   /select里面配置
3,在SearchHandler   /spell里面配置

按照上面3来,就可以快速配置好拼写检查功能了,其实笔者上面写的4步,其实只配置2,3步就可以了,另外的第4步用默认值就可以了,在这里把它写出来,只是让大家有个认识


拼写组件SpellCheckComponent它其实是核心的东西,在他的里面可以配置1至多个拼写检查器,启动的时候所有的检查器都会加载,这次笔者主要介绍的有2个拼写检查器,一个是默认的只对主索引做拼写校正,另外一个是自定义加载spellings.txt拼写检查库,带拼写校正索引库的检查器,其他的检查器各位道友想要使用的话就自己去看wiki了。

Java代码 复制代码  收藏代码
  1. <searchComponent name="spellcheck" class="solr.SpellCheckComponent">  
  2.        
  3. <!-- 查询分析器,如果不指定的话,默认会使用field字段类型的分词器 -->  
  4.    <str name="queryAnalyzerFieldType">string</str>  
  5.    <!-- 默认的校正器,只对主索引库管用 -->  
  6. <lst name="spellchecker">  
  7.      <str name="name">default</str>  
  8.      <str name="field">my_word</str>  
  9.      <str name="classname">solr.DirectSolrSpellChecker</str>   
  10.      <str name="distanceMeasure">internal</str>  
  11.      <float name="accuracy">0.7</float>  
  12.      <int name="maxEdits">1</int>  
  13.      <int name="minPrefix">1</int>  
  14.      <int name="maxInspections">5</int>  
  15.      <int name="minQueryLength">4</int>  
  16.      <float name="maxQueryFrequency">0.01</float>  
  17.    </lst>  
  18.    
  19.  <!--  读取拼写检查库的索引进行校正可以,使用默认配置,取消注释即可 -->  
  20. <lst name="spellchecker">  
  21.         <str name="classname">solr.FileBasedSpellChecker</str>  
  22.         <str name="name">file</str>  
  23.         <str name="sourceLocation">spellings.txt</str>  
  24.         <str name="characterEncoding">UTF-8</str>  
  25.         <str name="spellcheckIndexDir">spellcheckerFile</str>  
  26.       </lst>  
  27.  </searchComponent>  
 <searchComponent name="spellcheck" class="solr.SpellCheckComponent">
      
	<!-- 查询分析器,如果不指定的话,默认会使用field字段类型的分词器 -->
    <str name="queryAnalyzerFieldType">string</str>
    <!-- 默认的校正器,只对主索引库管用 -->
	<lst name="spellchecker">
      <str name="name">default</str>
      <str name="field">my_word</str>
      <str name="classname">solr.DirectSolrSpellChecker</str> 
      <str name="distanceMeasure">internal</str>
      <float name="accuracy">0.7</float>
      <int name="maxEdits">1</int>
      <int name="minPrefix">1</int>
      <int name="maxInspections">5</int>
      <int name="minQueryLength">4</int>
      <float name="maxQueryFrequency">0.01</float>
    </lst>
	 
	 <!--  读取拼写检查库的索引进行校正可以,使用默认配置,取消注释即可 -->
	<lst name="spellchecker">
         <str name="classname">solr.FileBasedSpellChecker</str>
         <str name="name">file</str>
         <str name="sourceLocation">spellings.txt</str>
         <str name="characterEncoding">UTF-8</str>
         <str name="spellcheckIndexDir">spellcheckerFile</str>
       </lst>
  </searchComponent>


对于上面的代码,虽然可以加载多个校正器,但是在拼写检查时,只能指定特定的一个进行校正,那么为什么要配置多个校正检查器呢? 笔者个人感觉这个主要是方便在程序运行可以动态切换校正器。

在spellings.txt里面自定义的拼写检查词,注意编码的格式一定是要UTF-8无BOM的格式,这里面的词,会在solr服务启动时,自动创建spellcheckerFile文件夹并把内容加载到

Java代码 复制代码  收藏代码
  1. F:\eclipse10tomcat\webapps\solr\solr_home\collections\collection1\data\spellcheckerFile  
F:\eclipse10tomcat\webapps\solr\solr_home\collections\collection1\data\spellcheckerFile

索引起来。

SearchHandler   /select这个检索请求里面的配置很重要,拼写检查是否启用就是在这里面配置,

Java代码 复制代码  收藏代码
  1. <requestHandler name="/select" class="solr.SearchHandler">  
  2.    <!-- default values for query parameters can be specified, these  
  3.         will be overridden by parameters in the request  
  4.      -->  
  5.     <lst name="defaults">  
  6.       <str name="echoParams">explicit</str>  
  7.       <int name="rows">10</int>  
  8.       <str name="df">text</str>  
  9.     </lst>  
  10.  <!-- 这行代码非常重要,如果没有这行,拼写检查,是不起作用的-->  
  11.   <arr name="last-components">  
  12.         <str>spellcheck</str>  
  13.       </arr>  
  14.    </requestHandler>  
 <requestHandler name="/select" class="solr.SearchHandler">
    <!-- default values for query parameters can be specified, these
         will be overridden by parameters in the request
      -->
     <lst name="defaults">
       <str name="echoParams">explicit</str>
       <int name="rows">10</int>
       <str name="df">text</str>
     </lst>
	 <!-- 这行代码非常重要,如果没有这行,拼写检查,是不起作用的-->
	  <arr name="last-components">
         <str>spellcheck</str>
       </arr>
    </requestHandler>




SearchHandler   /spell组件使用默认配置即可

Java代码 复制代码  收藏代码
  1. <requestHandler name="/spell" class="solr.SearchHandler" startup="lazy">  
  2.     <lst name="defaults">  
  3.       <str name="df">text</str>  
  4.       <str name="spellcheck.dictionary">direct</str>  
  5.       <str name="spellcheck">on</str>  
  6.       <str name="spellcheck.extendedResults">true</str>              
  7.       <str name="spellcheck.collate">true</str>  
  8.       <str name="spellcheck.collateExtendedResults">true</str>         
  9.     </lst>  
  10.     <arr name="last-components">  
  11.       <str>spellcheck</str>  
  12.     </arr>  
  13.   </requestHandler>  
<requestHandler name="/spell" class="solr.SearchHandler" startup="lazy">
    <lst name="defaults">
      <str name="df">text</str>
      <str name="spellcheck.dictionary">direct</str>
      <str name="spellcheck">on</str>
      <str name="spellcheck.extendedResults">true</str>            
      <str name="spellcheck.collate">true</str>
      <str name="spellcheck.collateExtendedResults">true</str>       
    </lst>
    <arr name="last-components">
      <str>spellcheck</str>
    </arr>
  </requestHandler>



至此,拼写检查功能已经配置完毕,可以用solr的UI页面进行主索引测试,也可以用spellCheckFile里面的副索引,测试,但是,一次只能使用一种校正方法
下面给出solrj代码

Java代码 复制代码  收藏代码
  1.     public  List<String>   spellcheck(String word){  
  2.         List<String>  wordList=new ArrayList<String>();  
  3.         SolrQuery query = new SolrQuery();  
  4.         //query.set("q","name:ac");  
  5.         //query.set("qt", "/spell");  
  6.      //默认是主索引  
  7.         query.set("q""my_word:"+word+"");    
  8.         query.set("qt""/select");  
  9.         //query.set("spellcheck.build", "true");//遇到新的检查词,会自动添加到索引里面  
  10.         //query.set("spellcheck.dictionary", "file");//使用副索引,checkSpellFile里面的进行使用  
  11.         query.set("spellcheck""true");  
  12.         query.set("spellcheck.count", Integer.MAX_VALUE);  
  13.           //  params.set("spellcheck.build", "true");  
  14.            
  15.         try {  
  16.         QueryResponse   rsp = server.query(query);  
  17.         System.out.println("直接命中:"+rsp.getResults().size());               
  18.         SolrDocumentList ss=rsp.getResults();  
  19.         for(SolrDocument doc:ss){  
  20.             System.out.println(doc.get("my_word"));  
  21.         }  
  22.         //…上面取结果的代码  
  23.         SpellCheckResponse re=rsp.getSpellCheckResponse();  
  24.           
  25.         if (re != null) {  
  26.             for(Suggestion s:re.getSuggestions()){  
  27.              List<String> list=s.getAlternatives();  
  28.              for(String spellWord:list){  
  29.                  System.out.println(spellWord);  
  30.                 // wordList.add(spellWord);  
  31.              }  
  32.             }  
  33. //        for(Collation s: spellCheckResponse.getCollatedResults()){  
  34. //            System.out.println(s.toString());  
  35. //        }  
  36.         }  
  37.   
  38.           return wordList;  
  39.         } catch (SolrServerException e) {  
  40.             // TODO Auto-generated catch block  
  41.             e.printStackTrace();  
  42.         }  
  43.           
  44.         return null;  
  45.     }  
	public  List<String>   spellcheck(String word){
		List<String>  wordList=new ArrayList<String>();
		SolrQuery query = new SolrQuery();
		//query.set("q","name:ac");
		//query.set("qt", "/spell");
	 //默认是主索引
		query.set("q", "my_word:"+word+"");  
		query.set("qt", "/select");
		//query.set("spellcheck.build", "true");//遇到新的检查词,会自动添加到索引里面
		//query.set("spellcheck.dictionary", "file");//使用副索引,checkSpellFile里面的进行使用
		query.set("spellcheck", "true");
		query.set("spellcheck.count", Integer.MAX_VALUE);
		  //  params.set("spellcheck.build", "true");
		 
		try {
		QueryResponse	rsp = server.query(query);
	    System.out.println("直接命中:"+rsp.getResults().size());             
		SolrDocumentList ss=rsp.getResults();
		for(SolrDocument doc:ss){
			System.out.println(doc.get("my_word"));
		}
		//…上面取结果的代码
	    SpellCheckResponse re=rsp.getSpellCheckResponse();
		
		if (re != null) {
		    for(Suggestion s:re.getSuggestions()){
		     List<String> list=s.getAlternatives();
		     for(String spellWord:list){
		    	 System.out.println(spellWord);
		    	// wordList.add(spellWord);
		     }
		    }
//		  for(Collation s: spellCheckResponse.getCollatedResults()){
//			  System.out.println(s.toString());
//		  }
		}

		  return wordList;
		} catch (SolrServerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}





最后,笔者关于拼写检查还有一个问题没有搞清楚,就是使用spellings.txt里面的自定义词,检索时只能检索出长度大于2的词,希望各位看到此篇文章的读者也测试一下,找一下解决方法

猜你喜欢

转载自weitao1026.iteye.com/blog/2266938
今日推荐