SpringBoot整合Spring Data Elasticsearch(ES7.x),内附完整代码
前言
本文讲述了SpringBoot
整合Spring Data Elasticsearch
的详细过程,主要使用了ElasticsearchRestTemplate、ElasticsearchRepository
等类来实现Index
、Document
CRUD操作的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直接就可以创建和删除索引。
@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://juejin.cn/post/7005073093899403294