一、什么是ElasticSearch
Elasticsearch 是一个分布式的开源搜索和分析引擎,基于RESTful Web 接口,适用于所有类型的数据,包括文本、数字、地理空间、结构化和非结构化数据。
可以用来做全文检索、结构化搜索和分析等
二、安装使用
官网下载地址:https://www.elastic.co/cn/downloads/
1.docker中搭建ES环境
(1)下载ES镜像
docker pull elasticsearch:7.4.2
(2)映射配置文件
配置映射文件夹
mkdir -p /mydata/elasticsearch/config
配置映射文件夹
mkdir -p /mydata/elasticsearch/data
设置文件夹权限任何用户可读可写
chmod 777 /mydata/elasticsearch -R
配置 http.host
echo "http.host: 0.0.0.0" >> /mydata/elasticsearch/config/elasticsearch.yml
(3)启动容器,访问服务http://localhost:9200/
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type"="single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx128m" \
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.4.2
注意:es默认占用2G内存,此处添加 -e ES_JAVA_OPTS="-Xms64m -Xmx128m" 参数指定占用内存
2.搭建 Kibana 环境
Kibana能够以图表的形式呈现数据,并且具有可扩展的用户界面,可以全方位的配置和管理ElasticSearch
docker pull kibana:7.4.2
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.56.10:9200 -p 5601:5601 -d kibana:7.4.2
3.安装ik分词器
由于es自带没有中文分词器,这里添加大家用的比较多的ik分词器(注意ik分词器的版本必须和es版本一致)
# 进入es的容器
docker exec -it es bash
# 进入bin目录
cd /usr/share/elasticsearch/bin/
# 在线安装ik分词器
./elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-analysis-ik-7.4.2.zip
# 查看是否安装成功
cd ../plugins/
ls
三、核心概念
1.Near Realtime (NRT)
ES号称对外提供的是近实时的搜索服务,意思是数据从写入ES到可以被Searchable仅仅需要1秒钟,所以说基于ES执行的搜索和分析可以达到秒级
2.Cluster
集群是一个或多个node的集合,它们一起保存你存放进去的数据,用户可以在所有的node之间进行检索,一般的每个集群都会有一个唯一的名称标识,默认的名称标识为 elasticsearch ,这个名字很重要,因为node想加入cluster时,需要这个名称信息
3.Node
单台server就是一个node,它和cluster一样,也存在一个默认的名称。它的名称是通过UUID生成的随机串,也可以定制不同的名称,但是名字最好别重复
4.Index(索引)
一个索引是一个文档的集合,每个索引有唯一的名字,通过这个名字来操作它。一个集群中可以有任意多个索引
5.Type
可以作为index中的逻辑类别。为了更细的划分,比如用户数据type、评论数据type、博客数据type
6.Document
ES中存储的一条数据,就像mysql中的一行记录一样。它可以是一条用户的记录、一个商品的记录等等
7.Shard(分片)
在创建一个索引时可以指定分成多少个分片来存储。每个分片本身也是一个功能完善且独立的“索引”,可以被放置在集群的任意节点上
8.Replication(备份)
一个分片可以有多个备份(副本)
四、常用语句
官方文档:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/
1._cat用法
# 查看所有节点
GET /_cat/nodes
# 查看 es 健康状况
GET /_cat/health
# 查看主节点
GET /_cat/master
# 查看所有索引
GET /_cat/indices
2.query dsl
格式:
GET /yourIndex/yourType/_search
{
// 请求参数
}
举例:
针对name字段进行全文检索
GET /yourIndex/yourType/_search
{
"query": {
# match表示全文检索,因此name会被分词成:凡人 修仙 凡人修仙传等,然后匹配出所有name中包含分词的doc
"match": {
"name": "凡人修仙传"
}
}
}
五、与SpringBoot整合
1.在pom.xml中添加es的依赖
<properties>
<java.version>1.8</java.version>
<elasticsearch.version>7.4.2</elasticsearch.version>
</properties>
<-- 使用Elasticsearch-Rest-Client(elasticsearch-rest-high-level-client)操作es -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.4.2</version>
</dependency>
2.在application.yml中添加es的配置
# elasticsearch配置
elasticsearch:
rest:
# es节点地址,集群则用逗号隔开
uris: http://192.168.XX.XXX:9200
3.编写配置类
@Configuration
public class ElasticSearchConfig {
public static final RequestOptions COMMON_OPTIONS;
static {
// RequestOptions类保存了请求的部分,这些部分应该在同一个应用程序中的许多请求之间共享。
// 创建一个singleton实例,并在所有请求之间共享它。可以设置请求头之类的一些配置
RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
// builder.addHeader("Authorization", "Bearer " + TOKEN);
// builder.setHttpAsyncResponseConsumerFactory(
// new HttpAsyncResponseConsumerFactory
// .HeapBufferedResponseConsumerFactory(30 * 1024 * 1024 *1024));
COMMON_OPTIONS = builder.build();
}
//创建ES实例
@Bean
public RestHighLevelClient restHighLevelClient(){
return new RestHighLevelClient(RestClient.builder(new HttpHost(
"192.168.XX.XXX",9200,"http"
)));
}
}
4.测试检索
#搜索address中包含 mill的所有人的年龄分布以及平均年龄
@Test
void test() throws IOException {
//搜索address中包含 mill的所有人的年龄分布以及平均年龄
// 创建检索请求
SearchRequest searchRequest = new SearchRequest();
// 指定索引
searchRequest.indices("bank");
// 指定 DSL 检索条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 构建检索条件 address 包含 mill
searchSourceBuilder.query(QueryBuilders.matchQuery("address","mill"));
// 按照年龄值分布进行聚合
TermsAggregationBuilder ageAgg = AggregationBuilders.terms("ageAgg").field("age").size(10);
searchSourceBuilder.aggregation(ageAgg);
// 1.3 计算平均薪资
AvgAggregationBuilder balanceAvg = AggregationBuilders.avg("balanceAvg").field("balance");
searchSourceBuilder.aggregation(balanceAvg);
System.out.println("检索条件:"+searchSourceBuilder.toString());
searchRequest.source(searchSourceBuilder);
//执行检索
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, ElasticSearchConfig.COMMON_OPTIONS);
//获取查询到的记录
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
//获取检索的分析信息
Aggregations aggregations = searchResponse.getAggregations();
// for (Aggregation aggregation : aggregations.asList()) {
// System.out.println("当前聚合名:" + aggregation.getName());
// }
Terms ageAgg1 = aggregations.get("ageAgg");
for (Terms.Bucket bucket : ageAgg1.getBuckets()) {
String keyAsString = bucket.getKeyAsString();
System.out.println("年龄:" + keyAsString + " 岁的有 " + bucket.getDocCount() + " 人");
}
Avg balanceAvg1 = aggregations.get("balanceAvg");
System.out.println("平均薪资: " + balanceAvg1.getValue());
}