IK 分词器 #
IK 分词器是一款专为处理中文文本设计的分词器,高效且智能。支持 ik_smart
和 ik_max_word
两种分词模式。
使用样例 #
Easysearch 内置了 IK 分词器,用户可以直接在分词配置中使用 IK 的分词模式。
# 1.创建索引
PUT index_ik
# 2.创建映射关系
POST index_ik/_mapping
{
"properties": {
"content": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
}
}
}
# 3.写入文档
POST index_ik/_create/1
{"content":"美国留给伊拉克的是个烂摊子吗"}
POST index_ik/_create/2
{"content":"公安部:各地校车将享最高路权"}
POST index_ik/_create/3
{"content":"中韩渔警冲突调查:韩警平均每天扣1艘中国渔船"}
POST index_ik/_create/4
{"content":"中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"}
# 4.高亮查询
POST index_ik/_search
{
"query" : { "match" : { "content" : "中国" }},
"highlight" : {
"pre_tags" : ["<tag1>", "<tag2>"],
"post_tags" : ["</tag1>", "</tag2>"],
"fields" : {
"content" : {}
}
}
}
# 返回内容
{
"took": 14,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 2,
"hits": [
{
"_index": "index",
"_type": "fulltext",
"_id": "4",
"_score": 2,
"_source": {
"content": "中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"
},
"highlight": {
"content": [
"<tag1>中国</tag1>驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首 "
]
}
},
{
"_index": "index",
"_type": "fulltext",
"_id": "3",
"_score": 2,
"_source": {
"content": "中韩渔警冲突调查:韩警平均每天扣1艘中国渔船"
},
"highlight": {
"content": [
"均每天扣1艘<tag1>中国</tag1>渔船 "
]
}
}
]
}
}
关于 ik_smart 和 ik_max_word #
ik_smart
和 ik_max_word
是 IK 分词器的两个分词模式。
ik_max_word:将文本根据词典内容做最细粒度的切分。例如,ik_max_word 会将”中华人民共和国国歌”切分到“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国、共和,和,国国,国歌”,详尽生成各种可能的组合。
ik_smart:执行文本粗粒度的切分。例如:ik_smart 会把 ”中华人民共和国国歌”到“中华人民共和国,国歌”。
ik_smart 比较适合短语查询,而 ik_max_word 更合适精准匹配。值得注意的是,由于 ik_smart 做了分词切割的优化,其的分词结果并不是 ik_max_word 的分词结果的子集。
字段级别词典设置 #
Easysearch 1.10 版本在 IK 分词器原有的功能上增加了自定义字段级别词典的功能。
自定义字段级别词典的功能支持用户对不同的字段设置不同的分词词库,用户既可以指定 IK 完全使用自有的词库,也支持在 IK 默认的词库上增加自定义的词库内容。
自定义词库内容 #
默认的词库索引是 .analysis_ik 索引,IK 插件自动初始化的 .analysis_ik 索引。
用户可以自定义使用某个索引替代 .analysis_ik(设置参数下面会提及),但是要保持和 .analysis_ik 一个的 mapping 结构和使用预设的 pipeline:ik_dicts_default_date_pipeline。
.analysis_ik 词库需要存储的格式如下:
POST .analysis_ik/_doc
{
"dict_key": "test_dic",
"dict_type": "main_dicts",
"dict_content": "dict_content": """中华人民共和国
中文万岁
秋水共长天"""
}
主要使用字段
- dict_content:词典内容字段。各个词典以换行符分隔。
- dict_key:自定义词典名。对应自定义词典中设置的 dict_key。
- dict_type:字典类型,可选 “main_dicts”, “stopwords_dicts”, “quantifier_dicts” 三个值。其中任意 dict_key 的"main_dicts"必须存在。
设置自定义词库 #
自定义词库的生效主要通过自定义 tokenizer 进行设置。
PUT my-index-000001
{
"settings": {
"analysis": {
"analyzer": {
"my_custom_analyzer": {
"type": "custom",
"tokenizer": "my_tokenizer"
}
},
"tokenizer": {
"my_tokenizer": {
"type": "ik_max_word",
"custom_dict_enable": true,
"load_default_dicts":true,
"lowcase_enable": true,
"dict_key": "test_dic",
"dict_index":"custom_index"
}
}
}
},
"mappings": {
"properties": {
"test_ik": {
"type": "text",
"analyzer": "my_custom_analyzer"
}
}
}
}
其中
- custom_dict_enable:布尔值,默认 false,true 则可以定制词典读取路径,否则 load_default_dicts / dict_key / dict_index 均失效。
- load_default_dicts:布尔值,默认 true,定制的词典是否包含默认的词典库。
- lowcase_enable:布尔值,默认为 true,是否大小写敏感,false 则保留原来文本的大小写。
- dict_key:string。对应词库索引中的 dict_key 字段内容。如果词典名不匹配,则会装载错误或者直接报错 。
- dict_index: string。词库索引名称,默认是 .analysis_ik。可以自定义,但是要保持和 mapping 结构以及 pipeline 一致。
词库内容更新 #
词库现阶段只接受追加内容,没有删除词库数据的功能。如果在同一条数据上进行修改则也被视为追加。暂时不建议对词库内容进行删除或者修改,可能会造成节点间词库的混乱。
词库的追加内容是能自动被程序探测的,这个主要依赖于 .analysis_ik 的时间戳字段和 pipeline 执行。
# 词典索引写入需要的默认时间戳 pipeline
GET _ingest/pipeline/ik_dicts_default_date_pipeline
{
"ik_dicts_default_date_pipeline": {
"processors": [
{
"set": {
"field": "upload_dicts_timestamp",
"value": "{{_ingest.timestamp}}",
"override": true
}
}
]
}
}
# 词典索引的结构
GET .analysis.ik
{
".analysis.ik": {
"aliases": {},
"mappings": {
"properties": {
"dict_content": {
"type": "text",
"analyzer": "custom_analyzer"
},
"dict_key": {
"type": "keyword"
},
"dict_type": {
"type": "keyword"
},
"upload_dicts_timestamp": {
"type": "date"
}
}
},
"settings": {
"index": {
"number_of_shards": "1",
"provided_name": ".analysis.ik",
"default_pipeline": "ik_dicts_default_date_pipeline",
"analysis": {
"analyzer": {
"custom_analyzer": {
"type": "custom",
"tokenizer": "pattern_tokenizer"
}
},
"tokenizer": {
"pattern_tokenizer": {
"pattern": "\n",
"type": "pattern"
}
}
},
"number_of_replicas": "1"
}
}
}
}
这里 ik_dicts_default_date_pipeline 会对每一条写入词库的数据赋予当前 upload_dicts_timestamp 时间戳。ik 会记录当前词库的最大时间戳,然后每分钟都会去查询一次词库索引现有的最大时间戳。如果查到词库索引的最大的时间戳大于上次记录到的时间戳,则对这段时间内的词库内容都进行加载。