ElasticSearch学习笔记
Posted 程程有小棉被啊__
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ElasticSearch学习笔记相关的知识,希望对你有一定的参考价值。
一、ElasticSearch相关概念
1.1、基本概念
ES是面向文档(Document)的,他可以存储整个对象或文档Document。还会索引(index)每个文档的内容,让其可以被搜索。在ES中,可以对Document进行索引,搜索,排序,过滤。ES对比mysql:
MySQL ->DataBases ->Tables->Rows->Columns
ElasticSearch->Indices->Types->Documents->Fields
1.2、核心概念
2.1、index索引(database)
ElasticSearch索引的精髓:一切设计都是为了提高搜索的性能。万物皆可索引!
一个索引就是一个拥有几分相似特征的文档集合,例如,你可以有一个客户数据的索引,还可以有订单数据的索引。一个索引由一个名字来标识,并且当对某个索引中的文档进行索引,搜索,更新,删除时都需要用到这个索引的名字。在一个集群中,可以定义任意多的索引。索引(index)类似于MySQL中的数据库(database)。
2.2、type类型(table)
在一个索引中,可以定义一种或多种类型。一个类型是该索引的一个逻辑上的分类/分区,通常,会为具有一组共同字段的文档定义一个类型。例如,我们可以把OA系统中所有的数据都存在一个index中,在这个index中,可以为考勤数据定义一个类型,报销数据定义一个类型,人员信息定义一个类型。类型(type)类似于MySQL中的表(table)
从7.x版本后,默认不再支持自定义索引类型(默认类型为:_doc)
2.3、filed字段
相当于数据表中的字段,对文档数据根据不同属性进行分类标识。字段(filed)类似MySQL中的字段
2.4、Mapping映射
mapping是处理数据的方式和规则方面做的一些限制,例如,对某个字段的数据类型,默认值,分析器,是否被索引等等,类似于MySQL建表时对每个字段设置类型,主键,外键等
2.5、Document文档
一个文档是一个可被索引的基础信息单元,类似于MySQL中的一条数据,你可以有一个员工的document,该员工的某个角色document。文档以JSON格式表示。在一个index/type里面,可以存储多个document。注意,尽管一个文档,物理上存在于一个索引中,但是文档必须被索引/赋予一个索引的type。
2.6、集群cluster
一个集群由一个或者多个节点组织在一起,他们共享整个数据,并一起提供索引和搜索服务。一个集群由一个唯一的名字标识,整个名字默认为“elasticsearch”。一个节点只能通过指定某个集群的名字来加入该集群。
2.7、节点node
一个节点是集群中的一个服务器,作为集群的一部分,他存储数据,参与集群的索引和搜索功能。和集群类似,一个节点也是由一个名字来标识,默认情况,这个名字是一个随机的漫威漫画角色的名字。这个名字会在启动的时候赋予节点。
一个节点可以通过配置集群名称的方式来加入一个指定的集群。默认情况下,每个节点都会被分配到“elasticsearch”的集群中。一个集群中可以有任意多的节点。
2.8、分片和副本shards&replicas
一个索引可以存储超出单个节点硬件限制的大量数据。例如,一个具有10亿文档的索引占据1TB的磁盘空间,而任一节点都1TB的磁盘空间,或者单个节点处理搜索请求,响应速度太慢。为了解决这个问题,ES提供了将索引划分为多份的能力,这些份就是分片shards。当创建一个索引的时候,可以指定想要分片的数量。每一个分片本身也是一个功能完善且独立的索引,这个索引可以被放置到集群中的任何节点上。
分片很重要,主要有两方面原因:
(1)允许你水平分割/扩展内容容量
(2)允许在分片(潜在的,位于多个节点上)进行分布式的并行操作,提高性能。至于分片如何分布,文档如何聚合都有ES管理。
在一个网络/云的环境里,失败随时都可能发生,在某个分片/节点不知怎么的就处于离线状态,或者由于任何原因消失了,这种情况下,有一个故障转移机制是非常有用并且是强烈推荐的。为此目的,Elasticsearch允许你创建分片的一份或多份拷贝,这些拷贝叫做复制分片,或者直接叫复制。
复制之所以重要,有两个主要原因: 在分片/节点失败的情况下,提供了高可用性。因为这个原因,注意到复制分片从不与原/主要(original/primary)分片置于同一节点上是非常重要的。扩展你的搜索量/吞吐量,因为搜索可以在所有的复制上并行运行。总之,每个索引可以被分成多个分片。一个索引也可以被复制0次(意思是没有复制)或多次。一旦复制了,每个索引就有了主分片(作为复制源的原来的分片)和复制分片(主分片的拷贝)之别。分片和复制的数量可以在索引创建的时候指定。在索引创建之后,你可以在任何时候动态地改变复制的数量,但是你事后不能改变分片的数量。
默认情况下,Elasticsearch中的每个索引被分片5个主分片和1个复制,这意味着,如果你的集群中至少有两个节点,你的索引将会有5个主分片和另外5个复制分片(1个完全拷贝),这样的话每个索引总共就有10个分片。
2.9、分配Allocation
将分片分配给某个节点的过程,包括分配主分片或者副本。如果是副本,还包含从主分片复制数据的过程。这个过程是否master节点完成的。
1.3、ES客户端操作
1、elasticsearch-head插件
2、elasticsearch提供的Restful接口直接访问
3、elasticsearch提供的API访问
4、kibana工具
二、ElasticSearch基础操作
2.1、索引操作
1、创建索引
对比关系型数据库,index就等同于创建database
向ES发送PUT请求:http://localhost:9200/shopping
2、查看索引
向ES发送GET请求:http://localhost:9200/shopping 查看当前shopping的索引信息
向ES发送GET请求:http://localhost:9200/_cat/indices?v 查看所有index信息
3、删除索引
向ES发送DELETE请求:http://localhost:9200/shopping 删除shopping索引
2.2、文档操作
1、创建文档
创建文档,并添加数据。文档相当于关系型数据库中的表数据,添加的数据格式为JSON格式。
(1)向ES发送POST请求:http://localhost:9200/shopping/_doc ES自动生成随机ID。重复请求,会添加多条数据
请求体内容为:
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":1999.00
添加成功返回内容:
"_index": "shopping",
"_type": "_doc",
"_id": "IacKhoUBQHPHVJzVREAO",
"_version": 1,
"result": "created",
"_shards":
"total": 2,
"successful": 1,
"failed": 0
,
"_seq_no": 0,
"_primary_term": 1
(2)向ES发送POST请求:http://localhost:9200/shopping/_doc/1001 ID为用户指定的1001。重复请求,会将ID为1001的数据进行更新操作。
请求体内容不变
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":1999.00
添加成功返回内容:
"_index": "shopping",
"_type": "_doc",
"_id": "1001",
"_version": 1,
"result": "created",
"_shards":
"total": 2,
"successful": 1,
"failed": 0
,
"_seq_no": 1,
"_primary_term": 1
(3)向ES发送PUT请求:http://localhost:9200/shopping/_create/1003 ID为用户指定的1003。
请求体内容不变
添加成功返回内容:
"_index": "shopping",
"_type": "_doc",
"_id": "1003",
"_version": 1,
"result": "created",
"_shards":
"total": 2,
"successful": 1,
"failed": 0
,
"_seq_no": 3,
"_primary_term": 1
2、查询文档
(1)根据ID查询
向ES发送GET请求:http://localhost:9200/shopping/_doc/1003 查询ID为1003的数据
返回内容
"_index": "shopping",
"_type": "_doc",
"_id": "1003",
"_version": 1,
"_seq_no": 3,
"_primary_term": 1,
"found": true,
"_source":
"title": "小米手机",
"category": "小米",
"images": "http://www.gulixueyuan.com/xm.jpg",
"price": 1999
(2)查询所有
向ES发送GET请求:http://localhost:9200/shopping/_search 查询所有
返回内容
"took":2,
"timed_out":false,
"_shards":
"total":1,
"successful":1,
"skipped":0,
"failed":0
,
"hits":
"total":
"value":3,
"relation":"eq"
,
"max_score":1,
"hits":[
"_index":"shopping",
"_type":"_doc",
"_id":"IacKhoUBQHPHVJzVREAO",
"_score":1,
"_source":
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":1999
,
"_index":"shopping",
"_type":"_doc",
"_id":"1001",
"_score":1,
"_source":
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":1999
,
"_index":"shopping",
"_type":"_doc",
"_id":"1003",
"_score":1,
"_source":
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":1999
]
3、修改文档
(1)数据全量更新
将ID为1001的数据price改为4999.00
向ES发送PUT请求:http://localhost:9200/shopping/_doc/l001
请求体内容
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":4999.00
返回内容
"_index":"shopping",
"_type":"_doc",
"_id":"1001",
"_version":3,
"result":"updated",
"_shards":
"total":2,
"successful":1,
"failed":0
,
"_seq_no":4,
"_primary_term":1
(2)局部数据更新
向ES发送POST请求:http://localhost:9200/shopping/_update/l001
请求体内容
"doc":
"title":"华为手机"
返回内容
"_index":"shopping",
"_type":"_doc",
"_id":"1001",
"_version":6,
"result":"updated",
"_shards":
"total":2,
"successful":1,
"failed":0
,
"_seq_no":7,
"_primary_term":1
4、删除文档
删除ID为1001的数据
向ES发送DELETE请求:http://localhost:9200/shopping/_doc/l001
返回内容
"_index":"shopping",
"_type":"_doc",
"_id":"1001",
"_version":7,
"result":"deleted",
"_shards":
"total":2,
"successful":1,
"failed":0
,
"_seq_no":8,
"_primary_term":1
5、复杂查询
5.1、条件查询
查询category值为小米的数据
向ES发送POST请求:http://localhost:9200/shopping/_search
请求体内容
"query":
"match":
"category":"小米"
返回内容
"took":1,
"timed_out":false,
"_shards":
"total":1,
"successful":1,
"skipped":0,
"failed":0
,
"hits":
"total":
"value":2,
"relation":"eq"
,
"max_score":1,
"hits":[
"_index":"shopping",
"_type":"_doc",
"_id":"1003",
"_score":1,
"_source":
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":1999
,
"_index":"shopping",
"_type":"_doc",
"_id":"IacKhoUBQHPHVJzVREAO",
"_score":1,
"_source":
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":1999
]
5.2、全量查询
向ES发送POST请求:http://localhost:9200/shopping/_search
请求体内容
"query":
"match_all":
返回内容
"took":1,
"timed_out":false,
"_shards":
"total":1,
"successful":1,
"skipped":0,
"failed":0
,
"hits":
"total":
"value":2,
"relation":"eq"
,
"max_score":1,
"hits":[
"_index":"shopping",
"_type":"_doc",
"_id":"1003",
"_score":1,
"_source":
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":1999
,
"_index":"shopping",
"_type":"_doc",
"_id":"IacKhoUBQHPHVJzVREAO",
"_score":1,
"_source":
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":1999
]
5.3、分页查询
向ES发送POST请求:http://localhost:9200/shopping/_search
请求体内容
"query":
"match_all":
,
"from":0,
"size":2
5.4、查询显示指定的字段
向ES发送POST请求:http://localhost:9200/shopping/_search
请求体内容
"query":
"match_all":
,
"form":0,
"size":2,
"_source":["title"]
返回结果
"took":2,
"timed_out":false,
"_shards":
"total":1,
"successful":1,
"skipped":0,
"failed":0
,
"hits":
"total":
"value":2,
"relation":"eq"
,
"max_score":1,
"hits":[
"_index":"shopping",
"_type":"_doc",
"_id":"1003",
"_score":1,
"_source":
"title":"小米手机"
,
"_index":"shopping",
"_type":"_doc",
"_id":"IacKhoUBQHPHVJzVREAO",
"_score":1,
"_source":
"title":"小米手机"
]
5.5、排序
向ES发送POST请求:http://localhost:9200/shopping/_search
请求体内容
"query":
"match_all":
,
"from":0,
"size":2,
"_source":["title"],
"sort":
"price":
"order":"desc"
5.6、多条件查询
查询category值为小米,并且price的值为1999.00
向ES发送POST请求:http://localhost:9200/shopping/_search
请求体内容:
bool:条件,
must:多个条件必须满足,相当于SQL的and
"query":
"bool":
"must":[
"match":
"category":"小米"
,
"match":
"price":1999.00
]
查询category值为小米,或者category的值为华为
向ES发送POST请求:http://localhost:9200/shopping/_search
请求体内容:
bool:条件,
should:多个条件必须满足,相当于SQL的or
"query":
"bool":
"should":[
"match":
"category":"小米"
,
"match":
"category":"华为"
]
5.7、范围查询
查询category值为小米,或者category的值为华为,并且价格区间在999-1000之间
向ES发送POST请求:http://localhost:9200/shopping/_search
请求体内容:
bool:条件,
should:多个条件必须满足,相当于SQL的or
filter:过滤
range:范围
"query":
"bool":
"should":[
"match":
"category":"小米"
,
"match":
"category":"华为"
],
"filter":
"range":
"price":
"gt":999.00,
"lt":1000.00
5.8、完全匹配
当查询category的值为“小米”的数据时,当我们match中category的值等于“小米”,或者等于“米”ES都能将“小米”的值查询出来。这是因为ES在文档中存储数据时,会进行“分词”操作。根据倒排索引的匹配,当需要完全匹配,就需要使用match_phrase,例如:
向ES发送POST请求:http://localhost:9200/shopping/_search
请求体内容:
"query":
"match_phrase":
"category":"小米"
5.9、高亮查询
当需要将查询出来的结果进行高亮显示,需要在查询语句后面添加“highlight”属性,并指定需要高亮显示的字段。例如:
向ES发送POST请求:http://localhost:9200/shopping/_search
请求体内容:
"query":
"match_phrase":
"category": "小米"
,
"highlight":
"fields":
"category":
返回结果
"took":279,
"timed_out":false,
"_shards":
"total":1,
"successful":1,
"skipped":0,
"failed":0
,
"hits":
"total":
"value":2,
"relation":"eq"
,
"max_score":0.36464313,
"hits":[
"_index":"shopping",
"_type":"_doc",
"_id":"1003",
"_score":0.36464313,
"_source":
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":1999
,
"highlight":
"category":[
"<em>小</em><em>米</em>"
]
,
"_index":"shopping",
"_type":"_doc",
"_id":"IacKhoUBQHPHVJzVREAO",
"_score":0.36464313,
"_source":
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":1999
,
"highlight":
"category":[
"<em>小</em><em>米</em>"
]
]
6.0、聚合查询
ES支持聚合查询,例如需要根据price进行分组,或者求取price的平均值。
(1)根据price进行分组
向ES发送POST请求:http://localhost:9200/shopping/_search
请求体内容:
aggs:聚合操作
price_group:本次聚合操作名称,可以由用户随意起名
terms:分组
"aggs":
"price_group":
"terms":
"field":"price"
返回结果:
"took":120,
"timed_out":false,
"_shards":
"total":1,
"successful":1,
"skipped":0,
"failed":0
,
"hits":
"total":
"value":2,
"relation":"eq"
,
"max_score":1,
"hits":[
"_index":"shopping",
"_type":"_doc",
"_id":"1003",
"_score":1,
"_source":
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":1999
,
"_index":"shopping",
"_type":"_doc",
"_id":"IacKhoUBQHPHVJzVREAO",
"_score":1,
"_source":
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":1999
]
,
"aggregations":
"price_gorup":
"doc_count_error_upper_bound":0,
"sum_other_doc_count":0,
"buckets":[
"key":1999,
"doc_count":2
]
(2)求取price的平均值
向ES发送POST请求:http://localhost:9200/shopping/_search
请求体内容:
aggs:聚合操作
price_avg:本次聚合操作名称,可以由用户随意起名
avg:平均值
size:这里值为0,目的是为了不再查询结果中显示原始的数据
"aggs":
"price_avg":
"avg":
"field": "price"
,
"size":0
返回结果
"took":93,
"timed_out":false,
"_shards":
"total":1,
"successful":1,
"skipped":0,
"failed":0
,
"hits":
"total":
"value":2,
"relation":"eq"
,
"max_score":null,
"hits":[
]
,
"aggregations":
"price_avg":
"value":1999
2.3、映射关系
在上述查询中,ES查询时会对字段进行分词查询,为了控制每个字段是否需要分词查询,就需要设置对应的映射关系。
1、创建user索引
向ES发送PUT请求:http://localhost:9200/user
2、设置mapping
给user索引创建映射关系
向ES发送PUT请求:http://localhost:9200/user/_mapping
请求体内容:
properties:需要设置的属性对象
name,sex,tel 对三个字段的属性设置
type:类型,text可以被分词,keyword不可以被分词
index:改字段是否可以被索引
"properties":
"name":
"type":"text",
"index":true
,
"sex":
"type":"keyword",
"index":true
,
"tel":
"type":"keyword",
"index":false
3、查看设置的映射关系
向ES发送GET请求:http://localhost:9200/user/_mapping
返回结果
"user":
"mappings":
"properties":
"name":
"type":"text"
,
"sex":
"type":"keyword"
,
"tel":
"type":"keyword",
"index":false
4、添加测试数据
为了测试映射关系,给user索引中添加数据
向ES发送POST请求:http://localhost:9200/user/_create/1001
请求体内容
"name":"张三",
"sex":"男士",
"tel":"1111"
5、查询测试
向ES发送POST请求:http://localhost:9200/user/_search
(1)根据name值为张进行查询
请求体内容:
"query":
"match":
"name":"张"
返回内容:
"took":6,
"timed_out":false,
"_shards":
"total":1,
"successful":1,
"skipped":0,
"failed":0
,
"hits":
"total":
"value":1,
"relation":"eq"
,
"max_score":0.2876821,
"hits":[
"_index":"user",
"_type":"_doc",
"_id":"1001",
"_score":0.2876821,
"_source":
"name":"张三",
"sex":"男士",
"tel":"1111"
]
当根据name值为张进行查询时,可以查出张三,因为name的映射类型为text,ES默认进行了分词操作。
(2)根据sex值为男进行查询
请求体内容:
"query":
"match":
"sex":"男"
返回内容:
"took":2,
"timed_out":false,
"_shards":
"total":1,
"successful":1,
"skipped":0,
"failed":0
,
"hits":
"total":
"value":0,
"relation":"eq"
,
"max_score":null,
"hits":[
]
由于sex的映射类型为keyword,ES并没有对其进行分词操作,所以当sex值为男,并不会查询出来。如果需要查询,则需要根据sex值为男士进行查询。
(3)根据电话号查询
请求体内容:
"query":
"match":
"tel":"1111"
返回内容:
"error":
"root_cause":[
"type":"query_shard_exception",
"reason":"failed to create query: Cannot search on field [tel] since it is not indexed.",
"index_uuid":"p407n_WqRC6wJRd4EXeQWQ",
"index":"user"
],
"type":"search_phase_execution_exception",
"reason":"all shards failed",
"phase":"query",
"grouped":true,
"failed_shards":[
"shard":0,
"index":"user",
"node":"vcEDMcA6RB-SWuZuDTpaCA",
"reason":
"type":"query_shard_exception",
"reason":"failed to create query: Cannot search on field [tel] since it is not indexed.",
"index_uuid":"p407n_WqRC6wJRd4EXeQWQ",
"index":"user",
"caused_by":
"type":"illegal_argument_exception",
"reason":"Cannot search on field [tel] since it is not indexed."
]
,
"status":400
由于tel的映射关系,index值为false,意味着tel字段不能够被用来索引,所以报错,并提示:Cannot search on field [tel] since it is not indexed.
三、ElasticSearch的JavaAPI
引入依赖
<dependencies>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.8.0</version>
</dependency>
<!-- elasticsearch 的客户端 -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.8.0</version>
</dependency>
<!-- elasticsearch 依赖 2.x 的 log4j -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.9</version>
</dependency>
<!-- junit 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
创建ES客户端
public static void main(String[] args) throws IOException
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//关闭ES客户端
esClient.close();
3.1、索引API
1、创建索引
public static void main(String[] args) throws IOException
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//创建索引
CreateIndexRequest request = new CreateIndexRequest("user");
CreateIndexResponse response = esClient.indices().create(request, RequestOptions.DEFAULT);
//响应状态 true:success false:error
boolean acknowledged = response.isAcknowledged();
System.out.println(acknowledged);
//关闭ES客户端
esClient.close();
2、查询索引
public static void main(String[] args) throws IOException
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//查询索引
GetIndexRequest request = new GetIndexRequest("user");
GetIndexResponse response = esClient.indices().get(request, RequestOptions.DEFAULT);
System.out.println(response.getAliases());
System.out.println(response.getMappings());
System.out.println(response.getSettings());
//关闭ES客户端
esClient.close();
3、删除索引
public static void main(String[] args) throws IOException
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//删除索引
DeleteIndexRequest request = new DeleteIndexRequest("user");
AcknowledgedResponse delete = esClient.indices().delete(request, RequestOptions.DEFAULT);
boolean acknowledged = delete.isAcknowledged();
System.out.println(acknowledged);
//关闭ES客户端
esClient.close();
3.2、文档API
核心API:
IndexRequest:插入数据请求
UpdateRequest:更新数据请求
GetRequest:查询数据请求
DeleteRequest:删除数据请求
1、新增文档(IndexRequest)
public static void main(String[] args) throws IOException
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//插入数据
IndexRequest request = new IndexRequest();
request.index("user").id("1001");
User user = new User();
user.setName("张三");
user.setAge(18);
user.setSex("男");
//向ES插入数据,必须将数据转为JSON格式
ObjectMapper mapper = new ObjectMapper();
String userJson = mapper.writeValueAsString(user);
request.source(userJson, XContent以上是关于ElasticSearch学习笔记的主要内容,如果未能解决你的问题,请参考以下文章
Elasticsearch - 尚硅谷(2. Elasticsearch 安装)学习笔记