SpringBoot整合Easy-es
一.什么是Easy-Es
Easy-Es(简称EE)是一款基于ElasticSearch(简称Es)官方提供的RestHighLevelClient打造的ORM开发框架,在 RestHighLevelClient 的基础上,只做增强不做改变,为简化开发、提高效率而生,您如果有用过Mybatis-Plus(简称MP),那么您基本可以零学习成本直接上手EE,EE是MP的Es平替版,在有些方面甚至比MP更简单,同时也融入了更多Es独有的功能,助力您快速实现各种场景的开发.
二.为什么要使用Easy-Es
EasyEs是一个基于
ElasticSearch官方提供的
RestHighLevelClient开发的
ORM框架,它的设计理念类似于
Mybatis-Plus,旨在简化开发、提高效率。使用EasyEs的主要原因包括:
- 简化操作:EasyEs让开发者无需掌握复杂的DSL语句MySQLElasticsearch
- 提高效率:对于熟悉Mybatis-Plus
- 易于集成:EasyEs作为一款轻量级的ORM框架,对现有工程的影响小,几乎无侵入性,启动时会自动注入基本的CRUD操作,性能基本无损耗,使得开发者能够直接面向对象操作,提高了开发效率。
- 降低成本:在特定的应用场景下,如大型数据的存储和检索,EasyEs通过优化存储和索引方式,如使用ZSTD压缩功能快照备份S3存储
综上所述,使用EasyEs可以显著简化Elasticsearch的操作,提高开发效率,同时降低数据存储和检索的成本,是开发和运维人员值得考虑的选择.
三.Spring整合Easy-Es
1.依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- lombok插件依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- Easy-Es暂不支持SpringBoot3.X,且推荐Elasticsearch版本为7.14.0 -->
<dependency>
<groupId>cn.easy-es</groupId>
<artifactId>easy-es-boot-starter</artifactId>
<version>1.1.1</version>
<exclusions>
<exclusion>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclusion>
<exclusion>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
</exclusion>
<exclusion>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.14.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.14.0</version>
</dependency>
</dependencies>
2.配置
easy-es:
enable: true
address : 服务器地址:9200
global-config:
process_index_mode: manual
3.启动类
@SpringBootApplication
@EsMapperScan("com.easyes.mapper")
public class EasyEsApplication {
public static void main(String[] args) {
SpringApplication.run(EasyEsApplication.class, args);
}
}
4.mapper
public interface DocumentMapper extends BaseEsMapper<Document> {
}
5.service
package com.easyes.service;
import com.easyes.entity.Document;
import java.util.List;
public interface IDocumentService{
/**
* 查询ES所有数据
* @return 查询Document结果对象集合
*/
List<Document> findAllData();
/**
* 创建索引
* @return 结果信息
* @throws Exception
*/
String createIndex() throws Exception;
/**
* 删除索引
* @return 结果信息
*/
String deleteIndex();
/**
* ES新增数据
* @param document 新增数据实体类
* @return 结果信息
* @throws Exception
*/
String addData(Document document) throws Exception;
/**
* 根据id删除ES数据
* @param id 需要删除的数据的id
* @return
*/
String deleteDataById(String id);
/**
* 修改ES数据
* @param document 修改数据对象
*/
String updateData(Document document);
/**
* 分词匹配查询content字段
* @param value 查询内容
* @return
*/
List<Document> findMatch(String value);
/**
* 根据id查询数据
* @param id 查询id
* @return
*/
Document findById(String id);
}
6.serviceImpl
package com.easyes.service.impl;
import cn.easyes.common.utils.StringUtils;
import cn.easyes.core.conditions.LambdaEsQueryWrapper;
import com.easyes.entity.Document;
import com.easyes.mapper.DocumentMapper;
import com.easyes.service.IDocumentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
@Service
public class DocumentServiceImpl implements IDocumentService {
@Autowired
private DocumentMapper documentMapper;
/**
* 查询ES所有数据
* @return 查询Document结果对象集合
*/
@Override
public List<Document> findAllData() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.matchAllQuery();
return documentMapper.selectList(wrapper);
}
/**
* 创建索引
* @return 结果信息
* @throws Exception
*/
@Override
public String createIndex() throws Exception {
StringBuilder msg = new StringBuilder();
String indexName = Document.class.getSimpleName().toLowerCase();
boolean existsIndex = documentMapper.existsIndex(indexName);
if (existsIndex){
throw new Exception("Document实体对应索引已存在,删除索引接口:deleteIndex");
}
boolean success = documentMapper.createIndex();
if (success){
msg.append("Document索引创建成功");
}else {
msg.append("索引创建失败");
}
return msg.toString();
}
/**
* 删除索引
* @return 结果信息
*/
@Override
public String deleteIndex() {
StringBuilder msg = new StringBuilder();
String indexName = Document.class.getSimpleName().toLowerCase();
if (documentMapper.deleteIndex(indexName)){
msg.append("删除成功");
}else {
msg.append("删除失败");
}
return msg.toString();
}
/**
* ES新增数据
* @param document 新增数据实体类
* @return 结果信息
* @throws Exception
*/
@Override
public String addData(Document document) throws Exception {
if (StringUtils.isEmpty(document.getTitle()) || StringUtils.isEmpty(document.getContent())) {
throw new Exception("请补全title及content数据");
}
document.setCreateTime(new Date());
documentMapper.insert(document);
return "Added successfully!";
}
/**
* 根据id删除ES数据
* @param id 需要删除的数据的id
* @return
*/
@Override
public String deleteDataById(String id) {
documentMapper.deleteById(id);
return "Success";
}
/**
* 修改ES数据
* @param document 修改数据对象
*/
@Override
public String updateData(Document document) {
documentMapper.updateById(document);
return "Success";
}
/**
* 分词匹配查询content字段
* @param value 查询内容
* @return
*/
@Override
public List<Document> findMatch(String value) {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.match(Document::getContent,value);
wrapper.orderByDesc(Document::getCreateTime);
List<Document> documents = documentMapper.selectList(wrapper);
return documents;
}
/**
* 根据id查询数据
* @param id
* @return
*/
@Override
public Document findById(String id) {
return null;
}
}
7.controller
package com.easyes.controller;
import com.easyes.entity.Document;
import com.easyes.service.IDocumentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class DocumentController {
@Autowired
private IDocumentService iDocumentService;
/**
* 创建索引
* @return 结果信息
* @throws Exception
*/
@GetMapping("/createIndex")
public String createIndex() throws Exception {
return iDocumentService.createIndex();
}
/**
* 删除索引
* @return 结果信息
*/
@GetMapping("/deleteIndex")
public String deleteIndex(){
return iDocumentService.deleteIndex();
}
/**
* 查询ES所有数据
* @return 查询Document结果对象集合
*/
@GetMapping("/findAll")
public List<Document> findAll(){
return iDocumentService.findAllData();
}
/**
* 根据id查询数据
* @param id 查询数据的id
* @return 查询Document结果对象
*/
@GetMapping("/findById")
public Document findById(String id){
return iDocumentService.findById(id);
}
/**
* ES新增数据
* @param document 新增数据对象
* @return 结果信息
* @throws Exception
*/
@GetMapping("/add")
public String addData(@RequestBody Document document) throws Exception {
return iDocumentService.addData(document);
}
/**
* 修改ES数据
* @param document 修改数据对象
*/
@GetMapping("/update")
public String updateData(@RequestBody Document document){
return iDocumentService.updateData(document);
}
/**
* 根据id删除ES数据
* @param id 需要删除的数据的id
* @return
*/
@GetMapping("/delete")
public String deleteData(String id){
return iDocumentService.deleteDataById(id);
}
/**
* 分词匹配查询content字段
* @param value 查询内容
* @return
*/
@GetMapping("/match")
public List<Document> findMatch(String value){
return iDocumentService.findMatch(value);
}
}
实体类注解
// Lombok 注解,自动为类生成 getter 和 setter 方法
@Data
// 指定 Elasticsearch 索引名及分片数
@IndexName(value = "user_es", shardsNum = 3)
public class User {
/**
* 用户ID
* 使用自定义ID类型
*/
@IndexId(type = IdType.CUSTOMIZE)
private Integer id;
/**
* 用户姓名
* 字段类型为 TEXT,使用 IK 最大词元分词器进行索引和搜索
* 在搜索结果中,匹配的部分将被高亮显示
*/
@IndexField(value = "userName", fieldType = FieldType.TEXT, analyzer = Analyzer.IK_MAX_WORD, searchAnalyzer = Analyzer.IK_MAX_WORD)
@HighLight(preTag = "<span style=\"color:red\">", postTag = "</span>")
private String name;
/**
* 用户年龄
* 字段类型为 INTEGER
*/
@IndexField(fieldType = FieldType.INTEGER)
private Integer age;
/**
* 用户工资
* 字段类型为 DOUBLE
*/
@IndexField(fieldType = FieldType.DOUBLE)
private BigDecimal salary;
/**
* 用户生日
* 字段类型为 DATE
*/
@IndexField(fieldType = FieldType.DATE)
private Date birthday;
}