ElasticSearch

流行的搜索引擎

介绍

索引 index

一个索引可以理解成一个关系数据库的库

类型 type

(es7已经不推荐使用)

一种type就像一类表,比如user表,order表

映射 mapping

(es7已经不推荐使用)

mapping定义了每个字段的类型等信息。相当于关系型数据库中的表结

文档 document

一个document相当于关系型数据库中的一⾏记录

字段 field

相当于关系型数据库表的字段

集群 cluster

-集群由一个或多个节点组成,一个集群有一个默认名称elasticsearch

节点 node

集群的节点,一台机器 或者一个进程

分片和副本 node

副本是分片的副本。分⽚有主分片(primary Shard)和副本分片(replica Shard)之分。Index数据在物理理上被分布在多个主分片中,每个主分片只存放部分数据。每个主分⽚可以有多个副本,叫副本分片,是主分片的复制

核心数据类型

字符串

text
用于全文索引,该类型的字段将通过分词器 进⾏分词

keyword
不分词,只能搜索该字段的完整的值

数值型

integer, short, byte, double, float, half_float, scaled_float

数值型 boolean

二进制

binary
该类型的字段把值当做经过 base64 编码的字符串,默认不存储,且不可搜索

范围类型

范围类型表示值是一个范围,而不是⼀个具体的值

integer_range, float_range, long_range, double_range, date_range

譬如 age 的类型是 integer_range,那么值可以是 {“gte” : 20, “lte” : 40};搜索 “term” : {“age”: 21} 可以搜索该值

日期

由于Json没有date类型,所以es通过识别字符串是否符合format定义的格式来判断是否为date类型

format默认为:strict_date_optional_time||epoch_millis,”2022-01-01” “2022/01/01 12:10:30” 这种字符串格式

搜索

Query DSL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
GET bank/_search

{
"query":{
// 查询所有
"match_all": {},

// 全文检索 查询指定字段
"match": {
// 查询 字段包含今天,吃好饱 的数据
"field_one": "今天 吃好饱"
},

// 完整单词匹配,不分词
"match_phrase": {
"field_one": "今天 吃好饱"
},

// 多字段匹配,只要field_one,field_two包含今天,吃好饱的都匹配
"multi_match": {
"query": "今天 吃好饱",
"field": ["field_one","field_two"]
},

// 复合查询
"bool": {
// 必须匹配
"mush": [
{
"match": {
"field_one": "今天 吃好饱"
},
},
{
"match": {
"field_two": "今天 吃好饱"
},
}
],
// 必须不匹配
"mush_not": [
{
"match": {
"field_three": "今天 吃好饱"
},
}
],
// 应该,满足或不满足都可以
"should": [
{
"match": {
"field_four": "今天 吃好饱"
},
},
],
// 过滤查询,不参与评分,效率更高
"filter":{
"range": {
// 查询年龄在 18~30之间的
"age": {
"gte": 18,
"lte": 30
}
}
}
},

// 嵌入式查询,要查询的下级是一个对象里的属性的时候使用
"nested":{
// 对象名称
"path":"addr",
"query":{
"term": {
"age": "28"
}
}
},

// 非文本字段,精确字段建议用 term
"term": {
// 查询年龄是28的数据
"age": "28"
},

// 区间查询
"range": {
"age": {
// 查询10~20岁的信息
"gte": 10,
"lte": 20
}
}
},
// 排序
"sort": [
{
"id": "desc"
}
],
// 从第1条开始 查10条
"form": 0,
"size": 10,
// 返回指定字段
"_source": ["field_1","field_2"]
}

Aggregations 聚合查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
GET bank/_search

{
"query": {
"match_all": {},
},
// 聚合
"aggs": {
// 起一个名字叫 ageAgg
"ageAgg": {
// 对年龄字段进行分组,
"terms": {
"field": "age",
// 取前10组
"size": 10
},
// 对上面聚合的结果进行二次聚合
"aggs": {
"ageAvg": {
// 对薪资求平均值
"avg": {
"field": "banlance",
}
}
}
}
}
}

安装

Docker安装

SpringBoot使用

es原生框架组件

pom

1
2
3
4
5
6
7
8
9
<properties>
<!-- 防止springBoot版本和es版本不一致 -->
<elasticsearch.version>7.6.2</elasticsearch.version>
</properties>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.6.2</version>
</dependency>

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Configuration
public class MyElasticSearchConfig {

public static final RequestOptions COMMON_OPTIONS;

static {
RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
// 添加请求头,配置访问es的一些请求信息
// builder.addHeader()
COMMON_OPTIONS = builder.build();
}

@Bean
public RestHighLevelClient restHighLevelClient() {
return new RestHighLevelClient(
RestClient.builder(
// 多个就写多个
new HttpHost("127.0.0.1", 9200, "http"),
new HttpHost("127.0.0.1", 9201, "http")
)
);
}
}

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
@Autowired
private RestHighLevelClient restHighLevelClient;

/**
* 保存数据
**/
@Test
public void esTest() throws IOException {
IndexRequest users = new IndexRequest("users");
// 数据id
users.id("1");
Object o = new Object();
// 要保存的数据源,格式化为json格式,指定数据格式为json
users.source(JSONObject.toJSONString(o), XContentType.JSON);
IndexResponse response = restHighLevelClient.index(users, MyElasticSearchConfig.COMMON_OPTIONS);
}

/**
* ES搜索
*/
@Test
public void esSearch() throws IOException {
SearchRequest searchRequest = new SearchRequest();
// 指定查询的索引
searchRequest.indices("users");
// 指定检索条件
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 查询条件
sourceBuilder.query(
QueryBuilders.matchQuery("name","张三")
);
// 聚合条件
sourceBuilder.aggregation(
// terms中写聚合的名字,filed指定聚合的字段,size写聚合的条数
AggregationBuilders.terms("aggInfo").field("age").size(10)
);
searchRequest.source(sourceBuilder);
// 执行
SearchResponse response = restHighLevelClient.search(searchRequest, MyElasticSearchConfig.COMMON_OPTIONS);

// 获取所有查到的数据
SearchHits hits = response.getHits();
SearchHit[] hitsHits = hits.getHits();
for (SearchHit hitsHit : hitsHits) {
Object bean = JSONObject.parseObject(hitsHit.getSourceAsString(), Object.class);
System.out.println(bean);
}
}

spring-boot-data-elasticsearch

注:只有springboot2.3.x以上的版本支持es7

pom

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
</dependencies>

yml

1
2
3
4
5
6
7
8
9
10
11
spring:
application:
name: TestElasticsearch
elasticsearch:
rest:
# ip地址
uris: 192.168.0.18:9200
# 用户名
username: elastic
# 密码
password: elastic

实体

1
2
3
4
5
6
7
8
9
10
11
12
13
@Document(indexName = "user-index",replicas = 3) // 名称和分片数
public class User implements Serializable {

private static final long serialVersionUID = 2852000052380434205L;

@Id // 指定id
@Field(type = FieldType.Long, store = true) // 指定字段的类型和是否永久存储
private Long id;

@Field(type = FieldType.Text, analyzer = "ik_max_word", store = true)
private String name;

// 省略get set方法

继承ElasticsearchRepository

1
2
3
// 这里面提供了一些常用的方法,泛型第一个是存储的文档类型,第二个是id
public interface UserRepository extends ElasticsearchRepository<User,Long> {
}

集群搭建

es集群架构

配置信息

1
2
3
4
5
6
7
8
9
10
11
12
13
# 写在elasticsearch.yml文件中
# 集群名称,保证唯一
cluster.name: es-1
#为本机ip地址
network.host: 0.0.0.0
# 节点名称,必须不一样
node.name: node-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"]

相关文章

数据库连接池

Junit和Spring

Tomcat

Servlet

Request,Response和ServletContext

Cookie和Session

JSP和EL和Jstl

Filter和Listener

Mybatis

SpringCache