Elasticsearch2.X与5.X中文分词插件IK配置详解

Elasticsearch2.X与5.X中文分词插件IK配置详解

1.IK的安装与配置

首先是安装,ES安装此处不再赘述,ES对应的版本号大致对比如下

IK versionES version
master6.x -> master
6.3.06.3.0
6.2.46.2.4
6.1.36.1.3
5.6.85.6.8
5.5.35.5.3
5.4.35.4.3
5.3.35.3.3
5.2.25.2.2
5.1.25.1.2
1.10.62.4.6
1.9.52.3.5
1.8.12.2.1
1.7.02.1.1
1.5.02.0.0
1.2.61.0.0
1.2.50.90.x
1.1.30.20.x
1.0.00.16.2 -> 0.19.0

根据你的ES的具体版本寻找对应的IK版本

IK的github地址 https://github.com/medcl/elasticsearch-analysis-ik
IK的编译后压缩包地址 https://github.com/medcl/elasticsearch-analysis-ik/releases
注:如果你用的是源码需要手动用maven编译打包一下

获取到压缩包后,扔到Elasticsearch/plugins/ik中进行解压(有的压缩包可能会自带一个父文件夹,那么就需要提取文件夹里面的东西扔到ik里),如果ES版本是2.X的,需要在conf/elasticsearch.yml加入index.analysis.analyzer.ik.type: ik即可,如果是5.X版本的不需要进行任何的配置,直接启动elasticsearch,可以看到后台log里有写读取ik即为成功。

[2018-10-11 15:13:19,285][INFO ][ik-analyzer              ] try load config from /home/es/es/elasticsearch-2.4.4/config/analysis-ik/IKAnalyzer.cfg.xml
[2018-10-11 15:13:19,285][INFO ][ik-analyzer              ] try load config from /home/es/es/elasticsearch-2.4.4/plugins/ik/config/IKAnalyzer.cfg.xml
2.IK分词的原理与测试

分词的测试使用curl或者postman都可以,我个人倾向于postman,主要是能保存,要方便一些。下面给出测试代码
首先是分词情况的测试

POST: 127.0.0.1:9100/_analyze
JSON:{
	"text":"今天也在摸鱼中度过",
	"analyzer":"ik_max_word"
}

其中analyzer里默认是standard,也可以指定其他的自带的分词器如english。ik的分词器有ik_max_word和ik_smart,二者区别前者为最细粒度的拆分,后者最粗粒度。
原本es对于中文的分词会把每一个字单独分开,在使用ik后会分成多个词,如果以最细粒度的ik_max_word拆分的话,结果如下

{
    "tokens": [
        {
            "token": "今天",
            "start_offset": 0,
            "end_offset": 2,
            "type": "CN_WORD",
            "position": 0
        },
        {
            "token": "也",
            "start_offset": 2,
            "end_offset": 3,
            "type": "CN_CHAR",
            "position": 1
        },
        {
            "token": "摸鱼",
            "start_offset": 4,
            "end_offset": 6,
            "type": "CN_WORD",
            "position": 2
        },
        {
            "token": "摸",
            "start_offset": 4,
            "end_offset": 5,
            "type": "CN_WORD",
            "position": 3
        },
        {
            "token": "鱼",
            "start_offset": 5,
            "end_offset": 6,
            "type": "CN_CHAR",
            "position": 4
        },
        {
            "token": "中度",
            "start_offset": 6,
            "end_offset": 8,
            "type": "CN_WORD",
            "position": 5
        },
        {
            "token": "度过",
            "start_offset": 7,
            "end_offset": 9,
            "type": "CN_WORD",
            "position": 6
        }
    ]
}

可以看到除了拆分出常用词外,还删除了介词,以及拆分出单字也有意义的词,比如“摸”,”鱼“这类单独的动词或者名词。对于采用这类分词器的索引,在查询时如果输入”今“或者”天“这样的词是无法查询出对应的索引的,因为分词里没有包含这两个单字。如果输入”摸鱼“,”度过“这样分词的则可以查询出来。

值得一提的是,对于查询时的字符串也会进行一次分词,然后对这个分词与索引里的对应的字符串分词进行匹配,比如对于刚才的查询语句,输入“天”查不到任何东西,输入“也摸鱼”则可以查询出对应的索引。那么输入“天也摸鱼”时实际上也可以查询出对应的索引,原因就是对查询时的字符串分词后出现了”天“、”也“、”摸鱼“这三个词,进行匹配后返回了对应的索引。

3.对索引指定分词器

以上分区器就已经可以完全使用了,然而对于索引而言其默认分词器依然为standard,如果想让新的索引使用ik的话则必须要进行单独的配置。对此有两种方法,一种是只改对应的某几个索引的字段采取分词器,这种情况适用于多语言的索引,对每种语言单独配置分词器。另一种直接设置默认分词器,在设置之后,新加入的所有索引都会默认采用ik作为分词器,下面分别介绍两种的配置。

1)字段单独指定分词器
在建立索引时,比如

PUT 127.0.0.1/testIndex/myType/_mapping
JSON
{
		"myType":{
			"properties":{
			"tag":{
				"type":"string",
				"analyzer":"ik_max_word"
			}
		}
		}
}

其中testIndex是索引名,myType是该索引的一个type名,tag是其中一个属性,执行该命令后tag这个属性的分词就会采用ik分词

不过要注意一点,对于已建好的属性是无法修改的,要想修改以前的属性只能重新建立索引导入原来的数据。
2)设置默认分词为ik
对于2.X版本中可以直接在对应的elasticsearch.yml里进行如下配置

index.analysis.analyzer.default.type: ik
#如果修改后启动报错请检查ik名是否跟你之前配置的ik名称一致

之后所有新的索引都会自动配置为ik作为分词器,然而跟上面的方法一样,都无法让之前的数据使用ik分词,依然只能重新导入。

对于5.X版本不支持yml配置,启动时会直接告诉你请采用curl修改setting配置来实现默认ik的分词(这种方式对2.X版本依然有效)

PUT http://10.88.2.119:9200/indexName/
{
   "settings": {
    "analysis": {
      "analyzer": {
      	"default":{
      		"type":"ik_max_word"
      }
      }
    }
  }
}

顺带一提对于setting的配置可以随时更改,无需新建新的索引,代码如下:

PUT 127.0.0.1:9200/indexName/_settings
{
	"settings": {
    "analysis": {
      "analyzer": {
      	"default":{
      		"type":"standard"
      }
      }
    }
  }
}

如果报错提示index已存在,需要在修改settings之前,执行POST 127.0.0.1:9200/indexName/_close关闭索引,然后执行完修改settings之后,再执行POST 127.0.0.1:9200/indexName/_open打开索引即可。

4.配置英文词过滤

以上已经完成了所需的中文分词功能,这里单独提到的英文词过滤是因为ik对于英文分词仅限于根据空格等分隔符来区分出单词来,然后转化为小写,而没有进行进一步的筛选,比如对于english分词器,对于“He likes she",会拆分成"he",“like”,“she”,注意这里拆分出来的是”like“而不是”likes"。然而使用ik分词,则会出现"he",“likes”,“she”,这就意味着查询时输入like是查询不出这条语句的,必须查询likes。为了解决这个问题,我采用的是

http://www.360doc.com/content/16/1017/14/29098895_599094191.shtml

提到的将中文分词与英文过滤混合的方式,配置时如下配置:

 index: 
  analysis: 
   analyzer: 
    default:
      type: custom
      tokenizer: ik_max_word
      filter: ["stemmer"]

当然写成

index.analysis.analyzer.default.type: custom
index.analysis.analyzer.default.tokenizer: ik_max_word
index.analysis.analyzer.default.filter: ["stemmer"]

也是没问题的,不过我喜欢前一种方法,看起来更直观一些。

如果使用settings

"settings": {
    "analysis": {
      "analyzer": {
      	"default":{
      		"type":"custom",
      		"tokenizer":"ik_max_word",
      		"filter":["stemmer"]
      }
      }
    }
  }

在进行这样的配置之后ik的分词对于加了s之类的单词也能正确分词了~

5.补充:以模板方式自动配置索引分词器

在采用5.X版本的时候,如果不想每次都提前建立索引再存数据的话,可以使用ES的template模板来实现自动配置,代码如下:

PUT 127.0.0.1:9200/_template/myTemplate
{
	"template":"my-log-*",
        "settings": {
            "index": {
                "number_of_shards": "3",
		    "analysis": {
		      "analyzer": {
		      	"default":{
		      		"type":"custom",
		      		"tokenizer":"ik_max_word",
		      		"filter":["stemmer"]
		      }
            }
		    }
        }
}
}

其作用时在每次加入新索引的时候,检测索引的名字是否匹配"template"属性里的名字,这里的时my-log-*,那么像my-log-2018-10-12这样的带有my-log-前缀的就会自动采用这个模板里的设置。顺带一提的是,这个模板除了配置setting也可以配置mapping,具体内容实际上和新建index的时候一样,可以说是很方便了。

总结

以上就是ES的中文分词的配置,其实弄懂了还是很简单的,只不过2.X版本跳到5.X版本是真的坑,总会出现一些莫名其妙的错误,顺带吐槽一下5.X不支持yml配置默认分词器好坑啊……

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值