1.前言:
上篇已經(jīng)說過ik的集成,這篇說下ik的實(shí)際使用
2.2、IK分詞器測(cè)試
IK提供了兩個(gè)分詞算法ik_smart 和 ik_max_word
- ik_smart:為最少切分
- ik_max_word:為最細(xì)粒度劃分。
2.2.1、最小切分示例
-
#分詞器測(cè)試ik_smart
-
POST _analyze
{
"analyzer":"ik_smart",
"text":"我是中國(guó)人"
}
?結(jié)果:
{
"tokens": [
{
"token": "我",
"start_offset": 0,
"end_offset": 1,
"type": "CN_CHAR",
"position": 0
},
{
"token": "是",
"start_offset": 1,
"end_offset": 2,
"type": "CN_CHAR",
"position": 1
},
{
"token": "中國(guó)人",
"start_offset": 2,
"end_offset": 5,
"type": "CN_WORD",
"position": 2
}
]
}
2.2.2、最細(xì)切分示例
#分詞器測(cè)試ik_max_word
POST _analyze
{
"analyzer":"ik_max_word",
"text":"我是中國(guó)人"
}
結(jié)果:
{
"tokens": [
{
"token": "我",
"start_offset": 0,
"end_offset": 1,
"type": "CN_CHAR",
"position": 0
},
{
"token": "是",
"start_offset": 1,
"end_offset": 2,
"type": "CN_CHAR",
"position": 1
},
{
"token": "中國(guó)人",
"start_offset": 2,
"end_offset": 5,
"type": "CN_WORD",
"position": 2
},
{
"token": "中國(guó)",
"start_offset": 2,
"end_offset": 4,
"type": "CN_WORD",
"position": 3
},
{
"token": "國(guó)人",
"start_offset": 3,
"end_offset": 5,
"type": "CN_WORD",
"position": 4
}
]
}
3、IK分詞器為何如此智能
????????通過上面的示例我們也看到了,這種中文的分詞效果是ES內(nèi)置的分詞器無法比擬的。那么它是如何做到的呢?不要過于驚訝,因?yàn)樵砥鋵?shí)非常簡(jiǎn)單,它是通過索引字典來達(dá)到的,這樣說可能比較抽象難懂,我們來實(shí)際看看ES的plugins/ik/config目錄:
3.1、ik分詞器的字典
????????看到那些*.dic結(jié)尾的文件了嗎?其實(shí)它就是dictionary(字典)的簡(jiǎn)寫,來實(shí)際看看字典內(nèi)容:如上圖。
????????實(shí)際的詞匯量是非常巨大的,根本不可能完全收錄到字典中。如果有需要,我們完全可以通過在字典文件中增加我們想要的詞語來擴(kuò)展我們自己的分詞規(guī)則。
4、擴(kuò)展ik分詞器的字典
示例:
????????“麻花疼”使用ik_smart、ik_max_word 分詞后的結(jié)果都是:麻花、疼。
? ?無法分詞為一個(gè)完整的“麻花疼”,因?yàn)閕k分詞器的詞典中沒有這個(gè)詞。示例如下圖:
?麻花疼
使用ik_smart分詞
GET _analyze
{
"analyzer": "ik_smart",
"text": "麻花疼"
}
{
"tokens": [
{
"token": "麻花",
"start_offset": 0,
"end_offset": 2,
"type": "CN_WORD",
"position": 1
},
{
"token": "疼",
"start_offset": 2,
"end_offset": 3,
"type": "CN_CHAR",
"position": 2
}
]
}
如何將“麻花疼”分詞為一個(gè)完整的詞,需要將其添加到詞典中。
4.1、ik分詞器的配置文件目錄
?在plugins/elasticsearch-analysis-ik-6.8.2/config/config
目錄下有ik分詞配置文件:
- IKAnalyzer.cfg.xml,用來配置自定義的詞庫(kù)
- main.dic,ik原生內(nèi)置的中文詞庫(kù),只要是這些單詞,都會(huì)被分在一起。
- surname.dic,中國(guó)的姓氏。
- suffix.dic,特殊(后綴)名詞,例如
鄉(xiāng)、江、所、省
等等。- preposition.dic,中文介詞,例如
不、也、了、仍
等等。- stopword.dic,英文停用詞庫(kù),例如
a、an、and、the
等。- quantifier.dic,單位名詞,如
厘米、件、倍、像素
等。- extra開頭的文件,是額外的詞庫(kù)。
4.2、IKAnalyzer.cfg.xml配置文件
4.3、新增字典配置文件,后綴為dic?
在新的字段配置文件my_ik.dic中添加新詞:“麻花疼”。
注意:詞庫(kù)的編碼必須是utf-8
。
?4.4、將新增的配置文件添加到IK字典配置文件中,并重啟ES和KIBANA
?ES啟動(dòng)控制臺(tái)中會(huì)顯示已經(jīng)讀取到自定義字典:
再次查詢,該詞已經(jīng)成功識(shí)別?。
4.5、IK插件還支持熱更新:
IKAnalyzer.cfg.xml配置文件中的有如下配置:
?其中?words_location
?是指一個(gè) url,比如?http://yoursite.com/getCustomDict
,該請(qǐng)求只需滿足以下兩點(diǎn)即可完成分詞熱更新。
- 該 http 請(qǐng)求需要返回兩個(gè)頭部(header),一個(gè)是?
Last-Modified
,一個(gè)是?ETag
,這兩者都是字符串類型,只要有一個(gè)發(fā)生變化,該插件就會(huì)去抓取新的分詞進(jìn)而更新詞庫(kù)。 - 該 http 請(qǐng)求返回的內(nèi)容格式是一行一個(gè)分詞,換行符用?
\n
?即可。
滿足上面兩點(diǎn)要求就可以實(shí)現(xiàn)熱更新分詞了,不需要重啟es 。
????????可以將需自動(dòng)更新的熱詞放在一個(gè)?UTF-8
?編碼的?.txt
文件里,放在 nginx 或其他簡(jiǎn)易 http server 下,當(dāng)?.txt
文件修改時(shí),http server 會(huì)在客戶端請(qǐng)求該文件時(shí)自動(dòng)返回相應(yīng)的 Last-Modified 和 ETag??梢粤硗庾鲆粋€(gè)工具來從業(yè)務(wù)系統(tǒng)提取相關(guān)詞匯,并更新這個(gè)?.txt
文件。
5.java調(diào)用ik分詞器的analyzer:
這里是用httpClient實(shí)現(xiàn)的,沒用es的客戶端,網(wǎng)上找了半天也沒找到合適的文章,大多都是用es高亮客戶端,還得用索引庫(kù),費(fèi)勁感覺有點(diǎn)。自己用httpClient寫吧
public static String httpPostNeedPassword(String json,String url,String username,
String password) {
String result = "";
try {
HttpClient httpClient = new HttpClient();
PostMethod postMethod = new PostMethod(url);
//需要驗(yàn)證
UsernamePasswordCredentials creds = new UsernamePasswordCredentials(username, password);
httpClient.getState().setCredentials(AuthScope.ANY, creds);
StringRequestEntity requestEntity = new StringRequestEntity(json, "application/json", "UTF-8");
postMethod.setRequestEntity(requestEntity);
int i = httpClient.executeMethod(postMethod);
InputStream inputStream = postMethod.getResponseBodyAsStream();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
String s;
StringBuffer sb = new StringBuffer();
while ((s = br.readLine()) != null) {
sb.append(s + "\n");
}
result = new String(sb.toString().getBytes(),"UTF-8");
postMethod.releaseConnection();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
@Test
public void test(){
String s = httpPostNeedPassword("{ \"analyzer\": \"ik_max_word\", \"text\":\"洛陽古跡風(fēng)景很好,是旅游勝地,毛澤東也去過,發(fā)呆著\" }", "http://123.57.220.31:9200/_analyze", "elastic", "mycomm123");
System.out.println(s);
}
結(jié)果:文章來源:http://www.zghlxwxcb.cn/news/detail-761358.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-761358.html
到了這里,關(guān)于ElasticSearch 學(xué)習(xí)8 :ik分詞器的擴(kuò)展,及java調(diào)用ik分詞器的analyzer的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!