天天看點

ElasticSearch第三步-中文分詞

ElasticSearch系列學習

ElasticSearch第一步-環境配置

ElasticSearch第二步-CRUD之Sense 

ElasticSearch第三步-中文分詞

ElasticSearch第四步-查詢詳解

ElasticSearch第五步-.net平台下c#操作ElasticSearch詳解

elasticsearch官方隻提供smartcn這個中文分詞插件,效果不是很好,好在國内有medcl大神(國内最早研究es的人之一)寫的兩個中文分詞插件,一個是ik的,一個是mmseg的,下面分别介紹ik的用法,

當我們建立一個index(庫db_news)時,easticsearch預設提供的分詞器db_news,分詞結果會把每個漢字分開,而不是我們想要的根據關鍵詞來分詞。例如:

代碼如下:

GET /db_news/_analyze?analyzer=standard
{
    我愛北京天安門
}      

分詞結果如下:

{
   "tokens": [
      {
         "token": "我",
         "start_offset": 6,
         "end_offset": 7,
         "type": "<IDEOGRAPHIC>",
         "position": 1
      },
      {
         "token": "愛",
         "start_offset": 7,
         "end_offset": 8,
         "type": "<IDEOGRAPHIC>",
         "position": 2
      },
      {
         "token": "北",
         "start_offset": 8,
         "end_offset": 9,
         "type": "<IDEOGRAPHIC>",
         "position": 3
      },
      {
         "token": "京",
         "start_offset": 9,
         "end_offset": 10,
         "type": "<IDEOGRAPHIC>",
         "position": 4
      },
      {
         "token": "天",
         "start_offset": 10,
         "end_offset": 11,
         "type": "<IDEOGRAPHIC>",
         "position": 5
      },
      {
         "token": "安",
         "start_offset": 11,
         "end_offset": 12,
         "type": "<IDEOGRAPHIC>",
         "position": 6
      },
      {
         "token": "門",
         "start_offset": 12,
         "end_offset": 13,
         "type": "<IDEOGRAPHIC>",
         "position": 7
      }
   ]
}      

正常情況下,這不是我們想要的結果,比如我們更希望 “我”,“愛”,“北京”,"天安門"這樣的分詞,這樣我們就需要安裝中文分詞插件,ik就是實作這個功能的。

 安裝ik插件

第一種方式是直接下載下傳配置,這種方式比較麻煩(對于Windows使用者來講),這裡我也不講了

下載下傳位址:https://github.com/medcl/elasticsearch-analysis-ik

 ********************************************************************************************

第二種方式是直接下載下傳elasticsearch中文發行版。下載下傳位址是:https://github.com/medcl/elasticsearch-rtf。重新運作安裝。

執行指令:

GET /db_news/_analyze?analyzer=ik
{
    我愛北京天安門啊王軍華
    
}      

結果如下:

{
   "tokens": [
      {
         "token": "我",
         "start_offset": 6,
         "end_offset": 7,
         "type": "CN_CHAR",
         "position": 1
      },
      {
         "token": "愛",
         "start_offset": 7,
         "end_offset": 8,
         "type": "CN_CHAR",
         "position": 2
      },
      {
         "token": "北京",
         "start_offset": 8,
         "end_offset": 10,
         "type": "CN_WORD",
         "position": 3
      },
      {
         "token": "天安門",
         "start_offset": 10,
         "end_offset": 13,
         "type": "CN_WORD",
         "position": 4
      },
      {
         "token": "啊",
         "start_offset": 13,
         "end_offset": 14,
         "type": "CN_CHAR",
         "position": 5
      },
      {
         "token": "王軍",
         "start_offset": 14,
         "end_offset": 16,
         "type": "CN_WORD",
         "position": 6
      },
      {
         "token": "華",
         "start_offset": 16,
         "end_offset": 17,
         "type": "CN_CHAR",
         "position": 7
      }
   ]
}      

關于分詞器定義需要注意的地方

如果我們直接建立索引庫,會使用預設的分詞進行分詞,這不是我們想要的結果。這個時候我們再去更改分詞器會報錯如下:

{
   "error": "IndexAlreadyExistsException[[db_news] already exists]",
   "status": 400
}      

而且沒有辦法解決沖突,唯一的辦法是删除已經存在的索引,建立一個索引,并制定mapping使用新的分詞器(注意要在資料插入之前,否則會使用elasticsearch預設的分詞器)。

 建立索引指令如下:

PUT /db_news
{
    
     "settings" : {
        "analysis" : {
            "analyzer" : {
                "stem" : {
                    "tokenizer" : "standard",
                    "filter" : ["standard", "lowercase", "stop", "porter_stem"]
                }
            }
        }
    },
    "mappings" : {
        "person" : {
            "dynamic" : true,
            "properties" : {
                "intro" : {
                    "type" : "string",
                    "indexAnalyzer" : "ik",
                    "searchAnalyzer":"ik"      
}
            }
        }
    }
}      

檢視建立的索引:

GET /db_news/_mapping      
{
   "db_news": {
      "mappings": {
         "person": {
            "dynamic": "true",
            "properties": {
               "age": {
                  "type": "long"
               },
               "intro": {
                  "type": "string",
                  "analyzer": "ik"
               },
               "name": {
                  "type": "string"
               }
            }
         }
      }
   }
}      

更新映射

說明:對于db_news/news,開始沒有字段msgs,後來添加了這個字段,那麼要先修改索引方式,在新增資料

PUT /db_news/_mapping/news
{
            "properties" : {
                "msgs" : {
                    "type" : "string",
                    "indexAnalyzer" : "ik",
                    "searchAnalyzer":"ik"
                }    
    }
}      

作者:夢亦曉,轉載請注明出處

如果此文能給您提供幫助,請點選右下角的【推薦】

如果您對此文有不同的見解或者意見,歡迎留言讨論