1.依赖
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.0.0</version><relativePath/>
</parent><properties><java.version>17</java.version>
</properties><dependencies><!--spring boot and web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--spring data elasticsearch--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency>
</dependencies>
2.yaml
elasticsearch:uris: http://10.0.117.74:9200username: elasticpassword: hXtO*Lzi2GGJ5wUmUA2c
3.索引类
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Document(indexName = "video")
public class VideoDTO {/*** type 对应Elasticsearch中属性类型,使用FiledType枚举快速获取。* text 类型能被分词* keywords 不能被分词* index 是否创建索引,作为搜索条件时index必须为true* analyzer 指定分词器类型。*/@Id@Field(type = FieldType.Text, index = false)private Long id;@Field(type = FieldType.Text)private String title;@Field(type = FieldType.Text)private String description;@Field(type = FieldType.Keyword)private String category;@Field(type = FieldType.Integer)private Integer duration;@Field(type = FieldType.Date, format = DateFormat.date_hour_minute_second)private LocalDateTime createTime;public VideoDTO(Long id, String title, String description, Integer duration,String category) {this.id = id;this.title = title;this.description = description;this.duration = duration;this.createTime = LocalDateTime.now();this.category = category;}
}
4.测试类
/*** Spring Data:用于简化数据访问和持久化的开发框架,提供了一组统一的 API 和抽象* 与各种数据存储技术(如关系型数据库、NoSQL 数据库、Elasticsearch 等)进行交互变得更加容易*//*** Java API Client(8.X版本开始推荐使用):是一个用于与Elasticsearch服务器进行通信的Java客户端库* 封装了底层的Transport通信,并提供了同步和异步调用、流式和函数式调用等方法* Java REST Client: 7.1版本之前使用的Java客户端是*/
@Service
public class EsTest {@Autowiredprivate ElasticsearchTemplate restTemplate;/*** 判断索引是否存在索引*/public void existsIndex() {IndexOperations indexOperations = restTemplate.indexOps(VideoDTO.class);boolean exists = indexOperations.exists();System.out.println(exists);}/*** 创建索引*/public void createIndex() {// spring data es所有索引操作都在这个接口IndexOperations indexOperations = restTemplate.indexOps(VideoDTO.class);// 是否存在,存在则删除if(indexOperations.exists()){indexOperations.delete();}// 创建索引indexOperations.create();//设置映射: 在正式开发中,几乎不会使用框架创建索引或设置映射,这是架构或者管理员的工作,不适合使用代码实现restTemplate.indexOps(VideoDTO.class).putMapping();}/*** 删除索引*/public void deleteIndex() {IndexOperations indexOperations = restTemplate.indexOps(VideoDTO.class);boolean delete = indexOperations.delete();System.out.println(delete);}/*** 添加*/public void insert(){VideoDTO videoDTO = new VideoDTO();videoDTO.setId(1L);videoDTO.setTitle("小滴课堂架构大课和Spring Cloud");videoDTO.setCreateTime(LocalDateTime.now());videoDTO.setDuration(100);videoDTO.setCategory("后端");videoDTO.setDescription("这个是综合大型课程,包括了jvm,redis,新版spring boot3.x,架构,监控,性能优化,算法,高并发等多方面内容");VideoDTO saved = restTemplate.save(videoDTO);System.out.println(saved);}/*** 更新*/public void update(){VideoDTO videoDTO = new VideoDTO();videoDTO.setId(1L);videoDTO.setTitle("小滴课堂架构大课和Spring Cloud V2");videoDTO.setCreateTime(LocalDateTime.now());videoDTO.setDuration(102);videoDTO.setCategory("后端");videoDTO.setDescription("这个是综合大型课程,包括了jvm,redis,新版spring boot3.x,架构,监控,性能优化,算法,高并发等多方面内容");VideoDTO saved = restTemplate.save(videoDTO);System.out.println(saved);}/*** 批量添加*/public void batchInsert() {List<VideoDTO> list = new ArrayList<>();list.add(new VideoDTO(2L, "老王录制的按摩课程", "主要按摩和会所推荐", 123, "后端"));list.add(new VideoDTO(3L, "冰冰的前端性能优化", "前端高手系列", 100042, "前端"));list.add(new VideoDTO(4L, "海量数据项目大课", "D哥的后端+大数据综合课程", 5432345, "后端"));list.add(new VideoDTO(5L, "小滴课堂永久会员", "可以看海量专题课程,IT技术持续充电平台", 6542, "后端"));list.add(new VideoDTO(6L, "大钊-前端低代码平台", "高效开发底层基础平台,效能平台案例", 53422, "前端"));list.add(new VideoDTO(7L, "自动化测试平台大课", "微服务架构下的spring cloud架构大课,包括jvm,效能平台", 6542, "后端"));Iterable<VideoDTO> result = restTemplate.save(list);System.out.println(result);}/*** 主键查询*/public void searchById(){VideoDTO videoDTO = restTemplate.get("3", VideoDTO.class);assert videoDTO != null;System.out.println(videoDTO);}/*** 删除ById*/public void deleteById() {String delete = restTemplate.delete("2", VideoDTO.class);System.out.println(delete);}/*** NativeQuery* 搜索复杂查询或无法使用CriteriaAPI 表达的查询时使用的类,例如在构建查询和使用聚合的场景*//*** 查询所有:*/public void searchAll(){SearchHits<VideoDTO> search = restTemplate.search(Query.findAll(), VideoDTO.class);List<SearchHit<VideoDTO>> searchHits = search.getSearchHits();// 获得searchHits,进行遍历得到contentList<VideoDTO> videoDTOS = new ArrayList<>();searchHits.forEach(hit -> {videoDTOS.add(hit.getContent());});System.out.println(videoDTOS);}/*** match查询*/public void matchQuery(){Query query = NativeQuery.builder().withQuery(q -> q.match(m -> m.field("description") //字段.query("spring") //值)).build();SearchHits<VideoDTO> searchHits = restTemplate.search(query, VideoDTO.class);// 获得searchHits,进行遍历得到contentList<VideoDTO> videoDTOS = new ArrayList<>();searchHits.forEach(hit -> {videoDTOS.add(hit.getContent());});System.out.println(videoDTOS);}/*** 分页查询*/public void pageSearch() {Query query = NativeQuery.builder().withQuery((co.elastic.clients.elasticsearch._types.query_dsl.Query) Query.findAll()).withPageable(Pageable.ofSize(3).withPage(0)).build();SearchHits<VideoDTO> searchHits = restTemplate.search(query, VideoDTO.class);// 获得searchHits,进行遍历得到contentList<VideoDTO> videoDTOS = new ArrayList<>();searchHits.forEach(hit -> {videoDTOS.add(hit.getContent());});System.out.println(videoDTOS);}/*** 排序查询,根据时长降序排列*/public void sortSearch() {Query query = NativeQuery.builder().withQuery((co.elastic.clients.elasticsearch._types.query_dsl.Query) Query.findAll()).withPageable(Pageable.ofSize(10).withPage(0))// descending():倒叙 ascending():默认的,正序.withSort(Sort.by("duration").descending()).build();SearchHits<VideoDTO> searchHits = restTemplate.search(query, VideoDTO.class);// 获得searchHits,进行遍历得到contentList<VideoDTO> videoDTOS = new ArrayList<>();searchHits.forEach(hit -> {videoDTOS.add(hit.getContent());});System.out.println(videoDTOS);}/*** StringQuery搜索:将Elasticsearch查询作为JSON字符串*/public void stringQuery() {//搜索标题有 架构 关键词,描述有 spring关键字,时长范围是 10~6000之间的String dsl = """{"bool":{"must":[{"match":{"title":"架构"}},{"match":{"description":"spring"}},{"range":{"duration":{"gte":10,"lte":6000}}}]}}""";Query query = new StringQuery(dsl);List<SearchHit<VideoDTO>> searchHitList = restTemplate.search(query, VideoDTO.class).getSearchHits();// 获得searchHits,进行遍历得到contentList<VideoDTO> videoDTOS = new ArrayList<>();searchHitList.forEach(hit -> {videoDTOS.add(hit.getContent());});System.out.println(videoDTOS);}/*** 聚合查询* CriteriaQuery* 创建Criteria来搜索数据,而无需了解 Elasticsearch 查询的语法或基础知识* 允许用户通过简单地连接和组合,指定搜索文档必须满足的对象来构建查询*/void aggQuery() {Query query = NativeQuery.builder().withAggregation("category_group", Aggregation.of(a -> a.terms(ta -> ta.field("category").size(2)))).build();SearchHits<VideoDTO> searchHits = restTemplate.search(query, VideoDTO.class);//获取聚合数据ElasticsearchAggregations aggregationsContainer = (ElasticsearchAggregations) searchHits.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(bucket -> {System.out.println("组名:"+bucket.key().stringValue() + ", 值" + bucket.docCount());});// 获得searchHits,进行遍历得到contentList<VideoDTO> videoDTOS = new ArrayList<>();searchHits.forEach(hit -> {videoDTOS.add(hit.getContent());});System.out.println(videoDTOS);}
}
5.接口
@RestController
@RequestMapping("/test")
public class TestAPI {@Autowiredprivate EsTest esTest;@PostMapping("/test")public String test(){esTest.createIndex();esTest.deleteIndex();return "test";}
}