Elasticsearch入门之从零开始安装ik分词器

Stella981
• 阅读 494

Elasticsearch入门之从零开始安装ik分词器

起因

需要在ES中使用聚合进行统计分析,但是聚合字段值为中文,ES的默认分词器对于中文支持非常不友好:会把完整的中文词语拆分为一系列独立的汉字进行聚合,显然这并不是我的初衷。我们来看个实例:

POST http://192.168.80.133:9200/my_index_name/my_type_name/_search
{
    "size": 0,
    "query" : {
        "range" : {
            "time": {
                "gte": 1513778040000,
                "lte": 1513848720000
            }
        }
    },
    "aggs": {
        "keywords": {
            "terms": {"field": "keywords"},
            "aggs": {
                "emotions": {
                    "terms": {"field": "emotion"}
                }
            }
        }    
    }
}

输出结果:

{
    "took": 22,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
        "total": 32,
        "max_score": 0.0,
        "hits": []
    },
    "aggregations": {
        "keywords": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
                {
                    "key": "力",  # 完整的词被拆分为独立的汉字
                    "doc_count": 2,
                    "emotions": {
                        "doc_count_error_upper_bound": 0,
                        "sum_other_doc_count": 0,
                        "buckets": [
                            {
                                "key": -1,
                                "doc_count": 1
                            },
                            {
                                "key": 0,
                                "doc_count": 1
                            }
                        ]
                    }
                },
                {
                    "key": "动",
                    "doc_count": 2,
                    "emotions": {
                        "doc_count_error_upper_bound": 0,
                        "sum_other_doc_count": 0,
                        "buckets": [
                            {
                                "key": -1,
                                "doc_count": 1
                            },
                            {
                                "key": 0,
                                "doc_count": 1
                            }
                        ]
                    }
                }
            ]
        }
    }
}

既然ES的默认分词器对于中文支持非常不友好,那么有没有可以支持中文的分词器呢?如果有,该如何使用呢? 第一个问题,万能的谷歌告诉了我结果,已经有了支持中文的分词器,而且是开源实现:IK Analysis for Elasticsearch,详见:https://github.com/medcl/elasticsearch-analysis-ik。 秉着“拿来主义”不重复造轮子的指导思想,直接先拿过来使用一下,看看效果怎么样。那么,如何使用IK分词器呢?其实这是一个ES插件,直接安装并对ES进行相应的配置即可。

安装IK分词器

我的ES版本为2.4.1,需要下载的IK版本为:1.10.1(注意:必须下载与ES版本对应的IK,否则不能使用)。

1.下载,编译IK

wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v1.10.1/elasticsearch-analysis-ik-1.10.1.zip
unzip elasticsearch-analysis-ik-1.10.1.zip
cd elasticsearch-analysis-ik-1.10.1
mvn clean package

在elasticsearch-analysis-ik-1.10.1\target\releases目录下生成打包文件:elasticsearch-analysis-ik-1.10.1.zip。

2.在ES中安装IK插件

将上述打包好的IK插件:elasticsearch-analysis-ik-1.10.1.zip拷贝到ES/plugins目录下,执行解压。

unzip elasticsearch-analysis-ik-1.10.1.zip
rm -rf elasticsearch-analysis-ik-1.10.1.zip # 解压完之后一定要删除这个zip包,否则在启动ES时报错

重启ES。

使用IK分词器

安装IK分词器完毕之后,就可以在ES使用了。

第一步:新建index

PUT http://192.168.80.133:9200/my_index_name

第二步:给将来要使用的doc字段添加mapping 在这里我在ES中存储的doc格式如下:

{
    "nagtive_kw": []
    "is_all": false,
    "emotion": 0,
    "focuce": false,
    "keywords": ["动力","外观","油耗"],  // 在keywords字段上进行聚合分析
    "source": "汽车之家",
    "time": -1,
    "machine_emotion": 0,
    "title": "no title",
    "spider": "qczj_index",
    "content": {},
    "url": "http://xxx",
    "brand": "宝马",
    "series": "宝马1系",
    "model": "2017款"
}

需要在keywords字段上进行聚合分析,所以给keywords字段添加mapping设置:

POST http://192.168.80.133:9200/my_index_name/my_type_name/_mapping
{
    "properties": {
        "keywords": { # 设置keywords字段使用ik分词器
            "type": "string",
            "store": "no",
            "analyzer": "ik_smart",
            "search_analyzer": "ik_smart",
            "boost": 8
        }
    }
}

注意: 在设置mapping时有一个小插曲,我根据IK的官网设置“keywords”的type为“text”时报错:

POST http://192.168.80.133:9200/my_index_name/my_type_name/_mapping
{
    "properties": {
        "keywords": {
            "type": "text", # text类型在2.4.1版本中不支持
            "store": "no",
            "analyzer": "ik_smart",
            "search_analyzer": "ik_smart",
            "boost": 8
        }
    }
}

报错:

{
    "error": {
        "root_cause": [
            {
                "type": "mapper_parsing_exception",
                "reason": "No handler for type [text] declared on field [keywords]"
            }
        ],
        "type": "mapper_parsing_exception",
        "reason": "No handler for type [text] declared on field [keywords]"
    },
    "status": 400
}

这是因为我使用的ES版本比较低:2.4.1,而text类型是ES5.0之后才添加的类型,所以不支持。在ES2.4.1版本中需要使用string类型。

第三步:添加doc对象

POST http://192.168.80.133:9200/my_index_name/my_type_name/
{
    "nagtive_kw": ["动力","外观","油耗"]
    "is_all": false,
    "emotion": 0,
    "focuce": false,
    "keywords": ["动力","外观","油耗"],  // 在keywords字段上进行聚合分析
    "source": "汽车之家",
    "time": -1,
    "machine_emotion": 0,
    "title": "从动次打次吃大餐",
    "spider": "qczj_index",
    "content": {},
    "url": "http://xxx",
    "brand": "宝马",
    "series": "宝马1系",
    "model": "2017款"
}

第四步:聚合分析

POST http://192.168.80.133:9200/my_index_name/my_type_name/_search
{
    "size": 0,
    "query" : {
        "range" : {
            "time": {
                "gte": 1513778040000,
                "lte": 1513848720000
            }
        }
    },
    "aggs": {
        "keywords": {
            "terms": {"field": "keywords"},
            "aggs": {
                "emotions": {
                    "terms": {"field": "emotion"}
                }
            }
        }    
    }
}

输出结果:

{
    "took": 22,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
        "total": 32,
        "max_score": 0.0,
        "hits": []
    },
    "aggregations": {
        "keywords": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
                {
                    "key": "动力",     # 完整的词没有被拆分为独立的汉字
                    "doc_count": 2,
                    "emotions": {
                        "doc_count_error_upper_bound": 0,
                        "sum_other_doc_count": 0,
                        "buckets": [
                            {
                                "key": -1,
                                "doc_count": 1
                            },
                            {
                                "key": 0,
                                "doc_count": 1
                            }
                        ]
                    }
                }
            ]
        }
    }
}

【参考】 http://www.cnblogs.com/xing901022/p/5910139.html 如何在Elasticsearch中安装中文分词器(IK+pinyin) https://elasticsearch.cn/question/47 关于聚合(aggs)的问题 https://github.com/medcl/elasticsearch-analysis-ik/issues/276 create map时出现No handler for type [text] declared on field [content] #276 http://blog.csdn.net/guo_jia_liang/article/details/52980716 Elasticsearch2.4学习(三)------Elasticsearch2.4插件安装详解

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Stella981 Stella981
2年前
ElasticSearch(六):IK分词器的安装与使用IK分词器创建索引
之前我们创建索引,查询数据,都是使用的默认的分词器,分词效果不太理想,会把text的字段分成一个一个汉字,然后搜索的时候也会把搜索的句子进行分词,所以这里就需要更加智能的分词器IK分词器了。1\.ik分词器的下载和安装,测试第一:下载地址:https://github.com/medcl/elasticsearchanalysisi
Wesley13 Wesley13
2年前
unity将 -u4E00 这种 编码 转汉字 方法
 unity中直接使用 JsonMapper.ToJson(对象),取到的字符串,里面汉字可能是\\u4E00类似这种其实也不用转,服务器会通过类似fastjson发序列化的方式,将json转对象,获取对象的值就是中文但是有时服务器要求将传参中字符串中类似\\u4E00这种转汉字,就需要下面 publ
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这