天天看點

總結 | Elasticsearch對外提供分詞服務實踐

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自身特性,優化、簡化業務場景才是王道!

作者:銘毅天下

轉載請标明出處,原文位址:

https://blog.csdn.net/laoyang360/article/details/80892343