全文檢索Solr集成HanLP中文分詞

之前發佈過HanLP的Lucene插件,後來不少人跟我說其實Solr更流行(反正我是以爲既然Solr是Lucene的子項目,那麼稍微改改配置就能支持Solr),因而就抽空作了個Solr插件出來,開源在Github上,歡迎改進。java

HanLP中文分詞solr插件支持Solr5.x,兼容Lucene5.x。git

快速上手

  1. hanlp-portable.jarhanlp-solr-plugin.jar共兩個jar放入${webapp}/WEB-INF/libgithub

  2. 修改solr core的配置文件${core}/conf/schema.xmlweb

<fieldType name="text_cn" class="solr.TextField">    <analyzer type="index" enableIndexMode="true" class="com.hankcs.lucene.HanLPAnalyzer"/>    <analyzer type="query" enableIndexMode="true" class="com.hankcs.lucene.HanLPAnalyzer"/></fieldType>

效果一覽

對於新手來講,上面的兩步可能太簡略了,不如看看下面的step by step瀏覽器

啓動solr

首先在solr-5.2.1\bin目錄下啓動solr:bash

solr start -f

用瀏覽器打開http://localhost:8983/solr/#/,看到以下頁面說明一切正常:app

建立core

在solr-5.2.1\server\solr下新建一個目錄,取個名字好比叫one,將 示例配置文件solr-5.2.1\server\solr\configsets\sample_techproducts_configs\conf 拷貝過來,對conf目錄下的schema.xml作上述一步改動,意思是使用HanLP分詞器來對text_cn域進行分詞。接着修改 schema.xml中的默認域type,搜索webapp

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

修改成maven

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

意思是默認文本爲text_cn類型。工具

完成了以後在solr的管理界面導入這個core one:

接着就能在下拉列表中看到這個core了:

上傳測試文檔

修改好了,就能夠拿一些測試文檔來試試效果了。hanlp-solr-plugin代碼庫中的src/test/resources下有個測試文檔集合documents.csv,其內容以下:

id,title1,你好世界2,商品和服務3,和服的價格是每鎊15便士4,服務大衆5,hanlp工做正常

表明着id從1到5共五個文檔,接下來複制solr-5.2.1\example\exampledocs下的上傳工具post.jar到resources目錄,利用以下命令行將數據導入:

java -Dc=one -Dtype=application/csv -jar post.jar *.csv

Windows用戶的話直接雙擊該目錄下的upload.cmd便可。

正常狀況下輸出以下結果:

SimplePostTool version 5.0.0Posting files to [base] url http://localhost:8983/solr/one/update using content-type application/csv...POSTing file documents.csv to [base]1 files indexed.COMMITting Solr index changes to http://localhost:8983/solr/one/update...Time spent: 0:00:00.059請按任意鍵繼續. . .

同時刷新一下core one的Overview,的確看到了5篇文檔:

搜索文檔

是時候看看HanLP分詞的效果了,點擊左側面板的Query,輸入「和服」試試:

發現精確地查到了「和服的價格是每鎊15便士」,而不是「商品和服務」這種錯誤文檔:

這說明HanLP工做良好。

要知道,很多中文分詞器眉毛鬍子一把抓地命中「商品和服務」這種錯誤文檔,下降了查準率,拉低了用戶體驗,跟原始的MySQL LIKE有何區別?

代碼調用

在Query改寫的時候,能夠利用HanLPAnalyzer分詞結果中的詞性等屬性,如

String text = "中華人民共和國很遼闊";for (int i = 0; i < text.length(); ++i){    System.out.print(text.charAt(i) + "" + i + " ");}System.out.println();Analyzer analyzer = new HanLPAnalyzer();TokenStream tokenStream = analyzer.tokenStream("field", text);tokenStream.reset();while (tokenStream.incrementToken()){    CharTermAttribute attribute = tokenStream.getAttribute(CharTermAttribute.class);    // 偏移量    OffsetAttribute offsetAtt = tokenStream.getAttribute(OffsetAttribute.class);    // 距離    PositionIncrementAttribute positionAttr = kenStream.getAttribute(PositionIncrementAttribute.class);    // 詞性    TypeAttribute typeAttr = tokenStream.getAttribute(TypeAttribute.class);    System.out.printf("[%d:%d %d] %s/%s\n", offsetAtt.startOffset(), offsetAtt.endOffset(), positionAttr.getPositionIncrement(), attribute, typeAttr.type());}

在另外一些場景,支持以自定義的分詞器(好比開啓了命名實體識別的分詞器、繁體中文分詞器、CRF分詞器等)構造HanLPTokenizer,好比:

tokenizer = new HanLPTokenizer(HanLP.newSegment()                    .enableJapaneseNameRecognize(true)                    .enableIndexMode(true), null, false);tokenizer.setReader(new StringReader("林志玲亮相網友:肯定不是波多野結衣?"));...

高級配置

HanLP分詞器主要經過class path下的hanlp.properties進行配置,請閱讀HanLP天然語言處理包文檔以瞭解更多相關配置,如:

  1. 停用詞

  2. 用戶詞典

  3. 詞性標註

  4. ……

相關文章
相關標籤/搜索