java语言中SpringBoot3.x下使用ElasticSearch8.x的初体验
在idea中使用java语言,使用SpringBoot3.x和ElasticSearch8.x的demo实现
·
需要的依赖版本
1.SpringBoot:3.x
2.ElasticSearch:8.x
3.JDK:17(终于不用1.8了)
先给出pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>es</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>es</name>
<description>es</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>8.17.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
<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.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>5.4.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
给出DTO示例
@Document(indexName = "student")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class StudentDTO {
@Id
@Field(type = FieldType.Long)
private Long id;
@Field(type = FieldType.Keyword)
private String name;
@Field(type = FieldType.Integer)
private Integer age;
@Field(type = FieldType.Keyword)
private String phoneNumber;
@Field(type = FieldType.Keyword)
private String sex;
@Field(type = FieldType.Date, format = DateFormat.date_hour_minute_second)
private Date createTime;
public StudentDTO(Long id, String name, Integer age, String phoneNumber, String sex) {
this.id = id;
this.name = name;
this.age = age;
this.phoneNumber = phoneNumber;
this.sex = sex;
}
}
创建单元测试类
新版本用的是ElasticsearchOperations
@SpringBootTest
public class EsApplicationTests {
@Autowired
private ElasticsearchOperations restTemplate;
//执行的代码逻辑
}
ElasticsearchOperations 中封装了挺多方法,以下简单介绍几个
判断索引是否存在
@Test
public void existsIndex() {
IndexOperations indexOperations = restTemplate.indexOps(StudentDTO.class);
boolean exists = indexOperations.exists();
System.out.println(exists);
}
创建索引
@Test
public void createIndex() {
IndexOperations indexOperations = restTemplate.indexOps(StudentDTO.class);
// 不存在
if(!indexOperations.exists()){
// 创建索引
indexOperations.create();
}
//设置字段mapping
restTemplate.indexOps(StudentDTO.class).putMapping();
}
删除索引
@Test
public void deleteIndex() {
IndexOperations indexOperations = restTemplate.indexOps(StudentDTO.class);
boolean delete = indexOperations.delete();
System.out.println(delete);
}
插入单行数据
@Test
public void insert(){
StudentDTO studentDTO = new StudentDTO();
studentDTO.setId(1L);
studentDTO.setAge(21);
studentDTO.setCreateTime(new Date());
studentDTO.setName("张三");
studentDTO.setPhoneNumber("18392020202");
studentDTO.setSex("男");
StudentDTO saved = restTemplate.save(studentDTO);
System.out.println(saved);
}
更新单行数据
本质是通过id字段(@Id注解)更新
(方法1)
@Test
public void update(){
StudentDTO studentDTO = new StudentDTO();
studentDTO.setId(1L);
studentDTO.setAge(18);
studentDTO.setCreateTime(new Date());
studentDTO.setName("李四");
studentDTO.setPhoneNumber("13904535353");
studentDTO.setSex("男");
StudentDTO saved = restTemplate.save(studentDTO);
System.out.println(saved);
}
(方法2)
@Test
void update2(){
StudentDTO studentDTO = restTemplate.get("1", StudentDTO.class);
assert studentDTO != null;
System.out.println(studentDTO);
studentDTO.setPhoneNumber("18749503962");
StudentDTO saved = restTemplate.save(studentDTO);
System.out.println(saved);
}
批量插入
@Test
public void batchInsert() {
List<StudentDTO> list = new ArrayList<>();
list.add(new StudentDTO(2L, "李四", 12, "17895937593", "男"));
list.add(new StudentDTO(3L, "王二麻子", 31, "18429053823", "男"));
list.add(new StudentDTO(4L, "子涵", 18, "13684924580", "女"));
list.add(new StudentDTO(5L, "寰寰", 60, "15920483957", "女"));
list.add(new StudentDTO(6L, "皇太极", 89, "15528091902", "男"));
Iterable<StudentDTO> result = restTemplate.save(list);
System.out.println(result);
}
查询指定文档
@Test
public void searchById(){
StudentDTO studentDTO = restTemplate.get("3", StudentDTO.class);
assert studentDTO != null;
System.out.println(studentDTO);
}
删除指定文档
@Test
public void deleteById() {
String delete = restTemplate.delete("3", StudentDTO.class);
System.out.println(delete);
}
查询所有数据
@Test
public void searchAll(){
SearchHits<StudentDTO> search = restTemplate.search(Query.findAll(), StudentDTO.class);
List<SearchHit<StudentDTO>> searchHits = search.getSearchHits();
List<StudentDTO> studentDTOS = searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList());
System.out.println(studentDTOS);
}
根据条件查询
@Test
public void matchQuery(){
Query query = NativeQuery.builder().withQuery(q -> q
.match(m -> m
.field("phoneNumber") //要查询的字段
.query("15528091902") //要查询的字段值
)).build();
SearchHits<StudentDTO> searchHits = restTemplate.search(query, StudentDTO.class);
List<StudentDTO> studentDTOS = searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList());
System.out.println(studentDTOS);
}
分页+排序查询
@Test
public void pageSearch() {
Query query = NativeQuery.builder()
.withQuery(Query.findAll())
.withPageable(Pageable.ofSize(3).withPage(0))
.withSort(Sort.by("age").descending())
.build();
SearchHits<StudentDTO> searchHits = restTemplate.search(query, StudentDTO.class);
List<StudentDTO> studentDTOS = searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList());
System.out.println(studentDTOS);
}
原生DSL查询
/*///原始DSL查询
GET /student/_search
{
"query":{
"bool":{
"must": [{
"match":{
"sex":"男"
}
},{
"range":{
"age":{
"gte":10,
"lte":50
}
}
}]
}
}
}*/
@Test
public void stringQuery() {
//搜索性别 男 ,电话号码 159,年龄范围是 10~50之间的
String dsl = """
{"bool":{"must":[{"match":{"sex":"男"}},{"range":{"age":{"gte":10,"lte":50}}}]}}
""";
Query query = new StringQuery(dsl);
List<SearchHit<StudentDTO>> searchHitList = restTemplate.search(query, StudentDTO.class).getSearchHits();
List<StudentDTO> studentDTOS = searchHitList.stream().map(SearchHit::getContent).collect(Collectors.toList());
System.out.println(studentDTOS);
}
聚合查询
@Test
public void aggQuery() {
Query query = NativeQuery.builder()
.withAggregation("category_group", Aggregation.of(a -> a.terms(o-> o.field("sex").size(2))))
.build();
SearchHits<StudentDTO> searchHitList = restTemplate.search(query, StudentDTO.class);
//获取聚合数据
ElasticsearchAggregations aggregationsContainer = (ElasticsearchAggregations) searchHitList.getAggregations();
Map<String, ElasticsearchAggregation> aggregations = Objects.requireNonNull(aggregationsContainer).aggregationsAsMap();
//获取对应名称的聚合
ElasticsearchAggregation aggregation = aggregations.get("category_group");
Buckets<StringTermsBucket> buckets = aggregation.aggregation().getAggregate().sterms().buckets();
//打印
buckets.array().forEach(o -> System.out.println("key:"+ o.key().stringValue() + ", value" + o.docCount()));
List<StudentDTO> studentDTOS = searchHitList.stream().map(SearchHit::getContent).collect(Collectors.toList());
System.out.println(studentDTOS);
}
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)