1、问题抛出?
实战开发应用场景中,有获取一段话、一篇文章词频的业务场景,
词频的前提就是分词。
常用的中文分词包括:
1、IK分词——https://github.com/medcl/elasticsearch-analysis-ik
2、结巴分词——https://github.com/huaban/elasticsearch-analysis-jieba
3、ANSJ分词——https://github.com/NLPchina/elasticsearch-analysis-ansj
实际开发中,我们可以借助以上分词工具封装成接口或服务进行分词。
但,有没有想过,借助Elasticsearch的分词插件直接实现分词呢并对外提供服务呢?
2、可行性
1、 Elasticsearch对中文的处理,倒排索引的前置条件就是中文分词。
而分词,我们常用的就是IK分词插件。
2、 正常ES的部署、开发设计时候就提前选好分词器。
综上,借助Elasticsearch实现分词完全没有问题。
3、Elasticsearch中的DSL实现
GET test_index/_analyze
{
"analyzer":"ik_smart",
"text":"9年后,我还是没有跑出去 | 震后余生"
}
返回结果:
{
"tokens": [
{
"token": "9",
"start_offset": 0,
"end_offset": 1,
"type": "ARABIC",
"position": 0
},
{
"token": "年后",
"start_offset": 1,
"end_offset": 3,
"type": "CN_WORD",
"position": 1
},
{
"token": "我",
"start_offset": 4,
"end_offset": 5,
"type": "CN_WORD",
"position": 2
},
{
"token": "还是",
"start_offset": 5,
"end_offset": 7,
"type": "CN_WORD",
"position": 3
},
{
"token": "没有",
"start_offset": 7,
"end_offset": 9,
"type": "CN_WORD",
"position": 4
},
{
"token": "跑出去",
"start_offset": 9,
"end_offset": 12,
"type": "CN_WORD",
"position": 5
},
{
"token": "震后",
"start_offset": 15,
"end_offset": 17,
"type": "CN_WORD",
"position": 6
},
{
"token": "余生",
"start_offset": 17,
"end_offset": 19,
"type": "CN_WORD",
"position": 7
}
]
}
4、Elasticsearch Java接口实现
以下是基于Jest5.3.3的接口实现。
/*
*@brief:获取分词结果接口
*@param:待分词的文章/字符串
*@return:不重复分词结果集(可根据实际业务场景二次开发)
*@date:20180704
*/
public static String IK_TYPE = "ik_smart";
public static Set<String> getIkAnalyzeSearchTerms(String searchContent) {
// 调用 IK 分词分词
JestClient client = JestHelper.getClient();
Analyze ikAnalyze = new Analyze.Builder()
.index(TEST_INDEX)
.analyzer(IK_TYPE)
.text(searchContent)
.build();
JestResult result = null;
Set<String> keySet = new HashSet<String>();
try {
result = client.execute(ikAnalyze);
JsonArray jsonArray = result.getJsonObject().getAsJsonArray("tokens");
int arraySize = jsonArray.size();
for (int i = 0; i < arraySize; ++i) {
JsonElement curKeyword = jsonArray.get(i).getAsJsonObject().get("token");
//Logger.info("rst = " + curKeyword.getAsString());
keySet.add(curKeyword.getAsString());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return keySet;
}
有了java接口,对外提供Restful API就变得相对简单了。
5、小结
充分挖据Elasticsearch自身特性,优化、简化业务场景才是王道!