# SpringBoot整合Elasticsearch初体验
# 1.添加maven依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath />
</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>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2.application.yml
spring:
application:
name: senta-es
data:
elasticsearch:
cluster-name: elasticsearch #es默认集群名字
cluster-nodes: 122.51.226.121:9300 #9200是图形界面端,9300代码端
repositories:
enabled: true #开启 Elasticsearch 仓库(默认值:true)
properties:
transport:
tcp:
connect_timeout: 120s # ES设置连接超时时间
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 3.实体类层
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
/**
* 对应的实体类
* @author 福小林
*
* 注解说明
* Document 对应一个文档数据 indexName 索引名称 type 类型
*/
@Document(indexName = "myIndexName", type = "user")
@Data
public class UserEntity {
@Id
private String id;
private String name;
private int sex;
private int age;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 4.Dao类层
import com.senta.elasticsearch.entity.UserEntity;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
/**
* @author 福小林
* 操作对应es的数据层
*/
@Repository
public interface UserRepository extends CrudRepository<UserEntity, String> {
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 5.Controller层
import com.senta.elasticsearch.entity.UserEntity;
import com.senta.elasticsearch.mapper.xml.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Optional;
/**
* @author 福小林
* 操作es的controller
*/
@RestController
public class EsController {
@Autowired
private UserRepository userRepository;
@RequestMapping("/addUser")
public UserEntity addUser(@RequestBody UserEntity user) {
return userRepository.save(user);
}
@RequestMapping("/findUser")
public Optional<UserEntity> findUser(String id) {
return userRepository.findById(id);
}
}
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
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
# 6.启动项目
@SpringBootApplication
public class ESApplication {
public static void main(String[] args) {
SpringApplication.run(ESApplication.class, args);
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# 7.若扫描Repostitory失败
/**
* @author 福小林
* 若扫描UserRepository失败,则需要添加E@nableElasticsearchRepositories
*/
@SpringBootApplication
@EnableElasticsearchRepositories(basePackages = "com.senta.repository")
public class ESApplication {
public static void main(String[] args) {
SpringApplication.run(ESApplication.class, args);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 8.结合DSL语句整合
# 8.1 常用dsl语句汇总
# 类似于mysql查询语句 SELECT * FROM billingitemdis WHERE orderDoctor='汪琳休' AND patientName='聂炎' AND itemClass1 !='E' AND orderDoctorId='12884' limit 0,308 ORDEY BY pk ASC
GET billing/billingitemdis/_search
{
"query":{
"bool":{
"must":[
{
"match":{
"orderDoctor":"汪琳休"
}
},
{
"match":{
"patientName":"聂炎"
}
}
],
"must_not":[
{
"match":{
"itemClass1":"E"
}
}
],
"should":[
{
"match":{
"hosOutp":"住院"
}
},
{
"match":{
"itemClass2":"治疗"
}
}
],
"filter":{
"term":{
"orderDoctorId":"12884"
}
}
}
},
"sort":[
{
"pk":{
"order":"asc"
}
}
],
"size":308,
"from":0
}
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
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
查询语句需要对应的顺序以上覆盖了大部分常用的顺序,当在java代码中创建应该遵循以上的顺序和层次结构,不然都有报错的可能
# 8.2 具体参数说明
# query
最外层查询结构
# bool
可以添加:must,must_not, should, filter
# must
可以通过match匹配多个条件,要求每个条件必须存在才可以查询到
## must_not
可以通过match匹配,符合条件的会被过滤掉
#should
可以通过match匹配多个条件,每个match的相关度计算一致,需要调整相关度可在should中添加bool作刺激匹配,项匹配的数据按相关度_score排序
# filter
过滤,通过term来精准过滤条件,全字仅匹配成功的才通过
# sort desc排序
排序,可以省写 "sort": "pk"
# size
显示当前页数据条数,ES有默认的大小可以通过 _settings设置,当显示不出全部数据时可能是页数限制
# from
当前页,从 0 开始,由于ES的特性,在第一页返回的是最快的,访问数据时间页深度增加而增加,不建议深分页
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
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
# 8.3 对应上面的dsl的java代码
@GetMapping("/query")
public Page<BillingItemDis> queryFromEs(){
NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
MatchQueryBuilder matchOderDoctor = QueryBuilders.matchQuery("orderDoctor", "汪琳休");
MatchQueryBuilder matchPatientName = QueryBuilders.matchQuery("patientName", "聂炎");
boolQuery.must(matchOderDoctor);
boolQuery.must(matchPatientName);
MatchQueryBuilder matchItemClass1 = QueryBuilders.matchQuery("itemClass1","E");
boolQuery.mustNot(matchItemClass1);
MatchQueryBuilder matchHosOutp = QueryBuilders.matchQuery("hosOutp", "住院");
MatchQueryBuilder matchItemClass2 = QueryBuilders.matchQuery("itemClass2", "治疗");
boolQuery.should(matchHosOutp);
boolQuery.should(matchItemClass2);
TermQueryBuilder termOrderDoctorId = QueryBuilders.termQuery("orderDoctorId", "12884");
boolQuery.filter(termOrderDoctorId);
builder.withQuery(boolQuery);
builder.withSort(SortBuilders.fieldSort("pk").order(SortOrder.DESC));
builder.withPageable(PageRequest.of(0,308));
NativeSearchQuery searchQuery = builder.build();
Page<BillingItemDis> search = billingItemDisRepository.search(searchQuery);
return search;
}
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
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
# 8.4 字段定义规范
Text:文本文件,会被分词,直接term就无法匹配,保存为string,不支持range,
Integer:基本数据类型
Long: 基本数据类型
Date: 日期类型,可通过format进行副值定义,建议需要进行日期筛选时使用
Float:单精度
Double: 双精度
Boolean :
Object: 对象类型
Auto: 自动,不使用
Nested: 嵌套对象数据类型,会形成特定的关联关系,更新关联父子对象时会更新整个数据库的父子,使用与查询多,偶尔更新的场景
Ip: 保存ip地址时使用
Attachment:附件类型,doc,xml
Keyword:关键词,默认不分词,可以完全匹配,要求姓名必须有keyword字段
DateFormat:日期类型对应的其他格式请参考 http://www.kyjszj.com/htzq/109.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
← DSL语言查询与过滤 权限模块设计 →