Solr之分词

1.  分词的基本概念

    分词就是将用户输入的一串文本分割成一个个token,一个个token组成了tokenStream,然后遍历tokenStream对其进行过滤操作,比如:去除停用词,特殊字符,标点符号和统一转换成小写形式。 

2.  Analyzer

    Analyzer包含两个核心组件:Tokenizer和TokenFilter,前者用于生成Token流,后者用于对tokenizer进行过滤。

    1.  常规用法 

<fieldType name="text_ca" class="solr.TextField" positionIncrementGap="100">
    <analyzer>
      <tokenizer class="solr.StandardTokenizerFactory"/>
      <filter class="solr.ElisionFilterFactory" articles="lang/contractions_ca.txt" ignoreCase="true"/>
      <filter class="solr.LowerCaseFilterFactory"/>
      <filter class="solr.StopFilterFactory" words="lang/stopwords_ca.txt" ignoreCase="true"/>
      <filter class="solr.SnowballPorterFilterFactory" language="Catalan"/>
    </analyzer>
</fieldType>

    2.  一个相同的分词器在两种阶段下被应用

  <fieldType name="ancestor_path" class="solr.TextField">
    <analyzer type="index">
      <tokenizer class="solr.KeywordTokenizerFactory"/>
    </analyzer>
    <analyzer type="query">
      <tokenizer class="solr.PathHierarchyTokenizerFactory" delimiter="/"/>
    </analyzer>
  </fieldType>

3.  Tokenizer    

    Analyzer必须要有一个Tokenizer,而TokenFilter可以没有。  

    Tokenizer不能直接被使用,需要通过TokenizerFactory工厂类来创建对应的Tokenizer         

    1.  solr自带的Tokenizer

        1.  KeywordTokenizer

            将整个文本当作一个Token.它的工厂类是KeywordTokenizerFactory            

<analyzer type="query">
      <tokenizer class="solr.KeywordTokenizerFactory"/>
</analyzer>

        2.  LetterTokenizer

            提取出文本的所有连续的字母序列,并去除非字母字符    

<analyzer type="query">
      <tokenizer class="solr.LetterTokenizerFactory"/>
</analyzer>

        3.  LowerCaseTokenizer

            继承LetterTokenizer的特性,还会将每个Token转换成小写形式。

<analyzer type="query">
      <tokenizer class="solr.LowerCaseTokenizer"/>
</analyzer>

        4.  NGramTokenizer

            根据给定的GramRange对域的文本生成n-gram token.它的工厂类是NGramTokenizerFactory

            NGramTokenizerFactory有两个可选参数

            1.  minGramSize  必须大于0,默认值是1

            2.  maxGramSize  必须大于0,默认值是2

            NGramTokenizer不会按照空格进行分词

<analyzer type="query">
      <tokenizer class="solr.NGramTokenizerFactory" minGramSize="2" maxGramSize="6"/>
</analyzer>
输入文本:  "hey man"
输出结果:  h, e, y, m ,a, n ,he ,ey ,y ,m ,ma , an

        5.  EdgeNGramTokenizer    

            每次都是从最左边或最右边开始n-gram

<analyzer type="query">
      <tokenizer class="solr.EdgeNGramTokenizerFactory" minGramSize="2" maxGramSize="6"/>
</analyzer>

        6.  WhitespaceTokenizer

            使用空白字符作为Token的定界分隔符来提取Token                  

<analyzer type="query">
      <tokenizer class="solr.WhitespaceTokenizerFactory" rule="java"/>
</analyzer>
输入:  I miss you,I do
结果:  I, miss ,you ,I ,do

        7.  StandardTokenizer

            它会按照逗号或者连接符-进行断词,会剔除标点符号,#$%&等特殊字符,不会转换大小写

            maxTokenLength  默认值255

<analyzer type="index">
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
        <filter class="solr.LowerCaseFilterFactory"/>
        <filter class="solr.ReversedWildcardFilterFactory" withOriginal="true"
           maxPosAsterisk="3" maxPosQuestion="2" maxFractionAsterisk="0.33"/>
</analyzer>

4.  TokenFilter

    TokenFilter是Tokenizer的过滤器,它用于对Tokenizer处理后的token进行二次过滤

    在solr中,TokenFilter都是在schema.xml配置文件中先声明的

    在<analyzer>元素下配置一个<filter>元素,<filter>元素的class属性配置成TokenFilter的工厂类        

    1.  StopFilter

        StopFilter会过滤掉在停用词字典里出现的Token,停用词字典文件默认名称为stopwords.txt,需要放置在core/conf目录下。工厂类是StopFilterFactory,有以下可选参数

        words  配置停用词字典文件的加载路径,文件里的空白行和#开头将会被忽略

        ignoreCase  是否忽略大小写,默认为false

        <filter class="solr.StopFilterFactory" format="snowball" words="lang/stopwords_de.txt" ignoreCase="true"/>

    2.  LowerCaseFilter

        用于将每个Token转换成小写形式

        <filter class="solr.LowerCaseFilterFactory"/>                                                

    3.  LengthFilter

        过滤掉不符合规定字符长度限制的Token,工厂类是LengthFilterFactory

        min  token字符的最小长度

        max  token字符的最大长度               

    4.  TrimFilter

        剔除Token前面和后面的空格字符,不会剔除Token中间包含的空格字符。工厂类是TrimFilterFactory

        <filter class="solr.TrimFilterFactory"/>

    5.  SynonymFilter

        用于Token的同义词映射,需要提前在同义词字典文件里声明

        synonyms  配置同义词字典文件的加载路径

        ignoreCase  忽略大小写,默认false

        expand  表示同一行的单词互为同义词  

        <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="false"/>

    6.  WordDelimiterFilter

        用于处理骆驼命名法的文本,帕斯卡命名法的文本,数字与非数字字符串混排的文本

        <filter class="solr.WordDelimiterFilterFactory" protected="protwords.txt"/>

        

 

    7.  EnglishPossessiveFilter

        剔除英文里的人称代词所有格    

        <filter class="solr.EnglishPossessiveFilterFactory"/>

    8.  PorterStemFilter

        去除单词结尾的ed/s/ing

        <filter class="solr.PorterStemFilterFactory"/>

    9.  EnglishMinimalStemFilter

        将英文单词复制转换为单数

        <filter class="solr.EnglishMinimalStemFilterFactory"/>

5.  中文分词器

    1.  IK分词器

        https://gitee.com/wltea/IK-Analyzer-2012FF

        项目很久未更新,需要用户自己修改一下源码,否则在solr 5.x中不能使用  

    2.  Ansj分词器

    3.  MMSeg4J

        https://code.google.com/p/mmseg4j/  

        MMSeg4J源码包含3个子模块:mmseg4j-core  mmseg4j-analysis  mmseg4j-solr 

        mmseg4j包含三种算法:simple  complex  maxword                                

        1.  mmseg4j支持solr5需要使用两个jar包

            将文件上传至/usr/local/tomcat-solr/webapps/solr/WEB-INF/lib目录下

            mmseg4j-core-1.10.0.jar和mmseg4j-solr-2.3.0.jar

        2.  修改managed-schema文件

<fieldType name="textComplex" class="solr.TextField" positionIncrementGap="100">
       <analyzer>
           <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" dicPath="dic"/>
       </analyzer>
</fieldType>
<fieldType name="textMaxWord" class="solr.TextField" positionIncrementGap="100">
       <analyzer>
           <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="max-word" />
       </analyzer>
</fieldType>
<fieldType name="textSimple" class="solr.TextField" positionIncrementGap="100">
        <analyzer>
            <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="simple" dicPath="n:/custom/path/to/my_dic" />
        </analyzer>

</fieldType>

        3.  修改字段类型

            <field name="userName" type="textSimple" multiValued="false" indexed="true" stored="true"/>

        4.  重启一下tomcat,使配置生效

        5.  配置用户自定义字典

            <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="simple" dicPath="/var/solr/data/zhenpin/conf/dic" />

        6.  在/var/solr/data/zhenpin/conf/dic目录下,创建一个文件名为words.dic,重启tomcat,使配置生效。

   <fieldtype name="textComplex" class="solr.TextField" positionIncrementGap="100">
        <analyzer type="index">
            <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" dicPath="/var/solr/dic" />
            <filter class="solr.StopFilterFactory" ignoreCase="false" words="stopwords.txt"/>
            <filter class="solr.WordDelimiterFilterFactory"  protected="protwords.txt"/>
            <filter class="solr.LowerCaseFilterFactory"/>
            <filter class="solr.NGramFilterFactory" minGramSize="1" maxGramSize="20"/>
            <filter class="solr.StandardFilterFactory"/>
        </analyzer>
        <analyzer type="query">
            <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" dicPath="/var/solr/dic" />
            <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
            <filter class="solr.StopFilterFactory" ignoreCase="false" words="stopwords.txt"/>
            <filter class="solr.WordDelimiterFilterFactory"  protected="protwords.txt"/>
            <filter class="solr.LowerCaseFilterFactory"/>
            <!--  <filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="20"/> -->
            <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
        </analyzer>
    </fieldtype>

  

                                        

                                                                                

posted @ 2022-06-08 15:45  奋斗史  阅读(597)  评论(0)    收藏  举报