全文检索引擎Solr系列—–全文检索基本原理
- - ImportNew场景:小时候我们都使用过新华字典,妈妈叫你翻开第38页,找到“坑爹”所在的位置,此时你会怎么查呢. 毫无疑问,你的眼睛会从38页的第一个字开始从头至尾地扫描,直到找到“坑爹”二字为止. 这种搜索方法叫做  顺序扫描法. 对于少量的数据,使用顺序扫描是够用的. 但是妈妈叫你查出坑爹的“坑”字在哪一页时,你要是从第一页的第一个字逐个的扫描下去,那你真的是被坑了. 
IK Analyzer是一款结合了词典和文法分析算法的中文分词组件,基于字符串匹配,支持用户词典扩展定义,支持细粒度和智能切分,比如:
  张三说的确实在理
 智能分词的结果是:
  张三 |  说的 |  确实 |  在理 
 最细粒度分词结果:
  张三 |  三 |  说的 |  的确 |  的 |  确实 |  实在 |  在理
 整合IK Analyzer比mmseg4j要简单很多, 下载解压缩IKAnalyzer2012FF_u1.jar放到目录:E:\solr-4.8.0\example\solr-webapp\webapp\WEB-INF\lib,修改配置文件schema.xml,添加代码:
      <field name="content" type="text_ik" indexed="true" stored="true"/> 
      <fieldType name="text_ik" class="solr.TextField">
            <analyzer type="index" isMaxWordLength="false" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
            <analyzer type="query" isMaxWordLength="true" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
      </fieldType>
   查询采用IK自己的最大分词法,索引则采用它的细粒度分词法
 此时就算配置完成了,重启服务:java -jar start.jar,来看看IKAnalyzer的分词效果怎么样,打开Solr管理界面,点击左侧的Analysis页面  
  
默认分词器进行最细粒度切分。IKAnalyzer支持通过配置IKAnalyzer.cfg.xml 文件来扩充您的与有词典以及停止词典(过滤词典),只需把IKAnalyzer.cfg.xml文件放入class目录下面,指定自己的词典mydic.dic
    <?xml version="1.0" encoding="UTF-8"?> 
    <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">   
    <properties>   
      <comment>IK Analyzer 扩展配置</comment> 
      <!--用户可以在这里配置自己的扩展字典  -->  
      <entry key="ext_dict">/mydict.dic; 
    /com/mycompany/dic/mydict2.dic;</entry>  
     
       <!--用户可以在这里配置自己的扩展停止词字典--> 
      <entry key="ext_stopwords">/ext_stopword.dic</entry>    
    </properties> 
 事实上前面的FieldType配置其实存在问题,根据目前最新的IK版本 IK Analyzer 2012FF_hf1.zip, 索引时使用最细粒度分词,查询时最大分词(智能分词)实际上是不生效的。
据作者 linliangyi说,在2012FF_hf1这个版本中已经修复,经测试还是没用,详情请看 此贴。
 package org.wltea.analyzer.lucene;
    
    import java.io.Reader;
    import java.util.Map;
    
    import org.apache.lucene.analysis.Tokenizer;
    import org.apache.lucene.analysis.util.TokenizerFactory;
    //lucene:4.8之前的版本
    //import org.apache.lucene.util.AttributeSource.AttributeFactory;
    //lucene:4.9
    import org.apache.lucene.util.AttributeFactory;
    
    public class IKAnalyzerSolrFactory extends TokenizerFactory{
        
        private boolean useSmart;
        
        public boolean useSmart() {
            return useSmart;
        }
        
        public void setUseSmart(boolean useSmart) {
            this.useSmart = useSmart;
        }
        
         public IKAnalyzerSolrFactory(Map<String,String> args) {
             super(args);
             assureMatchVersion();
             this.setUseSmart(args.get("useSmart").toString().equals("true"));
           }
    
    
        @Override
        public Tokenizer create(AttributeFactory factory, Reader input) {
            Tokenizer _IKTokenizer = new IKTokenizer(input , this.useSmart);
            return _IKTokenizer;
        }
    
    }
 重新编译后更新jar文件,更新schema.xml文件:
    <fieldType name="text_ik" class="solr.TextField" >
            <analyzer type="index">
                <tokenizer class="org.wltea.analyzer.lucene.IKAnalyzerSolrFactory" useSmart="false"/>
            </analyzer> 
            <analyzer type="query">
                <tokenizer class="org.wltea.analyzer.lucene.IKAnalyzerSolrFactory" useSmart="true"/>
            </analyzer> 
    </fieldType>