1 ElasticSearch
1.1ElasticSearch介绍
1.1.1什么是ElasticSearch
Elasticsearch,简称为es, es是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。es也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。
1.1.2ElasticSearch使用案例
2013年初,GitHub抛弃了Solr,采取ElasticSearch 来做PB级的搜索。 “GitHub使用ElasticSearch搜索20TB 的数据,包括13亿文件和1300亿行代码”。
维基百科:启动以elasticsearch为基础的核心搜索架构。
SoundCloud:“SoundCloud使用ElasticSearch为1.8亿用户提供即时而精准的音乐搜索服务”。
百度:百度目前广泛使用ElasticSearch作为文本数据分析,采集百度所有服务器上的各类指标数据及用户自定义数据,通过对各种数据进行多维分析展示,辅助定位分析实例异常或业务层面异常。目前覆盖百度内部20多个业务线(包括casio、云分析、网盟、预测、文库、直达号、钱包、风控等),单集群最大100台机器,200个ES节点,每天导入30TB+数据新浪使用ES 分析处理32亿条实时日志。
阿里使用ES 构建挖财自己的日志采集和分析体系。
1.1.3ElasticSearch对比Solr
Solr 利用 Zookeeper 进行分布式管理,而 Elasticsearch 自身带有分布式协调管理功能;
Solr 支持更多格式的数据,而 Elasticsearch 仅支持json文件格式;Solr 官方提供的功能更多,而 Elasticsearch 本身更注重于核心功能,高级功能多有第三方插件提供;
Solr 在传统的搜索应用中表现好于 Elasticsearch,但在处理实时搜索应用时效率明显低于 Elasticsearch。
1.2ElasticSearch安装和启动
1.2.1ES下载
ElasticSearch分为Linux和Window版本,基于我们主要学习的是ElasticSearch的Java客户端的使用,所以我们课程中使用的是安装较为简便的Window版本,项目上线后,公司的运维人员会安装Linux版的ES供我们连接使用。
ElasticSearch的官方地址: https://www.elastic.co/products/elasticsearch
可以选择稍微往前一点的版本,比较稳定。
1.2.2安装ES
Window版的ElasticSearch的安装很简单,类似Window版的Tomcat,解压开即安装完毕,解压后的ElasticSearch 的目录结构如下:
修改elasticsearch配置文件:config/elasticsearch.yml,增加以下命令:
http.cors.enabled: true
http.cors.allow-origin: “*”
node.master: true
node.data: true
此步为允许elasticsearch跨越访问,后面安装head插件时使用。
1.2.3启动ES
点击ElasticSearch下的bin目录下的elasticsearch.bat启动,控制台显示的日志信息如下:
注意:ElasticSearch是使用java开发的,且本版本的es需要的jdk版本要是11以上,所以安装ElasticSearch之前保证JDK11+安装完毕,并正确的配置好JDK环境变量,否则启动ElasticSearch失败。
9300是tcp通讯端口,集群间和TCPClient都执行该端口,9200是http协议的RESTful接口 。通过浏览器访问ElasticSearch服务器,看到如下返回的json信息,代表服务启动成功:
1.3安装ES图形化界面插件
ElasticSearch不同于Solr自带图形化界面,我们可以通过安装ElasticSearch的head插件,完成图形化界面的效果,完成索引数据的查看。安装插件的方式有两种,在线安装和本地安装。本文档采用本地安装方式进行head插件的安装。
安装head需要安装node和grunt。
1.下载head插件:https://github.com/mobz/elasticsearch-head 在资料中已经提供了elasticsearch-head-master插件压缩包:
2.将elasticsearch-head-master压缩包解压到es安装目录内。
3.下载nodejs:https://nodejs.org/en/download/
4.安装node。双击安装。安装路径可配置,其他默认即可。安装完毕,可以通过cmd控制台输入:node -v 查看版本号
5.将grunt安装为全局命令 ,grunt是基于Node.js的项目构建工具在cmd控制台中输入如下执行命令:
grunt安装成功。
6. 进入elasticsearch-head-master目录启动head,在命令提示符下输入命令:
如果安装过程中,提示如下信息:
则按照提示,下载文件,放在指定目录即可。
按照提示操作完成以后,再次执行npm install。安装成功以后,提示如下信息:
7. 打开浏览器,输入 http://localhost:9100,看到如下页面:
如果不能成功连接到es服务,需要修改ElasticSearch的config目录下的配置文件:config/elasticsearch.yml,增加跨域访问的命令。重启ES.
1.4 ES相关概念
Elasticsearch是面向文档(document oriented)的,这意味着它可以存储整个对象或文档(document)。然而它不仅仅是存储,还会索引(index)每个文档的内容使之可以被搜索。在Elasticsearch中,你可以对文档(而非成行成列的数据)进行索引、搜索、排序、过滤。Elasticsearch比传统关系型数据库如下:
1.4.1索引
一个索引就是一个拥有几分相似特征的文档的集合。比如说,你可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引。一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。在一个集群中,可以定义任意多的索引。
1.4.2类型
在一个索引中,你可以定义一种或多种类型。一个类型是你的索引的一个逻辑上的分类/分区,其语义完全由你来定。通常,会为具有一组共同字段的文档定义一个类型。比如说,我们假设你运营一个博客平台并且将你所有的数据存储到一个索引中。在这个索引中,你可以为用户数据定义一个类型,为博客数据定义另一个类型,当然,也可以为评论数据定义另一个类型。
1.4.3字段
相当于是数据表的字段,对文档数据根据不同属性进行的分类标识
1.4.4映射
mapping是处理数据的方式和规则方面做一些限制,如某个字段的数据类型、默认值、分析器、是否被索引等等,这些都是映射里面可以设置的,其它就是处理es里面数据的一些使用规则设置也叫做映射,按着最优规则处理数据对性能提高很大,因此才需要建立映射,并且需要思考如何建立映射才能对性能更好。
1.4.5文档
一个文档是一个可被索引的基础信息单元。比如,你可以拥有某一个客户的文档,某一个产品的一个文档,当然,也可以拥有某个订单的一个文档。文档以JSON(Javascript Object Notation)格式来表示,而JSON是一个到处存在的互联网数据交互格式。
在一个index/type里面,你可以存储任意多的文档。注意,尽管一个文档,物理上存在于一个索引之中,文档必须被索引/赋予一个索引的type。
1.4.6.接近实时NRT
Elasticsearch是一个接近实时的搜索平台。这意味着,从索引一个文档直到这个文档能够被搜索到有一个轻微的延迟(通常是1秒以内)。
1.4.7集群cluster
一个集群就是由一个或多个节点组织在一起,它们共同持有整个的数据,并一起提供索引和搜索功能。一个集群由一个唯一的名字标识,这个名字默认就是“elasticsearch”。这个名字是重要的,因为一个节点只能通过指定某个集群的名字,来加入这个集群
1.4.8节点node
一个节点是集群中的一个服务器,作为集群的一部分,它存储数据,参与集群的索引和搜索功能。和集群类似,一个节点也是由一个名字来标识的,默认情况下,这个名字是一个随机的漫威漫画角色的名字,这个名字会在启动的时候赋予节点。这个名字对于管理工作来说挺重要的,因为在这个管理过程中,你会去确定网络中的哪些服务器对应于Elasticsearch集群中的哪些节点。
一个节点可以通过配置集群名称的方式来加入一个指定的集群。默认情况下,每个节点都会被安排加入到一个叫做“elasticsearch”的集群中,这意味着,如果你在你的网络中启动了若干个节点,并假定它们能够相互发现彼此,它们将会自动地形成并加入到一个叫做“elasticsearch”的集群中。
在一个集群里,只要你想,可以拥有任意多个节点。而且,如果当前你的网络中没有运行任何Elasticsearch节点,这时启动一个节点,会默认创建并加入一个叫做“elasticsearch”的集群。
1.4.9分片和复制 shards&replicas
一个索引可以存储超出单个结点硬件限制的大量数据。比如,一个具有10亿文档的索引占据1TB的磁盘空间,而任一节点都没有这样大的磁盘空间;或者单个节点处理搜索请求,响应太慢。为了解决这个问题,Elasticsearch提供了将索引划分成多份的能力,这些份就叫做分片。当你创建一个索引的时候,你可以指定你想要的分片的数量。每个分片本身也是一个功能完善并且独立的“索引”,这个“索引”可以被放置到集群中的任何节点上。分片很重要,主要有两方面的原因: 1)允许你水平分割/扩展你的内容容量。 2)允许你在分片(潜在地,位于多个节点上)之上进行分布式的、并行的操作,进而提高性能/吞吐量。
至于一个分片怎样分布,它的文档怎样聚合回搜索请求,是完全由Elasticsearch管理的,对于作为用户的你来说,这些都是透明的。
在一个网络/云的环境里,失败随时都可能发生,在某个分片/节点不知怎么的就处于离线状态,或者由于任何原因消失了,这种情况下,有一个故障转移机制是非常有用并且是强烈推荐的。为此目的,Elasticsearch允许你创建分片的一份或多份拷贝,这些拷贝叫做复制分片,或者直接叫复制。
复制之所以重要,有两个主要原因: 在分片/节点失败的情况下,提供了高可用性。因为这个原因,注意到复制分
片从不与原/主要(original/primary)分片置于同一节点上是非常重要的。扩展你的搜索量/吞吐量,因为搜索可以在所有的复制上并行运行。总之,每个索引可以被分成多个分片。一个索引也可以被复制0次(意思是没有复制)或多次。一旦复制了,每个索引就有了主分片(作为复制源的原来的分片)和复制分片(主分片的拷贝)之别。分片和复制的数量可以在索引创建的时候指定。在索引创建之后,你可以在任何时候动态地改变复制的数量,但是你事后不能改变分片的数量。
默认情况下,Elasticsearch中的每个索引被分片5个主分片和1个复制,这意味着,如果你的集群中至少有两个节点,你的索引将会有5个主分片和另外5个复制分片(1个完全拷贝),这样的话每个索引总共就有10个分片。
Restful风格:一种软件架构风格:提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
Put: localhost:9200/索引名称/类型名称/文档id ,创建文档,指定文档id
Post:localhost:9200/索引名称/类型名称 创建文档,随机文档id
put:localhost:9200/索引名称/类型名称/文档id/ 修改文档
Delete:localhost:9200/索引名称/类型名称/文档id 删除文档
Get:localhost:9200/索引名称/类型名称/文档id 查询文档通过文档id
Postman官网:https://www.postman.com
1.4 ES基本操作
1.4.1索引操作
1.创建索引:
PUT请求: http://localhost:9200/索引名称
URL: http://localhost:9200/shopping
创建成功,返回结果:
{
“acknowledged”: true,
“shards_acknowledged”: true,
“index”: “shopping”
}
如果索引已经存在,则失败。
2.查询索引:
提交方式:GET
URL:http://localhost:9200/shopping
查询返回的结果:
{
“shopping”: {
“aliases”: {},
“mappings”: {},
“settings”: {
“index”: {
“creation_date”: “1621561683252”,
“number_of_shards”: “1”,
“number_of_replicas”: “1”,
“uuid”: “8aPvd6VWRNaSWj-AzPBuAQ”,
“version”: {
“created”: “7070099”
},
“provided_name”: “shopping”
}
}
}
}
查询所有索引:
localhost:9200/_cat/indices?v
结果:
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
yellow open hello 0XNp9Kz6SYOur2e5A-oUlg 1 1 0 0 208b 208b
yellow open shopping FjN4rlKIRA66XlMlbMQHTw 1 1 0 0 208b 208b
3.删除索引
提交方式:delete
url: http://localhost:9200/shopping
{
“acknowledged”: true
}
删除成功
1.4.2文档操作
1.创建文档
请求方式:post
url : http://localhost:9200/索引名称/类型名称
请求体,传入属性,JSON格式,相当于一个条记录(一个对象),这样会自动生成id
也可以在创建的时候指定id
创建成功
{
“_index”: “shopping”,
“_type”: “user”,
“_id”: “1002”,
“_version”: 1,
“result”: “created”,
“_shards”: {
“total”: 2,
“successful”: 1,
“failed”: 0
},
“_seq_no”: 2,
“_primary_term”: 1
}
第一个没有指定id,自动生成。第二个指定id创建文档1001.
2.查询文档
(1)通过id查询:
请求方式:GET
url:http://localhost:9200/索引名称/类型名称/文档id
结果:
{
“_index”: “shopping”,
“_type”: “user”,
“_id”: “1002”,
“_version”: 1,
“_seq_no”: 2,
“_primary_term”: 1,
“found”: true,
“_source”: {
“name”: “wangwu”,
“age”: 30,
“email”: “wangwu@163.com”
}
}
3.查询所有:
请求方式:GET
URL:http://localhost:9200/索引名称/类型名称/_search
请求体:没有。
查询user类型的所有文档。
查询结果:
{
“took”: 5,
“timed_out”: false,
“_shards”: {
“total”: 1,
“successful”: 1,
“skipped”: 0,
“failed”: 0
},
“hits”: {
“total”: {
“value”: 2,
“relation”: “eq”
},
“max_score”: 1.0,
“hits”: [
{
“_index”: “shopping”,
“_type”: “user”,
“_id”: “_9Lkm3kB9yWhVyWTuSQY”,
“_score”: 1.0,
“_source”: {
“name”: “rose”,
“age”: 20,
“email”: “rose@163.com”
}
},
{
“_index”: “shopping”,
“_type”: “user”,
“_id”: “1001”,
“_score”: 1.0,
“_source”: {
“name”: “jack”,
“age”: 30,
“email”: “jack@163.com”
}
}
]
}
}
也可以通过url:http://localhost:9200/索引名称/_search
查询当前索引下的文档。
4.删除文档:
(1)根据id删除:
提交方式:delete
url:http://localhost:9200/索引名称/类型名称/文档id
![](https://img-blog.csdnimg.cn/20210527153256376.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MDY5OTgzMw==,size_16,color_FFFFFF,t_70
5.修改文档:
(1)通过id更新
提交方式:put
url: http://localhost:9200/索引名称/类型名称/文档id
请求体:
{
“name”:“jack”,
“age” : 18,
“email”:“jack@163.com”
}
结果:
{
“_index”: “shopping”,
“_type”: “user”,
“_id”: “1001”,
“_version”: 9,
“result”: “updated”,
“_shards”: {
“total”: 2,
“successful”: 1,
“failed”: 0
},
“_seq_no”: 14,
“_primary_term”: 1
}
根据id查询,检验是否更新成功:
查询结果:
{
“_index”: “shopping”,
“_type”: “user”,
“_id”: “1001”,
“_version”: 9,
“_seq_no”: 14,
“_primary_term”: 1,
“found”: true,
“_source”: {
“name”: “jack”,
“age”: 18,
“email”: “jack@163.com”
}
}
(2)url同更新,请求方式使用POST,如果id已经存在,则更新,如果id不存在,则创建。
1.4.3查询操作
1.条件查询
提交方式:GET
URL: localhost:9200/hello/_search?q=name:rose
结果:
“hits”: [
{
“_index”: “shopping”,
“_type”: “user”,
“_id”: “1002”,
“_score”: 1.2648118,
“_source”: {
“name”: “rose”,
“age”: 24,
“email”: “rose@126.com”
}
},
{
“_index”: “shopping”,
“_type”: “user”,
“_id”: “1006”,
“_score”: 0.99270093,
“_source”: {
“name”: “rose 222”,
“age”: 35,
“email”: “rose222@126.com”
}
}
]
这里的查询条件不是完全匹配,只要name中包含rose这个词就行了。英文的词是通过空格分开的。
2.条件查询的其它形式:在请求体中提交查询条件
提交方式:GET或者POST都可以
提交参数:查询条件,JSON格式。名字中包含rose这个单词的都可以。
*{
“query”:{
“match”:{
“name”:“rose”
}
}
}
查询结果:
如果想要查询user类型的所有文档,可以将请求体改为如下内容。
{
“query”:{
“match_all”:{}
}
}*
3.分页查询:
提交方式:GET或者POST
请求体:
{
“query”:{
“match_all”:{
}
},
"from":0,
"size":2
}
结果:
“hits”: [
{
“_index”: “shopping”,
“_type”: “user”,
“_id”: “1001”,
“_score”: 1.0,
“_source”: {
“name”: “rose”,
“age”: 23,
“email”: “rose@163.com”
}
},
{
“_index”: “shopping”,
“_type”: “user”,
“_id”: “1002”,
“_score”: 1.0,
“_source”: {
“name”: “jack”,
“age”: 25,
“email”: “jack@163.com”
}
}
]
如果只想获取name的值,可以在请求体中添加条件:
{
“query”:{
“match_all”:{
}
},
"from":2,
"size":2,
"_source":["name"]
}
结果:
“hits”: [
{
“_index”: “shopping”,
“_type”: “user”,
“_id”: “1003”,
“_score”: 1.0,
“_source”: {
“name”: “tom”
}
},
{
“_index”: “shopping”,
“_type”: “user”,
“_id”: “1004”,
“_score”: 1.0,
“_source”: {
“name”: “jerry”
}
}
]
4.排序查询
请求体中添加排序的规则:
{
“query”:{
“match_all”:{
}
},
"from":0,
"size":5,
"_source":["name"],
"sort":{
"age":{
"order":"desc"
}
}
}
查询结果:
“hits”: [
{
“_index”: “shopping”,
“_type”: “user”,
“_id”: “1002”,
“_score”: null,
“_source”: {
“name”: “jack”,
“age”: 25,
“email”: “jack@163.com”
},
“sort”: [
25
]
},
{
“_index”: “shopping”,
“_type”: “user”,
“_id”: “1001”,
“_score”: null,
“_source”: {
“name”: “rose”,
“age”: 23,
“email”: “rose@163.com”
},
“sort”: [
23
]
}
]
5.多条件查询:
请求体:
{
“query”:{
“bool”:{
“must”:[
{
“match”:{
“name”:“李四”
}
},
{
“match”:{
“age”:30
}
}
]
}
}
}
Must:相当于and
Should:相当于or
范围查询
{
“query”:{
“bool”:{
“must”:[
{
“match”:{
“name”:“李四”
}
},
{
“match”:{
“age”:30
}
}
],
“filter”:{
“range”:{
“age”:{
“gt”:30
}
}
}
}
}
}
6.完全匹配:
如果直接写match本身不是必须要完成匹配,会对name的值进行分词,只要满足每一个词的要求,都能查到。
{
“query”:{
“match”:{
“name”:“rose”
}
}
}
查询结果:
“hits”: [
{
“_index”: “shopping”,
“_type”: “user”,
“_id”: “1001”,
“_score”: 1.093527,
“_source”: {
“name”: “rose”,
“age”: 23,
“email”: “rose@163.com”
}
},
{
“_index”: “shopping”,
“_type”: “user”,
“_id”: “1006”,
“_score”: 0.79679096,
“_source”: {
“name”: “rose 222”,
“age”: 64,
“email”: “rose222@126.com”
}
}
]
如果请求体如下:
{
“query”:{
“match”:{
“name”:“三四”
}
}
}
查询结果:
“hits”: [
{
“_index”: “shopping”,
“_type”: “user”,
“_id”: “1007”,
“_score”: 1.5108216,
“_source”: {
“name”: “张三”,
“age”: 30,
“email”: “zhangsan@138.com”
}
},
{
“_index”: “shopping”,
“_type”: “user”,
“_id”: “1008”,
“_score”: 1.5108216,
“_source”: {
“name”: “李四”,
“age”: 35,
“email”: “lisi@138.com”
}
}
]
如果想要完全匹配,使用match_phrase即可:
{
“query”:{
“match_phrase”:{
“name”:“三四”
}
}
}
7.高亮显示:
请求体如下:
{
“query”:{
“match_phrase”:{
“name”:“李四”
}
},
“highlight”:{
“fields”: {
“name”:{}
}
}
}
查询结果:
“hits”: [
{
“_index”: “shopping”,
“_type”: “user”,
“_id”: “1008”,
“_score”: 3.0216432,
“_source”: {
“name”: “李四”,
“age”: 35,
“email”: “lisi@138.com”
},
“highlight”: {
“name”: [
“李四”
]
}
}
]
8.分组查询
{
“aggs”:{
“name_group”:{
“terms”:{
“field”:“name.keyword”
}
}
}
}
根据名字分组查询。
计算年龄的平均值:
{
“aggs”:{
“age_avg”:{
“avg”:{
“field”:“age”
}
}
}
}
查询结果:
{
“aggs”:{
“age_avg”:{
“avg”:{
“field”:“age”
}
}
}
}
1.5分词
1.5.1IK分词器的集成
IK分词器:将中文分成词组
ES默认使用标准分词器:standard分词则会将每个中文分成一个单个的词:
优劣:IK 分词能够根据词库创建有效的分词索引,搜索的效率和准确率很高。劣势:有小部分词如果不存在词库,则不会被分词,因此在查询的时候,可能目标文本存在此词,但是分词分不出这词,则查询结果将为空。
优劣:standard分词是根据每个汉字进行的分词,因此 优势就是,IK存在的问题,将不会出现在standard分词上面,但是劣势更加明显,第一:搜索引擎的文本样例基本都是千万级,亿级数据,每字均创建索引,索引区会很大。第二:查询结果如果是match则会出现非常大的干扰型数据,且相关性的排序会不理想。特别是完全匹配跟部分匹配的排序非常糟糕(可能可以通过查询优化)。
查看分词效果:
POST请求,请求参数添加分词器和文本内容。
分词结果:
{
“tokens”: [
{
“token”: “天”,
“start_offset”: 0,
“end_offset”: 1,
“type”: “”,
“position”: 0
},
{
“token”: “津”,
“start_offset”: 1,
“end_offset”: 2,
“type”: “”,
“position”: 1
},
{
“token”: “市”,
“start_offset”: 2,
“end_offset”: 3,
“type”: “”,
“position”: 2
},
{
“token”: “大”,
“start_offset”: 3,
“end_offset”: 4,
“type”: “”,
“position”: 3
},
{
“token”: “学”,
“start_offset”: 4,
“end_offset”: 5,
“type”: “”,
“position”: 4
},
{
“token”: “软”,
“start_offset”: 5,
“end_offset”: 6,
“type”: “”,
“position”: 5
},
{
“token”: “件”,
“start_offset”: 6,
“end_offset”: 7,
“type”: “”,
“position”: 6
},
{
“token”: “学”,
“start_offset”: 7,
“end_offset”: 8,
“type”: “”,
“position”: 7
},
{
“token”: “院”,
“start_offset”: 8,
“end_offset”: 9,
“type”: “”,
“position”: 8
}
]
}
IK分词器的网址:https://github.com/medcl/elasticsearch-analysis-ik
Ik分词器的版本,需要与es版本一致。
在es的plugins文件夹下创建ik文件夹,将ik分词器的压缩文件解压以后,放入plugins的ik文件夹下,然后重启es即可。
Ik分词器提供了两个分词算法:ik_smart和ik_max_word
其中,ik_smart为最少切分,ik_max_word为最细粒度划分。
测试:
测试结果:
{
“tokens”: [
{
“token”: “天津市”,
“start_offset”: 0,
“end_offset”: 3,
“type”: “CN_WORD”,
“position”: 0
},
{
“token”: “大学”,
“start_offset”: 3,
“end_offset”: 5,
“type”: “CN_WORD”,
“position”: 1
},
{
“token”: “软件”,
“start_offset”: 5,
“end_offset”: 7,
“type”: “CN_WORD”,
“position”: 2
},
{
“token”: “学院”,
“start_offset”: 7,
“end_offset”: 9,
“type”: “CN_WORD”,
“position”: 3
}
]
}
测试最细力度拆分:
测试结果:
{
“tokens”: [
{
“token”: “天津市”,
“start_offset”: 0,
“end_offset”: 3,
“type”: “CN_WORD”,
“position”: 0
},
{
“token”: “天津”,
“start_offset”: 0,
“end_offset”: 2,
“type”: “CN_WORD”,
“position”: 1
},
{
“token”: “津市”,
“start_offset”: 1,
“end_offset”: 3,
“type”: “CN_WORD”,
“position”: 2
},
{
“token”: “大学”,
“start_offset”: 3,
“end_offset”: 5,
“type”: “CN_WORD”,
“position”: 3
},
{
“token”: “软件”,
“start_offset”: 5,
“end_offset”: 7,
“type”: “CN_WORD”,
“position”: 4
},
{
“token”: “学院”,
“start_offset”: 7,
“end_offset”: 9,
“type”: “CN_WORD”,
“position”: 5
}
]
}
1.5.2通过映射指定分词器
{
“mappings”:{
“product”:{
“properties”:{
“id”:{
“type”:“long”,
“store”:true,
“analyzer”:“ik_smart”
},
“name”:{
“type”:“text”,
“store”:true,
“analyzer”:“ik_smart”
}
}
}
}
}
1.6ES集群搭建
1.6.1ES集群搭建
搭建包含3个节点的集群。
1.关闭ES服务。
2.删除ES文件夹下的data。
3.复制三份ES文件夹,改名如下:
分别修改节点的配置文件如下:
节点一的配置:”
#节点一的配置信息
#集群名称,唯一的
cluster.name: my-elasticsearch
#节点名称,不一样
node.name: node-1
#ip地址
network.host: 127.0.0.1
#服务端口号,在同一机器下不一样
http.port: 9201
#集群间通信端口,在同一机器下必须不一样
transport.tcp.port: 9301
#设置集群自动发现机器ip集合
discovery.zen.ping.unicast.hosts: [“127.0.0.1:9301”,“127.0.0.1:9302”,“127.0.0.1:9303”]
#配置主节点
cluster.initial_master_nodes: [“node-1”]
节点二的配置:
#节点2的配置信息
#集群名称,唯一的
cluster.name: my-elasticsearch
#节点名称,不一样
node.name: node-2
#ip地址
network.host: 127.0.0.1
#服务端口号,在同一机器下不一样
http.port: 9202
#集群间通信端口,在同一机器下必须不一样
transport.tcp.port: 9302
#设置集群自动发现机器ip集合
discovery.zen.ping.unicast.hosts: [“127.0.0.1:9301”,“127.0.0.1:9302”,“127.0.0.1:9303”]
#配置主节点
cluster.initial_master_nodes: [“node-1”]
节点三的配置:
#节点3的配置信息
#集群名称,唯一的
cluster.name: my-elasticsearch
#节点名称,不一样
node.name: node-3
#ip地址
network.host: 127.0.0.1
#服务端口号,在同一机器下不一样
http.port: 9203
#集群间通信端口,在同一机器下必须不一样
transport.tcp.port: 9303
#设置集群自动发现机器ip集合
discovery.zen.ping.unicast.hosts: [“127.0.0.1:9301”,“127.0.0.1:9302”,“127.0.0.1:9303”]
#配置主节点
cluster.initial_master_nodes: [“node-1”]
分别启动三个节点:
在主节点的日志信息会看到如下:
代表集群已经启动,node-1为主节点。
1.6.2集群测试
通过header工具连接集群,随便连接某一个节点,可以看到如下界面
6MQ