首页 > 代码库 > ElasticSearch第三步-中文分词

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"
                }    
    }
}

 

 

 

ElasticSearch系列学习

ElasticSearch第一步-环境配置

ElasticSearch第二步-CRUD之Sense 

ElasticSearch第三步-中文分词

ElasticSearch第四步-查询详解

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

 

ElasticSearch第三步-中文分词