精华内容
下载资源
问答
  • Solr分词

    2018-08-07 15:35:00
    首先我们来看看我当初使用Lucene5是如何实现的, 在Solr5中,我们只需要为IKTokenizer扩展一个IKTokenizerFactory,为PinyinTokenFilter扩展一个PinyinTokenFilterFactory,为PinyinNGramTokenFilter...

    首先我们来看看我当初使用Lucene5是如何实现的,
    http://dl2.iteye.com/upload/attachment/0109/7925/0051fb7f-0b63-3371-9967-7e0e5169e102.png
     
    Solr5中,我们只需要为IKTokenizer扩展一个IKTokenizerFactory,PinyinTokenFilter扩展一个PinyinTokenFilterFactory,PinyinNGramTokenFilter扩展一个PinyinNGramTokenFilterFactory,其中IKTokenizerFactory我已经扩展过了,剩下需要做的就是自定义PinyinTokenFilterFactoryPinyinNGramTokenFilterFactory了。如果你不知道如何扩展,请参看SolrStopFilterFactory类源码,照葫芦画瓢。OK,我来全程截图示范,我是如何扩展的?

         既然是要扩展PinyinTokenFilterFactory,从类名就知道它是PinyinTokenFilter的工厂类,所以我们首先需要把我之前写的PinyinTokenFilterPinyinNGramTokenFiltercopy到一个新的项目中来,如图:
    http://dl2.iteye.com/upload/attachment/0109/7931/abec5110-887e-3e05-bc48-ab875e839144.png
     
    我新建一个solr-analyzer-extra Java Project,把我之前写的几个类copy到如图红色框住的package中,那几个类你在我Lucene5系列博客中都可以找到源码,或者你到我的GitHub上也可以得到相关源码。我的GitHub地址待会儿我会在博客的结尾处贴出来,敬请关注哦!图片中显示还有ikansj两个package,这就是我为了前面几篇博客扩展的TokenizerFactory,你懂的!然后我们需要添加依赖的Jar包,如图:
    http://dl2.iteye.com/upload/attachment/0109/7933/f4a74d1b-2718-3e6d-9c56-13f6dfd229ac.png
     
    之所以分Lucene5Solr5两个包,就是为了方便打包Jar包,这样我就可以把lucene5包下的类单独打包成一个jarsolr5下打包成一个jar,当你仅仅只是在Lucene5下需要使用拼音分词,那solr5包下的类是用不到的,打包成两个jar是为了按需加载类,你懂的!特此说明。

         OK,开始在Solr5包下扩展PinyinTokenFilterFactory,我扩展的源码如图:

    http://dl2.iteye.com/upload/attachment/0109/7960/c41df5ae-10b9-35bc-8ed1-2d6f83521423.png
     扩展的PinyinNGramTokenFilterFactory源码如图:
    http://dl2.iteye.com/upload/attachment/0109/7950/4f64a1b8-42be-3212-bd4e-7fe803882cd8.png
     
    对应的PinyinNGramTokenFilter类我稍作了修改,主要是添加了nGramNumber参数,用于控制是否对纯数字进行nGram处理,有时候可能并不希望对类似 2011 这样的数字进行nGram,当然如果你需要对纯数字字符串进行nGram处理,请把nGramNumber参数设置为true即可,默认该值为falsePinyinNGramTokenFilter类我修改的地方如下:
    http://dl2.iteye.com/upload/attachment/0109/7952/89946743-0b45-3515-bbba-6dca06ebf378.png
     
    http://dl2.iteye.com/upload/attachment/0109/7954/c5285d29-c634-31f4-bd6a-209b9fb4d678.png
     
    http://dl2.iteye.com/upload/attachment/0109/7956/665940ad-a8de-3681-98b9-7002571ad668.png
     
    http://dl2.iteye.com/upload/attachment/0109/7958/9583c8fc-03ae-3ffb-abdd-b78a831f2daa.png

    其中定义了一个常量类Constant,就是不想把默认值常量写死在各个类里,所以统一放到了一个常量类里,如图:
    http://dl2.iteye.com/upload/attachment/0109/7962/60aa70f5-5817-360a-b45c-60cc24cad364.png

    上面涉及到的所有源码我待会儿都会在底下附件里上传分享给你们。OK,到此该扩展的类都编写完毕了,我们需要将他们打包成jar,如图:
    http://dl2.iteye.com/upload/attachment/0109/7964/e2b81999-581e-36a3-a752-2626dc010df3.png
     
    http://dl2.iteye.com/upload/attachment/0109/7966/6fcdf04e-1aa7-3480-b7f0-7dbea1e075b8.png
     
    http://dl2.iteye.com/upload/attachment/0109/7968/313dc1f3-38e1-35f0-af17-b8b270fd0a7d.png

    http://dl2.iteye.com/upload/attachment/0109/7970/af065013-e50e-3960-8cb2-9aac56a7e5e3.png
     
    http://dl2.iteye.com/upload/attachment/0109/7972/3fa5ad4a-785f-3202-87e4-b0c2df53d1fc.png
     
    http://dl2.iteye.com/upload/attachment/0109/7974/17c276bc-8bf9-31ec-8710-44dcb99ac8bb.png
     
    http://dl2.iteye.com/upload/attachment/0109/7976/f8a4bf42-0bb6-35fe-b595-b93697f56c49.png
     
    http://dl2.iteye.com/upload/attachment/0109/7978/f1fa026d-8da4-3b11-9fed-15a19793042a.png
     
    然后你就会在你的桌面上看到这个jar包,
    http://dl2.iteye.com/upload/attachment/0109/7980/08938f80-cecf-37b6-8de5-e940d2e61178.png
     OK,
    同理,对solr5包下的类进行打包,提供给使用Solr5的用户使用,如图:
    http://dl2.iteye.com/upload/attachment/0109/7982/6aff06d7-d4de-3108-aa37-effac44afb00.png
     
    http://dl2.iteye.com/upload/attachment/0109/7984/9f4bb301-9734-3496-80e4-1547f1f43296.png
     
    http://dl2.iteye.com/upload/attachment/0109/7986/1a5cef32-c435-3b65-a2d5-ba6b80226681.png
     
    http://dl2.iteye.com/upload/attachment/0109/7988/289edc1a-235f-34c5-a23d-bad55e2273cc.png
     
    然后两个jar包就都打好了,如图:
    http://dl2.iteye.com/upload/attachment/0109/7990/4262bb3b-a12f-34f1-9da4-a626f8c54f2a.png
     
    接下来,我们就需要把我们打好的jar包导入到我们的corelib目录下,如图:
    http://dl2.iteye.com/upload/attachment/0109/7992/bb946fa9-f785-3c55-94f0-aa3610392389.png
     
    由于我们的汉字转拼音使用到了pinyin4j类库,所以我们还需要把pinyin4jjar包也复制到当前corelib目录下,如图:
    http://dl2.iteye.com/upload/attachment/0109/7994/44e65e48-85e5-34e8-b5fc-679464eacd74.png
     
    由于我们是先进行中文分词,然后再对分出来的中文词语进行拼音转换,而这里我以IK分词器为例,所以我们还需要把IKjar包也copy进去,如图:
    http://dl2.iteye.com/upload/attachment/0109/7998/afd24bdf-940c-3eb9-9eb2-42a6f2536c53.png
    OK,jar
    包导入完毕后,我们需要在我们的schema.xml中定义域类型,配置示例如图:
    http://dl2.iteye.com/upload/attachment/0109/8000/829db201-8772-3c92-b111-c5ddb80fd93d.png
     
    http://dl2.iteye.com/upload/attachment/0109/8002/9e669c22-5ff7-3485-9d25-856d452791fb.png
     
    这是默认最基本的配置,当然PinyinTokenFilterFactoryPinyinNGramTokenFilterFactory这两个工厂类是有可选的配置参数可以设置的,请看图:
    http://dl2.iteye.com/upload/attachment/0109/8004/78bcd96f-0773-3d8e-8f4d-1229e6c21373.png
     
    http://dl2.iteye.com/upload/attachment/0109/8006/90e6dc94-90e4-3526-97eb-4b0dfae9b370.png
     
    因此,你也可以这样配置:
    http://dl2.iteye.com/upload/attachment/0109/8008/b9fb0caf-6333-3d4e-a9eb-ca16af93d842.png
     
    域类型定义好后,你需要在你的某个域上应用这个新定义的text_pinyin域类型,如图:
    http://dl2.iteye.com/upload/attachment/0109/8010/bf7005a0-5e7c-333a-8d92-ddb60a96ae1e.png
     OK,
    启动你的tomcat,开始进行拼音分词测试,如图:
    http://dl2.iteye.com/upload/attachment/0109/8012/e5170602-e888-3ed5-8565-626f6e108d7e.png
     
    http://dl2.iteye.com/upload/attachment/0109/8014/14526a25-f058-38ae-9651-0cfe0bc4e343.png
     OK
    ,到此关于Solr5中关于拼音分词以及拼音搜索就讲解到这儿了

    要想在Sor中使用MMSeg4J分词器,首先你需要自定义一个TokenizerFactory实现类,虽然直接配置Analyzer类也可以,但那样无法配置Analyzer构造函数的参数,不够灵活,存在弊端,所以我一直都是以扩展TokenizerFactory的方式来讲解类似MMSeg4J这样的中文分词器在Solr中的使用。

          MMSegTokenizerFactory类我花了3个多小时修改了源码并经过N多测试,表示已经可以使用,我主要的是针对Lucene5 APIMMSegTokenizer类做了升级更新并添加了自定义停用词功能,默认MMSeg4J没有实现自定义停用词功能。相关jar包请到底下的附件里去下载。下面介绍MMSeg4Jsolr5中的使用步骤:

         1. copy依赖的jar包到当前core\lib目录下,如图:

    http://dl2.iteye.com/upload/attachment/0109/6634/2d0c99fb-0757-3102-ada4-a997ec4db5e6.png
         2.在你的schema.xml中配置fieldType应用上我扩展的MMSegTokenizerFactory类,具体配置看图:
    http://dl2.iteye.com/upload/attachment/0109/6636/86973c2b-40b8-3d65-b6dc-b4012fe9e3a3.png
     

    Xml代码  0f41823e677b8008d338d2278b05f312895.jpg

    1. <fieldType name="text_mm" class="solr.TextField">  
    2.         <analyzer type="index">  
    3.             <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="simple"   
    4.                 stopwordsPath="mmseg-stopwords/stopwords.dic"/>  
    5.         </analyzer>  
    6.         <analyzer type="query">  
    7.             <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex"/>  
    8.         </analyzer>  
    9. </fieldType>  

        其中mode参数表示MMSeg4J的分词模式,自带有3种可选值:simple,complex,maxword, mode参数不配置默认为maxword模式stopwordsPath是用来配置自定义停用词加载路径的,默认是相对于classPath的,自定义停用词字典文件放置路径请看图:
    http://dl2.iteye.com/upload/attachment/0109/6638/946fdefe-e2e2-3ccc-ad86-ccf3bbb738d5.png
     
    自定义停用词词典文件加载路径配置参数是可选的,不过由于MMSeg4J没有内置停用词功能,所以像空格字符,标点符号等等都会被分出来,所以一般建议添加停用词词典文件。不过要注意的是,自定义的停用词词典文件的编码必须是UTF-8BOM格式,而且在你使用文本编辑软件打开进行编辑的时候,请务必将你的编辑软件的编码设置为UTF-8,否则可能会出现本来是UTF-8BOM编码,你打开编辑保存后编码就改变了。当你发现明明停用词在词典文件里,却很奇怪不起作用时,那十有八九是因为词典文件编码已经被破坏,建议词典文件不要自己新建,可以保留一个dic模版文件,每次直接copy过来修改文件名然后再打开编辑。

     

         3.然后你需要在你的某个field域上应用刚才定义的FieldType(域类型),如图:
    http://dl2.iteye.com/upload/attachment/0109/6640/35bc9c40-4dff-32c7-b024-e4709656ea39.png
            OK
    ,现在你可以启动你的Tomcat进行分词测试了,如图:
    http://dl2.iteye.com/upload/attachment/0109/6644/49626cf8-7c06-35e0-9597-81a8ad1f0abc.png
     mmseg-stopwrods
    目录下的stopwords.dic停用词词典文件我添加了如下停用词:
    http://dl2.iteye.com/upload/attachment/0109/6646/bc270f40-81c9-33f5-8e85-8ccf11dea1af.png
     
    3个是一个空格字符,第4个是中文状态下的逗号字符,第5个是中文状态下的句号字符。你想要剔除哪些字符,具体留给你们自己去完善。

         如果我想配置自定义新词呢,比如么么哒,萌萌哒之类的,默认肯定是分不出来的,该如何配置呢?MMSeg4J默认是内置了自定义词典扩展功能的,且默认加载思路如下:

           从默认目录加载词库文件, 查找默认目录顺序:

           1.首先从系统属性mmseg.dic.path指定的目录中加载

           2.若从系统属性mmseg.dic.path指定的目录中加载不到,再从classpath/data目录加载

           3.若从classpath/data目录加载不到,再从user.dir/data目录加载

     

    需要注意的是,MMSeg4J对于字典dic文件的命名有要求,只有以words开头 .dic结尾的文件才会被加载

    知道上述加载原理,那我们只需要把自定义扩展词典文件如图放置即可:
    http://dl2.iteye.com/upload/attachment/0109/6648/afe37842-1f11-3b22-a18b-2785a88f7a21.png
     
    http://dl2.iteye.com/upload/attachment/0109/6650/c2793f60-9eff-3834-a63e-9ac37db6d226.png
     
    http://dl2.iteye.com/upload/attachment/0109/6652/70d730d6-ddf9-3ea8-be69-3f4973cf47a0.png
           
    到此,MMSeg4J分词器在Solr5中的使用就讲解完毕了

    Solr中该如何使用IK分词器呢,这是小伙伴们问的频率比较高的一个问题,今晚特此更新此篇博客。其实之前我在其他博客里已经使用了IK分词器,只是我没做详细说明。

           schema.xml配置中其实有很多关于分词器的配置示例,我从中摘录一段配置示例,比如:

    Xml代码  d0d25ab1441b05a7795f2d9c0b9f9e2ec54.jpg

    1. <fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">  
    2.       <analyzer type="index">  
    3.         <tokenizer class="solr.StandardTokenizerFactory"/>  
    4.         <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />  
    5.         <!-- in this example, we will only use synonyms at query time  
    6.         <filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/>  
    7.         -->  
    8.         <filter class="solr.LowerCaseFilterFactory"/>  
    9.       </analyzer>  
    10.       <analyzer type="query">  
    11.         <tokenizer class="solr.StandardTokenizerFactory"/>  
    12.         <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />  
    13.         <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>  
    14.         <filter class="solr.LowerCaseFilterFactory"/>  
    15.       </analyzer>  
    16.     </fieldType>  

        fileType是用来定义域类型的,name即表示域名称,class即表示域类型对应的class类,如果是solr内置的域类型则可以直接使用solr.前缀+域类型的类名即可,如果是你自定义的域类型,则class表示自定义域类型的完整类名(包含完整的包路径),在fileType元素下有analyzer元素,用来配置当前域类型使用什么分词器,你肯定很奇怪,为什么要配置两个analyzer,其实主要是为了区分两个阶段:索引建立阶段和Query查询阶段,索引建立阶段需要分词毋庸置疑,查询阶段是否需要分词,则取决于你的业务需求,用过Google的知道,用户在查询输入框里输入查询关键字,这时候我们需要对用户输入的查询关键字进行分词器,这时候我们就需要配置查询阶段使用什么分词器,为什么把分开配置?两者可以使用统一配置不行吗,配置两遍不是显得很冗余且繁琐吗?analyzertype元素就表示这两个阶段,之所以要分阶段配置分词器,是为了满足用户潜在的需求,因为查询阶段的分词需求和索引阶段的分词需求不一定是相同的。我们都知道分词器Analyzer是由一个Tokenizer + NtokenFilter组成,这就是为什么analyzer元素下会有tokenizer元素和filter元素,但tokenizer元素只允许有一个,filter元素可以有N个。之所以这样设计是为了为用户提供更细粒度的方式来配置分词器的行为,即你可以任意组合tokenizerfilter来实现你的特定需求,当然你也可以把这种组合写在Analyzer类里,然后直接在analyzer元素的class属性里配置自定义分词器的完整类名,这样就不需要这么繁琐的配置tokenizerfilter,即把实现细节屏蔽在analyzer类内部,但这样做的话,如果你需要更改实现细节,则需要修改Analyzer源码,然后重新打包成jar,相对来说,比较麻烦点,而使用analyzertokenizer,filter这样来配置,虽然繁琐点,但更灵活。而且采用<analyzer class="xxxxxxxx.IKAnalyzer"这样配置方式,看起来是比较简洁,我想你可能会比较喜欢这种方式,遗憾的是,solr在实现这种方式的时候,考虑不够周全,比如IKAnalyzer分词器,我们都知道IK分词器的构造器还有个useSmart参数,表示是否开启智能分词,而<analyzer class="xxxxxxxx.IKAnalyzer"这种方式,本质还是通过SAX方式解析XML,然后得到class类型字符串,然后通过反射去创建Analyzer实例对象,你可能会问我,我为什么知道是这样实现的?我看了Solr的源码所以我知道,无码无真相,来看截图:(FieldTypePluginLoader类中)
    http://dl2.iteye.com/upload/attachment/0109/5885/8806ad13-0f27-3cf0-9046-626e0ca49c12.png
     
    关键点部分我已经使用红色方框标注出来了,class.newInstance()本质就是通过反射的方式去调用类的无参构造函数,这个大家都知道吧,而IKAnalyzer分词器的构造函数代码如图:
    http://dl2.iteye.com/upload/attachment/0109/5887/e0d1bbda-575e-356a-ad33-db40dda71fe5.png
     
    这意味着useSmart参数永远得不到设置,它永远为false,这就是采用<analyzer class="xxxxxxxx.IKAnalyzer"这种方式进行配置的弊端。它看似非常简洁,但暗藏陷阱,坑爹的Solr。那有没办法解决呢?我能想到的办法就是修改源码重新打包,你可能会问怎么修改?听我慢慢说,不要急。

          FieldTypePluginLoader类中有个readAnalyzer(Node node)方法,其中有一句代码非常关键:

    Java代码  0b22cd404fde7c1404d70136385175a3354.jpg

    1. NamedNodeMap attrs = node.getAttributes();  
    2. String analyzerName = DOMUtil.getAttr(attrs,"class");  

       其中node对象即表示当前<analyzer元素节点,而DOMUtil.getAttr(attrs,"class");表示通过DOMUtil工具类来获取<analyzer元素的class属性,这个好理解吧,我们在schema.xml中可能是这样配置的

         <analyzer class="xxxxx.IKAnalyzer",那一句目的就是获取分词器的class类名,知道类名了就可以反射去创建分词器实例对象啊,就这么简单,所以我们可以自己在<analyzer元素中加一个参数,比如这样:

    Xml代码  31a59c4c9901bade15a56a6bedb9cdf6962.jpg

    1. <analyzer class="org.wltea.analyzer.lucene.IKAnalyzer" useSmart="true"/>     

       然后我们在代码里String useSmart = DOMUtil.getAttr(attrs,"useSmart");就可以获取到属性值了,然后就是通过反射把属性值设置到IKAnalyzer类的useSmart属性中了,这是基本的Java反射操作,下面我提供几个反射工具方法:

    Java代码  a07760cb3823aeedcdb8f6597674f79a2e6.jpg

    1. /** 
    2.      * 循环向上转型获取对象的DeclaredField. 若向上转型到Object仍无法找到返回null. 
    3.      */  
    4.     protected static Field getDeclaredField(final Object object, final String fieldName) {  
    5.         if (null == object || null == fieldName || fieldName.equals("")) {  
    6.             return null;  
    7.         }  
    8.         for (Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {  
    9.             try {  
    10.                 return superClass.getDeclaredField(fieldName);  
    11.             } catch (NoSuchFieldException e) {  
    12.                 // Field不在当前类定义,继续向上转型  
    13.                 continue;  
    14.             }  
    15.         }  
    16.         return null;  
    17.     }  
    18.   
    19.   
    20.   
    21. /** 
    22.      * 直接设置对象属性值无视private/protected修饰符不经过setter函数. 
    23.      */  
    24.     public static void setFieldValue(final Object object, final String fieldName, final Object value) {  
    25.         Field field = getDeclaredField(object, fieldName);  
    26.         if (field == null) {  
    27.             throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");  
    28.         }  
    29.         makeAccessible(field);  
    30.         try {  
    31.             field.set(object, value);  
    32.         } catch (IllegalAccessException e) {  
    33.             throw new RuntimeException("直接设置对象属性值出现异常", e);  
    34.         }  
    35.     }  
    36.   
    37.   
    38.   
    39.   
    40. /** 
    41.      * 强行设置Field可访问 
    42.      */  
    43.     protected static void makeAccessible(final Field field) {  
    44.         if (!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())) {  
    45.             field.setAccessible(true);  
    46.         }  
    47.     }  

        直接调用setFieldValue方法即可,比如在Analyzer analyzer = clazz.newInstance();这句下面添加一句

       setFieldValue(analyzer,"useSmart",Boolean.valueOf(useSmart ));

       这样我们在xml中配置的useSmart参数就设置到Analyzer类中了,这样才能起作用。solr源码如何导入Eclipse上篇博客里我已经介绍过了,至于如果把修改过后的代码打包成jar,直接使用eclipse自带的export功能即可,如图:
    http://dl2.iteye.com/upload/attachment/0109/5891/39c3dc91-8adb-32e2-b701-61b267cda4ae.png
    http://dl2.iteye.com/upload/attachment/0109/5893/a8557baf-6fda-3bc5-aa1f-b4c858fd9a27.png
    http://dl2.iteye.com/upload/attachment/0109/5895/d3c971b8-ebe0-3718-81d8-9a56a3234dce.png
    http://dl2.iteye.com/upload/attachment/0109/5897/eedfe76b-6b04-346f-b57b-6ebf0ad9a48c.png
    http://dl2.iteye.com/upload/attachment/0109/5899/4a4eabcb-bb0e-338b-bdbe-bfc7e0c9a775.png
     
    然后一路Next即可。我只是说说思路,剩下留给你们自己去实践。

         但是采用改源码方式不是很优雅,因为你本地虽然是修改好了,哪天你由Solr5.1.0升级到5.2.0,还要再改一遍,没升级一次就要改一次,你的代码copy给别人用,别人运行代码后看不到效果,增加沟通成本,你还得把你改过源码的jar包共享给别人,这也就是为什么有那么多人找我要什么IK jar包。

        Solr中可以使用TokenizerFactory方式来解决我刚才提出的问题:IKAnalyzer分词器的useSmart参数无法通过schema.xml配置文件进行设置。我花了点时间扩展了IKTokenizerFactory类,代码如下:

    Java代码  0dc3981e640df5ba2a9b096b4376a7a35b9.jpg

    1. package org.apache.lucene.analysis.ik;  
    2.   
    3. import java.util.Map;  
    4.   
    5. import org.apache.lucene.analysis.Tokenizer;  
    6. import org.apache.lucene.analysis.util.TokenizerFactory;  
    7. import org.apache.lucene.util.AttributeFactory;  
    8. import org.wltea.analyzer.lucene.IKTokenizer;  
    9.   
    10. public class IKTokenizerFactory extends TokenizerFactory {  
    11.     public IKTokenizerFactory(Map<String, String> args) {  
    12.         super(args);  
    13.         useSmart = getBoolean(args, "useSmart"false);  
    14.     }  
    15.     private boolean useSmart;  
    16.   
    17.     @Override  
    18.     public Tokenizer create(AttributeFactory attributeFactory) {  
    19.         Tokenizer tokenizer = new IKTokenizer(attributeFactory,useSmart);  
    20.         return tokenizer;  
    21.     }  
    22. }  

       同时我对IKTokenizer类也稍作了修改,修改后源码如下:

    Java代码  6d05b3632036700faa4daa4b52444da1883.jpg

    1. /** 
    2.  * IK分词器 Lucene Tokenizer适配器类 
    3.  * 兼容Lucene 4.0版本 
    4.  */  
    5. public final class IKTokenizer extends Tokenizer {  
    6.       
    7.     //IK分词器实现  
    8.     private IKSegmenter _IKImplement;  
    9.       
    10.     //词元文本属性  
    11.     private final CharTermAttribute termAtt;  
    12.     //词元位移属性  
    13.     private final OffsetAttribute offsetAtt;  
    14.     //词元分类属性(该属性分类参考org.wltea.analyzer.core.Lexeme中的分类常量)  
    15.     private final TypeAttribute typeAtt;  
    16.     //记录最后一个词元的结束位置  
    17.     private int endPosition;  
    18.       
    19.     private Version version = Version.LATEST;  
    20.     /** 
    21.      * Lucene 4.0 Tokenizer适配器类构造函数 
    22.      * @param in 
    23.      * @param useSmart 
    24.      */  
    25.     public IKTokenizer(Reader in , boolean useSmart){  
    26.         //super(in);  
    27.         offsetAtt = addAttribute(OffsetAttribute.class);  
    28.         termAtt = addAttribute(CharTermAttribute.class);  
    29.         typeAtt = addAttribute(TypeAttribute.class);  
    30.         _IKImplement = new IKSegmenter(input , useSmart);  
    31.     }  
    32.       
    33.     public IKTokenizer(AttributeFactory factory, boolean useSmart) {  
    34.         super(factory);  
    35.         offsetAtt = addAttribute(OffsetAttribute.class);  
    36.         termAtt = addAttribute(CharTermAttribute.class);  
    37.         typeAtt = addAttribute(TypeAttribute.class);  
    38.         _IKImplement = new IKSegmenter(input , useSmart);  
    39.     }  
    40.   
    41.     /* (non-Javadoc) 
    42.      * @see org.apache.lucene.analysis.TokenStream#incrementToken() 
    43.      */  
    44.     @Override  
    45.     public boolean incrementToken() throws IOException {  
    46.         //清除所有的词元属性  
    47.         clearAttributes();  
    48.         Lexeme nextLexeme = _IKImplement.next();  
    49.         if(nextLexeme != null){  
    50.             //Lexeme转成Attributes  
    51.             //设置词元文本  
    52.             termAtt.append(nextLexeme.getLexemeText());  
    53.             //设置词元长度  
    54.             termAtt.setLength(nextLexeme.getLength());  
    55.             //设置词元位移  
    56.             offsetAtt.setOffset(nextLexeme.getBeginPosition(), nextLexeme.getEndPosition());  
    57.             //记录分词的最后位置  
    58.             endPosition = nextLexeme.getEndPosition();  
    59.             //记录词元分类  
    60.             typeAtt.setType(nextLexeme.getLexemeTypeString());            
    61.             //返会true告知还有下个词元  
    62.             return true;  
    63.         }  
    64.         //返会false告知词元输出完毕  
    65.         return false;  
    66.     }  
    67.       
    68.     /* 
    69.      * (non-Javadoc) 
    70.      * @see org.apache.lucene.analysis.Tokenizer#reset(java.io.Reader) 
    71.      */  
    72.     @Override  
    73.     public void reset() throws IOException {  
    74.         super.reset();  
    75.         _IKImplement.reset(input);  
    76.     }     
    77.       
    78.     @Override  
    79.     public final void end() {  
    80.         // set final offset  
    81.         int finalOffset = correctOffset(this.endPosition);  
    82.         offsetAtt.setOffset(finalOffset, finalOffset);  
    83.     }  

        修改后重新打包的IKAnalyzer jar请见底下的附件。

        然后我把它打包成了solr-analyzer-ik-5.1.0.jar,只需要把这个jar包复制到你的core\lib目录下即可,然后你就可以像配置StandardTokenizerFactory一样的使用我们自定义的IKTokenizerFactory类了,并且能配置useSmart参数,这正是我想要的,能灵活的控制分词器参数,so cool。配置示例如下:
    http://dl2.iteye.com/upload/attachment/0109/5902/0f84cde8-c977-3976-b0e1-5718b1c8da50.png
    然后field域里应用我们配置的这个text_ik域类型,如图:
    http://dl2.iteye.com/upload/attachment/0109/5904/02e08a7a-e8d3-3854-8947-5bd7f51fa982.png
     
    然后你还需要把IKAnalyzer jar包以及我们自定义的IKTokenizerFactoryjarcopy到你当前core\lib目录下,如图:
    http://dl2.iteye.com/upload/attachment/0109/5906/149c2b92-a731-3a8b-bc78-ae8168f98fe9.png
     IKAnalyzer jar
    建议使用底下附件里我新上传的,因为源码我稍作了修改,上面已经提到过了。然后你需要把IKAnalyzer.cfg.xml配置文件copyE:\apache-tomcat-7.0.55\webapps\solr\WEB-INF\classes目录下,其中E:\apache-tomcat-7.0.55为我的Tomcat安装根目录,请类比成你自己的tomcat安装根目录,你懂的。如图:
    http://dl2.iteye.com/upload/attachment/0109/5908/2eabdfe1-9ffe-33c8-80ac-f8a6f9870fd1.png
     IKAnalyzer.cfg.xml
    配置如图:
    http://dl2.iteye.com/upload/attachment/0109/5910/bcfdfddc-366a-3505-85bc-6601443cee73.png
     ext.dic
    IK分词器的自定义扩展词典,内容如图:
    http://dl2.iteye.com/upload/attachment/0109/5912/9affdc53-286d-3aea-a7fc-2691e89320fd.png
     
    我就在里面加了两个自定义词语。

    然后你就可以启动你的tomcat,然后如图进行分词测试了,
    http://dl2.iteye.com/upload/attachment/0109/5914/3c0a0ff0-611e-325b-b8a6-c6866d62ded7.png
     
    上图是用来测试useSmart参数设置是否有生效,如果你看到如图的效果,说明配置成功了。


    http://dl2.iteye.com/upload/attachment/0109/5917/c2107b8f-c1ca-3674-96e4-2e871d36de7b.png
     
    上图是用来测试自定义词典是否有生效,因为我在ext.dic自定义词典里添加了 劲爆  * 这两个词,所以IK能分出来,逆袭和白富美没有在自定义扩展词典里添加,所以IK分不出来。如果你能看到如图效果,说明IK的自定义扩展词典也配置成功了

     OK,直接开门见山,不绕弯子啦!基于上篇博客,我们知道了在Solr中配置分词器有两种方式,一种是直接配置分词器类,比如:

    Xml代码  f8a471915b588f164016d9c37b387be574a.jpg

    1. <fieldType name="text_ik" class="solr.TextField">        
    2.         <analyzer class="org.wltea.analyzer.lucene.IKAnalyzer" />        
    3. </fieldType>  

     一种是配置TokenizerFactory类,由于Solr API中并没有内置类似IKAnsj这样的中文分词器的TokenizerFactory类,所以我们需要自己扩展,不过你们不用担心,我已经扩展好了。配置样例如下:

    Xml代码  39e796c0dd314eb5f8d14cf6cb5feb31221.jpg

    1. <fieldType name="text_ik" class="solr.TextField">  
    2.         <analyzer type="index">  
    3.             <tokenizer class="org.apache.lucene.analysis.ik.IKTokenizerFactory" useSmart="true"/>  
    4.         </analyzer>  
    5.         <analyzer type="query">  
    6.             <tokenizer class="org.apache.lucene.analysis.ik.IKTokenizerFactory" useSmart="false"/>  
    7.         </analyzer>  
    8. </fieldType>  

        我扩展的AnsjTokenizerFactory源码如下:

    Java代码  8d51bfd90b789846938e013b82c97a61648.jpg

    1. public class AnsjTokenizerFactory  extends TokenizerFactory {  
    2.     /**是否查询分词*/  
    3.     private boolean query;  
    4.     /**是否分析词干.进行单复数,时态的转换(只针对英文单词)*/  
    5.     private boolean pstemming;  
    6.     /**自定义停用词词典文件路径*/  
    7.     private String stopwordsDir;  
    8.           
    9.     public AnsjTokenizerFactory(Map<String, String> args) {  
    10.         super(args);  
    11.         query = getBoolean(args, "query"false);  
    12.         pstemming = getBoolean(args, "pstemming"false);  
    13.         stopwordsDir = get(args, "stopwordsDir""");  
    14.     }  
    15.       
    16.     @Override  
    17.     public Tokenizer create(AttributeFactory factory) {  
    18.         if(query) {  
    19.             return new AnsjTokenizer(factory,new ToAnalysis(new Forest[0]),stopwordsDir,pstemming);  
    20.         }  
    21.         return new AnsjTokenizer(factory,new IndexAnalysis(new Forest[0]),stopwordsDir,pstemming);  
    22.     }  
    23. }  

       下面介绍如何在Solr中使用Ansj分词器,首先你需要在Solr_homecore\lib目录下添加依赖的jar

        ansj_seg-2.0.8.jar(戳我试试(*^__^*) 嘻嘻)

        solr-analyzer-ansj-5.1.0.jar(这个jar包体积较小,请在底下的附件里下载)

        nlp-lang-0.2.jar(这是ansj-seg-2.0.8.jar依赖的jar)

        如图:
    http://dl2.iteye.com/upload/attachment/0109/6213/490a1251-ec9b-3e5d-8402-493fdcda9487.png
     
    然后在schema.xml中添加如下配置:
    http://dl2.iteye.com/upload/attachment/0109/6217/77aca6f9-7375-31c8-a79a-1f880175191f.png
     
    至于querypstemmingstopwordsDir3个配置参数的含义,请看我在源码中作的注释,如图:
    http://dl2.iteye.com/upload/attachment/0109/6219/435f3da5-1301-3408-89fc-660979cde37a.png
     query
    参数:分词的两个阶段:建立索引阶段和查询阶段,即表示是否为查询阶段分词,针对不同的分词阶段采用的分词策略是不一样的。具体看源码,如图:
    http://dl2.iteye.com/upload/attachment/0109/6221/7a28ffaf-335e-38bf-8a51-3776597ab5b9.png
     pstemming
    :表示是否对英文单词进行单复数转换以及时态转换,比如apples还原成appleloved还原成love,broken还原成break,注意pstemming参数仅仅是针对英文,因为只有英文才有单复数和时态形式。

    stopwordsDir参数就很好理解了,就是你的自定义停用词词典的存放路径,

    上面3个参数是可选的,不是必须配置的。

    TokenizerFactory配置好了,然后你就在你的Field中应用此分词器了,如图:
    http://dl2.iteye.com/upload/attachment/0109/6223/229ab5c8-dc68-35c9-bc6e-0f6bf5f5a10a.png
     
    然后你需要把ansjlibrary.properties配置文件copyE:\apache-tomcat-7.0.55\webapps\solr\WEB-INF\classes路径,如图:
    http://dl2.iteye.com/upload/attachment/0109/6225/293aa39a-6bfb-3b4e-9c40-c5ebf3d4421b.png
     library.properties
    配置如下:

    Xml代码  334ce575f43623bad1ab17960ecedcbc3d3.jpg

    1. #redress dic file path  
    2. ambiguityLibrary=E:/apache-tomcat-7.0.55/webapps/solr/WEB-INF/classes/library/ambiguity.dic  
    3. #path of userLibrary this is default library  
    4. userLibrary=E:/apache-tomcat-7.0.55/webapps/solr/WEB-INF/classes/library  
    5. #set real name  
    6. isRealName=true  

     比较恶心的是,anasj分词器的字典文件加载路径这里只能写死成绝对路径,因为它源码里加载字典文件是直接通过new File(dicPath)这种方式来实现的。当你在eclipse中运行,你的dicPath相对路径是你的项目根目录,而如果你的项目部署到tomcat,那dicPath的相对路径就是tomcat根目录下的bin,这确实比较啃爹,所以我这里干脆直接写成绝对路径,当然你可以把字典文件放到任意目录下,比如C:\Library,不是非要放到tomcat下,这个我必须要澄清下。下图是Ansj分词器在加载字典文件时比较恶心的实现方式:
    http://dl2.iteye.com/upload/attachment/0109/6227/9537c120-3c0d-3518-a27c-9165ae667184.png
     
    如果改成这样方式加载字典文件会比较好点,我个人觉得:

       this.getClass().getClassLoader().getResourceAsStream(dicPath);

    这样你的字典文件路径dicPath的相对路径才是当前classPath。不过ansj里你把字典文件配置成绝对路径也可以,不一定非要相对路径,这点仁者见仁智者见智吧!骚年,你怎么看?

    接着你需要在E:\apache-tomcat-7.0.55\webapps\solr\WEB-INF\classes目录下新建一个library目录,然后把ansj自带的两个字典文件ambiguity.dicdefault.dic复制进去,然后新建一个ext.dic文件。相关的字典文件和配置文件我待会儿会上传到附件里供你们参考。其中ext.dic是用户自定义扩展字典文件,如图:
    http://dl2.iteye.com/upload/attachment/0109/6230/651ce113-9f25-3362-b2c3-152d8b2bb635.png
     
    http://dl2.iteye.com/upload/attachment/0109/6232/80b5c34a-6c5c-3b13-a404-91186ce48fe7.png
     
    对于类似这种网络新词,ansj分词器默认是分不出来的,这时就需要定义自定义扩展字典。

    你应该已经发现了,我们在配置AnsjTokenizerFactory的时候配置了stopwordsDir="stopwords/stopwords.dic"自定义停用词加载路径,这里的stopwordsDir是相对于当前classpath的即E:\apache-tomcat-7.0.55\webapps\solr\WEB-INF\classes,所以我们需要在E:\apache-tomcat-7.0.55\webapps\solr\WEB-INF\classes下新建stopwords文件夹,然后在stopwords文件夹下新建一个stopwords.dic字典文件,stopwords.dic内容如下:
    http://dl2.iteye.com/upload/attachment/0109/6234/275e017a-a528-303e-bec6-687a24a13014.png
     
    这里我只加两个词语作为演示,你们可以根据你自己的需求随意添加你自己的停用词。需要解释下的是,之所以stopwordsDir参数是相对于当前classpath,是因为我在实现AnsjTokenizerFactory时是采用这样的方式来加载词典文件的,如图:
    http://dl2.iteye.com/upload/attachment/0109/6236/aed58239-a813-385b-8fad-95d81f6ca6c6.png
     
    这一切准备好了,你就开始进行分词测试了,请如图进行测试:
    http://dl2.iteye.com/upload/attachment/0109/6238/ece9949a-a990-3f36-af8c-87ef45da71d4.png
     
    上图是对自定义新词进行分词测试,么么哒和啪**之所以能被分出来,是因为我们在library\ext.dic自定义词典文件中添加了那两个词语。


    http://dl2.iteye.com/upload/attachment/0109/6242/7a414627-b5fc-32ea-8359-fa1d61388a16.png
     
    上图是用来测试pstemming参数即英文单词的单复数转换以及时态转换,loved是过去式,自动被转换成原型love
    http://dl2.iteye.com/upload/attachment/0109/6244/5524d971-7e14-3b6c-bdb9-d190c7444820.png
     

    上图是用来测试自定义停用词的,如果你看到如图效果,说明你配置成功了!

     

    转载于:https://my.oschina.net/u/147708/blog/1923939

    展开全文
  • Solr5.5搜索引擎之分词原理说明.docx 介绍了Solr5.5内部使用的分词原理,有助于开发者自定义自己的分词器时掌握分词的基础知识。
  • 介绍了Solr5.5内部使用的分词原理,有助于开发者自定义自己的分词器时掌握分词的基础知识。
  • solr配置IK分词器及分词原理解析

    千次阅读 2019-09-01 23:40:27
    1、没有配置IK分词器,用solr自带的text分词它会把一句话分成单个的字。 2、配置IK分词器,的话它会把句子分成词组 3、下载配置分词器 1) 下载分词器IK 分词器下载地址: 1 ...

    1、没有配置IK分词器,用solr自带的text分词它会把一句话分成单个的字。

    2、配置IK分词器,的话它会把句子分成词组

    3、下载配置分词器

    1) 下载分词器IK

    分词器下载地址:

    1

    http://download.csdn.net/detail/u013292160/9926148

    2) 解压下载的文件

    3) 将ik-analyzer-solr5-5.x.jar这个jar包放入solr项目下的WEB-INF\lib目录中

    我的目录:

    1

    /usr/local/tomcat/apache-tomcat-8.5.13/webapps/solr/WEB-INF/lib

    4) 将IKAnalyzer.cfg.xml,mydict.dic,stopword.dic放在solr项目下的WEB-INF\classes目录中。

    我的目录:

    1

    /usr/local/tomcat/apache-tomcat-8.5.13/webapps/solr/WEB-INF/classes

     

    5) 在SolrHome中添加IK分词器

    编辑文件:

    1

    /usr/local/tomcat/apache-tomcat-8.5.13/solr_home/Test/conf/managed-schema

    在文件最后</schema>标签中添加如下配置

    1

    2

    3

    4

    <fieldType name="text_ik" class="solr.TextField">

           <analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>

    </fieldType>

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

    4、验证分词器是否配置成功

    重启Tomcat并访问Solr客户端,点击analysis,输入测试分词的句子,在下拉列表框选择ik分词器,点击Analyse Value验证是否安装成功分词器,并能正确的进行分词。

    展开全文
  • solr分词只能全词匹配怪现象

    千次阅读 2015-07-22 17:05:44
    例如ik分词,安装配置后,可以正常分词,如下图所示Index和Query都没问题了,十分高兴吧! 随后,创建collection,导入数据,再尝试搜索。如下图所示,我们搜索“第四次会议”,可以看到有3条记录,还有点小兴奋...

    现象:

    例如ik分词,安装配置后,可以正常分词,如下图所示Index和Query都没问题了,十分高兴吧!

    随后,创建collection,导入数据,再尝试搜索。如下图所示,我们搜索“第四次会议”,可以看到有3条记录,还有点小兴奋!


    既然已经分词了,应该可以搜索非完全匹配的,如下图所示:


    fuck!Why 搜索“第五次会议”一条匹配的没有?关键搜索条件也进行了分词!郁闷的一天开始了,索引删了建建了删,反反复复尝试,向大牛益达反复咨询。最后我开始怀疑了,是不是lucene底层就是这样的?启动我的ElasticSearch服务,确认了一下,120%可以部分匹配搜索。

            百度点的搜都有麻木的时候发下如下这两篇文章:

    http://www.aboutit.cn/post/323

    http://blog.csdn.net/bruce128/article/details/18351593


    特别注意,我用的是solr4.9,所以需要把各核心schema.xml中的版本由1.1改为1.5这样查询时分词才能成功,比如搜索中华人民共和国,如果不配置的话,默认是短语匹配,就只搜索文档中包含中华人民共和国的结果,但是如果配置了查询分词,那么中华、人民….都能被匹配。

    修改后的schema如下所示:
    <span style="color:#330033;"><strong><schema name="example core zero" version="1.5"></strong></span>



    展开全文
  • Solr工作原理

    万次阅读 2018-07-13 14:56:19
    Solr简介Solr是一个独立的企业级搜索应用服务器,它对外提供类似于...要想知道solr的实现原理,首先得了解什么是全文检索,solr的索引创建过程和索引搜索过程。一、全文检索首先举个例子:比如现在有5个文档,我现在...

    Solr简介

    Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口。用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引;也可以通过Http Get操作提出查找请求,并得到XML格式的返回结果。

    要想知道solr的实现原理,首先得了解什么是全文检索,solr的索引创建过程和索引搜索过程。

    一、全文检索

    首先举个例子:比如现在有5个文档,我现在想从5个文档中查找出包含"solr工作原理"的文档,此时有两种做法:

    1.顺序扫描法:对5个文档依次查找,包含目标字段的文档就记录下来,最后查找的结果可能是在2,3文档中,这种查找方式叫做顺序扫描法

    顺序扫描法在文档数量较少的情况下,查找速度还是很快的,但是当文档数量很多时,查找速度就差强人意了。

    2.全文检索:对文档内容进行分词,对分词后的结果创建索引,然后通过对索引进行搜索的方式叫做全文检索

    全文检索就相当于根据偏旁部首或者拼音去查找字典,在文档很多的情况,这种查找速度肯定比你一个一个文档查找要快。

    二、索引创建和搜索过程

    1.创建索引

    举例子:

    文档一:solr是基于Lucene开发的企业级搜索引擎技术

    文档二:Solr是一个独立的企业级搜索应用服务器,Solr是一个高性能,基于Lucene的全文搜索服务器

    首先经过分词器分词,solr会为分词后的结果(词典)创建索引,然后将索引和文档id列表对应起来,如下图所示:


    比如:solr在文档1和文档2中都有出现,所以对应的文档ID列表中既包含文档1的ID也包含文档2的ID,文档ID列表对应到具体的文档,并体现该词典在该文档中出现的频次,频次越多说明权重越大,权重越大搜索的结果就会排在前面。

    solr内部会对分词的结果做如下处理:

    1.去除停词和标点符号,例如英文的this,that等, 中文的"的","一"等没有特殊含义的词

    2.会将所有的大写英文字母转换成小写,方便统一创建索引和搜索索引

    3.将复数形式转为单数形式,比如students转为student,也是方便统一创建索引和搜索索引

    2.索引搜索过程

    知道了创建索引的过程,那么根据索引进行搜索就变得简单了。

    1.用户输入搜索条件

    2.对搜索条件进行分词处理

    3.根据分词的结果查找索引

    4.根据索引找到文档ID列表

    5.根据文档ID列表找到具体的文档,根据出现的频次等计算权重,最后将文档列表按照权重排序返回


    访问我的达人课

    更多博客内容详见我的博客 Wang's Blog



    展开全文
  • Solr 搜索原理1.搜索原理2.Solr 中数据存储说明 1.搜索原理 Solr 能够提升检索效率的主要原因就是分词和索引(反向索引)。 分词:会对搜索条件/存储内容进行分词,分成日常所使用的词语。 索引:存储在 Solr 中...
  • solr实现原理

    千次阅读 2018-05-07 23:22:35
    solr那是我1年前使用到的一个搜索引擎,由于当初对于配置了相应了,但是今天突然面试问到了,哎,太久了,真的忘记了,今天特地写一篇博客记下来solr是一个独立的企业级搜索应用服务器,它对外t提供类似于web-...
  • solr中文分词器技术

    2018-08-14 15:45:56
    中文分词技术(中文分词原理)词是最小的能够独立活动的有意义的语言成分,英文单词之间是以空格作为自然分界符的,而汉语是以字为基本的书写单位,词语之间没有明显的区分标记,因此,中文词语分析是中文信息处理的...
  • solr基本原理

    2018-02-06 17:09:37
    全文检索引擎Solr系列—–全文检索基本原理 场景:小时候我们都使用过新华字典,妈妈叫你翻开第38页,找到“坑爹”所在的位置,此时你会怎么查呢?毫无疑问,你的眼睛会从38页的第一个字开始...
  • solr原理

    2018-06-02 14:56:00
    在少量数据中进行数据查询时,可以使用使用顺序扫描法逐条扫描,但是在数据量比较大时,顺序扫描法可能会比较耗时,这是... solr检索的使用的是一种反向索引,反向索引就是从关键词到文档的映射过程。保存这种信息...
  • solr底层原理

    千次阅读 2018-06-11 10:41:17
    比如说,我们要寻找既包含字符串“lucene”又包含字符串“solr”的文档,我们只需要以下几步: 1. 取出包含字符串“lucene”的文档链表。 2. 取出包含字符串“solr”的文档链表。 3. 通过合并链表,找出既包含...
  • 搜索引擎的基本原理: 1.通过分词创建索引 a.根据存储数据对应的字段进行分词,得到分词库; Solr/Lucene采用的是一种反向索引,所谓反向索引:就是从关键字到文档的映射过程,保存这种映射这种信息的索引称为反
  • Solr原理及使用

    2021-08-02 18:44:47
    solr是基于Lucence开发的企业级搜索引擎技术,而lucence的原理是倒排索引。那么什么是倒排索引呢?接下来我们就介绍一下lucence倒排索引原理。 假设有两篇文章1和2: 文章1的内容为:老超在卡子门工作...
  • Solr中文分词及分数计算

    千次阅读 2019-05-23 11:45:06
    Solr中文分词及分数计算 中文分词 基本概念 众所周知,英文是以词为单位的,词与词之间是靠空格隔开,而中文是以字为单位,句子中所有的字连起来才能表达清楚意思。举个例子,英文句子I am a student,用中文表示...
  • Solr核心原理倒排索引

    2019-07-28 23:00:27
     中文和英文等语言不同,单词之间没有明确分隔符号,所以首先要用分词系统将文档自动切分成单词序列。这样每个文档就转换为由单词序列构成的数据流,为了系统后续处理方便,需要对每个不同的单词赋予唯一的单词编号...
  • 获取demo相关jar包 2, 源代码实现明细 org.apache.lucene.demo.IndexFiles : StandardAnalyzer index阶段 org.apache.lucene.demo.SearchFiles : StandardAnalyzer query阶段 StandardAnalyzer 中文分词示例:...
  • Solr原理

    千次阅读 2019-01-05 14:07:20
     中文和英文等语言不同,单词之间没有明确分隔符号,所以首先要用分词系统将文档自动切分成单词序列。这样每个文档就转换为由单词序列构成的数据流,为了系统后续处理方便,需要对每个不同的单词赋予唯一的单词编号...
  • Lucene是一套信息检索工具包,并不包含搜索引擎系统,它包含了索引结构、读写索引工具、相关性工具、排序等功能,因此在使用Lucene时仍需要关注搜索引擎系统,例如数据获取、解析、分词等方面的东西。而solr和...
  • ik分词器的分词原理本质上是词典分词。现在内存中初始化一个词典,然后在分词过程中挨个读取字符,和字典中的字符相匹配,把文档中的所有词语拆分出来的过程。 ...
  • solr原理就是倒排索引 数据库是正排索引 倒排索引与正排索引讲解 2。IK中文分词器 下载地址 2.2将架包放在solr-8.2.0\server\solr-webapp\webapp\WEB-INF\lib 这个文件夹下 2.3在solr-8.2.0\server\solr-webapp\...
  • solr原理

    2019-09-27 19:50:20
    首先要明白solr其实本质上是一个软件应用,它的原理其实是基于lucence的,lucence中文的意思是全文检索工具,他是将你的每一个文档进行划分,然后创建索引,当你搜到某一关键字时,就会搜出来它的文档。 原始文档...
  • Lucene的分词原理与分词系统 lucene算法Solr搜索引擎全文检 分词原理 建立索引和查询的过程中,都是以基本的语素项为单位的。基本的语素项就是通过分词得到。这个过程决定了索引单元金额最终的匹配过程...
  • solr(中文分词器)集群

    2019-04-09 10:34:03
    solr 源码 + IK 分词器 + zookeeper。
  • 1,这里Solr主要是怎么使用的呢? 当我们在前台页面搜索商品名称关键词时, 我们这时是在Solr库中去查找相应的商品信息, 然后将搜索关键词高亮. 2,那么Solr库中的商品信息又是如何添加的呢? 当我们在给商品上架的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,236
精华内容 1,294
关键字:

solr分词原理