查看原文
其他

SpringBoot整合Spring Data Elasticsearch(ES7.x),内附完整代码

点击关注 👉 顶级架构师 2022-07-01
推荐关注
顶级架构师后台回复 1024 有特别礼包


作者:星辰啊
来源:juejin.cn/post/7005073093899403294

上一篇:神仙接私活神器,牛到不行,绝了!


大家好,我是顶级架构师。

本文讲述了 SpringBoot 整合 Spring Data Elasticsearch 的详细过程,封装了 ES 常见的搜索、增删改操作,内附完整代码。

前言

本文讲述了SpringBoot整合Spring Data Elasticsearch的详细过程,主要使用了ElasticsearchRestTemplate、ElasticsearchRepository等类来实现IndexDocumentCRUD 操作的 Java Api。

在开始之前,我们首先需要选择 Es 对应版本的 jar 包,本文所使用的 Es 版本为 7.9.3,查看 spring 官网可知,对应的 springboot 版本为 2.4.x。

整合

创建一个 maven 项目,就可以操作起来了。

配置

pom.xml

引入以下 jar 包:

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</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>
<version>1.18.12</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.71</version>
</dependency>
</dependencies>

application.properties

spring.data.elasticsearch.repositories.enabled = true
spring.elasticsearch.rest.uris=localhost:9200

ElasticsearchRestTemplate 配置

@Configuration
public class ElasticsearchRestTemplateConfig extends AbstractElasticsearchConfiguration {
@Value("${spring.elasticsearch.rest.uris}")
private String uris;

@Override
public RestHighLevelClient elasticsearchClient() {
ClientConfiguration configuration = ClientConfiguration.builder()
.connectedTo(uris)
.build();
return RestClients.create(configuration).rest();
}
}

代码

Model

Model 类似于数据库实体,不过此处所映射的是 Index 和 Document 的字段。注解含义可查看 Spring 官网。

@Data
@Document(indexName = "order", shards = 1, replicas = 1)
public class Order implements Serializable {
@Id
private Integer id;

@Field(type = FieldType.Keyword)
private Long orderNo;

@Field(type = FieldType.Integer)
private Integer orderType;

@Field(type = FieldType.Long)
private Long orderAmount;

@Field(type = FieldType.Text, analyzer = "ik_smart", searchAnalyzer = "ik_max_word")
private String orderDesc;

@Field(type = FieldType.Keyword, analyzer = "ik_smart", searchAnalyzer = "ik_max_word")
private String username;

@Field(type = FieldType.Keyword, analyzer = "ik_smart", searchAnalyzer = "ik_max_word")
private String userPhone;

private Map<String, List<String>> highlights;
}

Repository

ElasticsearchRepository 接口封装了 Document 的 CRUD 操作,我们直接定义接口继承它即可。关注顶级架构师


public interface OrderRepository extends ElasticsearchRepository<Order, Integer> {
}

Service

public interface OrderService {
void saveAll(List<Order> orders);

Order findById(Integer id);

void deleteById(Integer id);

void updateById(Order order);

PageResponse<Order> findList(Order order, Integer pageIndex, Integer pageSize);

PageResponse<Order> findAll(Integer pageIndex, Integer pageSize);

PageResponse<Order> findHighlight(Order order, Integer pageIndex, Integer pageSize);
}

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
@Autowired
OrderRepository orderRepository;

@Autowired
ElasticsearchRestTemplate elasticsearchRestTemplate;

@Override
public void saveAll(List<Order> orders) {
orderRepository.saveAll(orders);
}

@Override
public void deleteById(Integer id) {
orderRepository.deleteById(id);
}

@Override
public void updateById(Order order) {
orderRepository.save(order);
}

@Override
public PageResponse<Order> findList(Order order, Integer pageIndex, Integer pageSize) {
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()
.and(new Criteria("orderDesc").contains(order.getOrderDesc()))
.and(new Criteria("orderNo").is(order.getOrderNo())))
.setPageable(PageRequest.of(pageIndex, pageSize));

SearchHits<Order> searchHits = elasticsearchRestTemplate.search(criteriaQuery, Order.class);
List<Order> result = searchHits.get().map(SearchHit::getContent).collect(Collectors.toList());
PageResponse<Order> pageResponse = new PageResponse<Order>();
pageResponse.setTotal(searchHits.getTotalHits());
pageResponse.setResult(result);
return pageResponse;
}

@Override
public PageResponse<Order> findAll(Integer pageIndex, Integer pageSize) {
Page<Order> page = orderRepository.findAll(PageRequest.of(pageIndex, pageSize));

PageResponse<Order> pageResponse = new PageResponse<Order>();
pageResponse.setTotal(page.getTotalElements());
pageResponse.setResult(page.getContent());
return pageResponse;
}

@Override
public PageResponse<Order> findHighlight(Order order, Integer pageIndex, Integer pageSize) {
if (order == null) {
PageResponse<Order> pageResponse = new PageResponse<Order>();
pageResponse.setTotal(0L);
pageResponse.setResult(new ArrayList<>());
return pageResponse;
}

CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()
.and(new Criteria("orderNo").is(order.getOrderNo()))
.and(new Criteria("orderDesc").contains(order.getOrderDesc())))
.setPageable(PageRequest.of(pageIndex, pageSize));

HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("orderNo").field("orderDesc");
highlightBuilder.requireFieldMatch(false);
highlightBuilder.preTags("<h3 style="color:blue">");
highlightBuilder.postTags("</h3>");

HighlightQuery highlightQuery = new HighlightQuery(highlightBuilder);
criteriaQuery.setHighlightQuery(highlightQuery);

SearchHits<Order> searchHits = elasticsearchRestTemplate.search(criteriaQuery, Order.class);

List<Order> result = searchHits.get().map(e -> {
Order element = e.getContent();
element.setHighlights(e.getHighlightFields());
return element;
}).collect(Collectors.toList());

PageResponse<Order> pageResponse = new PageResponse<Order>();
pageResponse.setTotal(searchHits.getTotalHits());
pageResponse.setResult(result);
return pageResponse;
}

@Override
public Order findById(Integer id) {
return orderRepository.findById(id).orElse(null);
}

Controller

  • Index 操作

使用 ElasticsearchRestTemplate 直接就可以创建和删除索引。另外搜索公众号Java后端栈后台回复“面试”,获取一份惊喜礼包。

@RequestMapping("/index/")
@RestController
public class IndexController {

@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;

/**
* 创建索引
*/

@GetMapping("create")
public String create(@RequestParam String indexName) {
IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(IndexCoordinates.of(indexName));
if (indexOperations.exists()) {
return "索引已存在";
}
indexOperations.create();
return "索引创建成功";
}

/**
* 删除索引
*/

@GetMapping("delete")
public String delete(@RequestParam String indexName) {
IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(IndexCoordinates.of(indexName));
indexOperations.delete();
return "索引删除成功";
}
}

  • Document 操作

主要包括简单查询、增删改、分页查询、高亮搜索。

@RequestMapping("/doc/")
@RestController
public class DocController {

@Autowired
OrderService orderService;

/**
* 批量创建
*/

@PostMapping("saveBatch")
public String saveBatch(@RequestBody List<Order> orders) {
if (CollectionUtils.isEmpty(orders)) {
return "文档不能为空";
}
orderService.saveAll(orders);
return "保存成功";
}

/**
* 根据id删除
*/

@GetMapping("deleteById")
public String deleteById(@RequestParam Integer id) {
orderService.deleteById(id);
return "删除成功";
}

/**
* 根据id更新
*/

@PostMapping("updateById")
public String updateById(@RequestBody Order order) {
orderService.updateById(order);
return "更新成功";
}

/**
* 根据id搜索
*/

@GetMapping("findById")
public String findById(@RequestParam Integer id) {
return JSON.toJSONString(orderService.findById(id));
}

/**
* 分页搜索所有
*/

@GetMapping("findAll")
public String findAll(@RequestParam Integer pageIndex, @RequestParam Integer pageSize) {
return JSON.toJSONString(orderService.findAll(pageIndex, pageSize));
}

/**
* 条件分页搜索
*/

@GetMapping("findList")
public String findList(@RequestBody Order order, @RequestParam Integer pageIndex, @RequestParam Integer pageSize) {
return JSON.toJSONString(orderService.findList(order, pageIndex, pageSize));
}

/**
* 条件高亮分页搜索
*/

@GetMapping("findHighlight")
public String findHighlight(@RequestBody(required = false) Order order, @RequestParam Integer pageIndex, @RequestParam Integer pageSize) {
return JSON.toJSONString(orderService.findHighlight(order, pageIndex, pageSize));
}
}

测试

直接 postman 访问 controller 进行测试即可。示例:

完整代码:https://github.com/jackson-zb/es-client

最后给读者整理了一份BAT大厂面试真题,需要的可扫码回复“面试题”即可获取。


公众号后台回复 架构 或者 架构整洁 有惊喜礼包!顶级架构师交流群

 「顶级架构师」建立了读者架构师交流群,大家可以添加小编微信进行加群。欢迎有想法、乐于分享的朋友们一起交流学习。

扫描添加好友邀你进架构师群,加我时注明姓名+公司+职位】


版权申明:内容来源网络,版权归原作者所有。如有侵权烦请告知,我们会立即删除并表示歉意。谢谢。

猜你还想看

推荐一套开源通用后台管理系统(附源码)

推荐一款完整的互联网商城管理系统(附源码)

面试官:生成订单30分钟未支付,则自动取消,该怎么实现?

阿里技术专家:一文教你高效画出技术架构图

16个 Redis 常见使用场景,面试有内容聊啦

面试官问:MySQL的自增 ID 用完了,怎么办?

知名国产论坛,凉了!!!!

卧槽!微信可以改彩色昵称了!!!

前后端分离的接口规范

微服务调用超时处理

SpringBoot+MDC实现全链路调用日志跟踪,这才叫优雅!

同事乱用 Redis 卡爆,我真是醉了...


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存