
01 | 版本更新概述
经过极限科技与 Dromara 开源社区下 Easy-Es 项目的紧密合作与共同努力,我们很荣幸地联合推出 Easy-Es 2.1.0-easysearch 版本!
作为双方携手打造的第一个合作成果,本版本已正式发布:
- 源码仓库:https://gitee.com/dromara/easy-es/tree/easy-es4easySearch/
- Maven 依赖:https://mvnrepository.com/artifact/org.dromara.easy-es/easy-es-boot-starter/2.1.0-easysearch
本次更新的核心内容是将 Easy-Es 框架底层增加兼容极限科技自主研发的 Easysearch 搜索引擎,这标志着国产搜索引擎与国内优秀开源项目深度融合的重要里程碑,是极限科技与 Dromara 社区携手共建国产技术生态的创新实践。
02 | 迁移至 Easysearch 的背景与优势
随着国内对自主可控技术需求的日益增长,特别是在基础设施软件领域,企业对于信创合规的要求不断提升。极限科技自主研发的 Easysearch 搜索引擎具备以下显著优势:
- 国产化自主可控:完全自主研发,符合信创要求,无许可证风险,为企业提供安全可靠的技术保障
- 轻量级架构:相比传统搜索引擎,资源占用更少,启动更快速,显著降低企业运维成本
- 卓越性能表现:查询性能优异,能够满足大部分业务场景需求,用户体验流畅
- 良好兼容性:与 Elasticsearch 的 API 接口基本兼容,迁移成本较低,保护用户现有投资
基于以上优势,双方决定共同将 Easy-Es 框架底层迁移至 Easysearch,这不仅为用户提供更多选择,更是双方携手推动国产搜索引擎生态建设的重要举措。
03 | Easy-Es 框架优势
Easy-Es 框架在搜索开发领域具备以下核心优势:
- 极简代码开发:相比原生 API 可减少 50%-80% 的代码量,大幅提升开发效率。
// 使用 Easy-Es 仅需一行代码完成查询
List<Document> documents = documentMapper.selectList(
EsWrappers.lambdaQuery(Document.class).eq(Document::getTitle, "测试")
);
-
自动索引管理: 框架提供全自动智能索引托管功能,开发者无需关心索引的创建、更新及数据迁移等复杂操作,索引全生命周期由框架自动管理,过程零停机。
-
SQL 语法兼容: 支持使用 MySQL 语法完成搜索查询操作,无需学习复杂的 DSL 语句。支持 and、or、like、in 等常用 SQL 语法。
-
Lambda 表达式支持: 采用 Lambda 风格编程,提供类型安全的字段访问,避免手动输入字段名可能产生的错误,提升代码可读性和开发效率。
-
无缝 Spring Boot 集成: 与 Spring Boot 生态深度集成,提供开箱即用的自动配置,无需复杂的手动配置,支持 Spring Boot Actuator 监控,完美融入企业级应用架构。
-
丰富的查询功能: 支持复杂的嵌套查询、聚合查询、范围查询、高亮显示等高级搜索功能,同时保持 API 的简洁易用,满足各种业务场景需求。
-
分布式架构支持: 完美适配 Easysearch 的分布式特性,支持集群模式部署,具备高可用性和横向扩展能力,满足企业级大规模数据处理需求。
- 成熟稳定的国产 ORM 框架: 作为 Dromara 开源社区下的顶级开源项目,Easy-Es 已在国内众多企业和项目中得到广泛应用和验证,拥有活跃的中文社区和完善的文档支持,为企业级应用提供了可靠的技术保障。
04 | 快速上手示例
1. 添加依赖
根据您使用的构建工具,选择对应的配置方式:
Maven 项目
pom.xml 配置:
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<spring-boot.version>2.7.0</spring-boot.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.dromara.easy-es</groupId>
<artifactId>easy-es-boot-starter</artifactId>
<version>2.1.0-easysearch</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Maven 启动命令:
# 运行应用
mvn spring-boot:run
# 编译打包
mvn clean package
Gradle 项目
build.gradle 配置:
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
}
group = 'org.easysearch'
version = '1.0-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
implementation 'org.dromara.easy-es:easy-es-boot-starter:2.1.0-easysearch'
implementation 'org.springframework.boot:spring-boot-starter-web'
}
Gradle 启动命令:
# 运行应用
./gradlew bootRun
# 编译打包
./gradlew clean build
2. 配置文件设置
application.yml(根据实际 Easysearch 部署情况修改):
easy-es:
enable: true
# Easysearch 服务地址
address: localhost:9200
# 协议:http 或 https
schema: https
# Easysearch 用户名
username: admin
# Easysearch 密码
password: your_password_here
# 连接保持时间(毫秒)
keep-alive-millis: 18000
global-config:
# 开启彩蛋模式(启动时显示 ASCII 艺术图案)
i-kun-mode: true
# 索引处理模式:smoothly 表示平滑模式(零停机更新索引)
process-index-mode: smoothly
# 异步处理索引时是否阻塞
async-process-index-blocking: true
# 是否打印 DSL 语句(开发调试时可设为 true)
print-dsl: false
db-config:
# 下划线转驼峰
map-underscore-to-camel-case: true
# 索引前缀
index-prefix: dev_
# 主键类型:customize 表示自定义
id-type: customize
# 字段更新策略:not_empty 表示非空时才更新
field-strategy: not_empty
# 刷新策略:immediate 表示立即刷新
refresh-policy: immediate
# 开启追踪总命中数
enable-track-total-hits: true
3. 实体类定义
package org.dromara.easyes.sample.entity;
import lombok.Data;
import lombok.experimental.Accessors;
import org.dromara.easyes.annotation.HighLight;
import org.dromara.easyes.annotation.IndexField;
import org.dromara.easyes.annotation.IndexId;
import org.dromara.easyes.annotation.IndexName;
import org.dromara.easyes.annotation.Settings;
import org.dromara.easyes.annotation.rely.Analyzer;
import org.dromara.easyes.annotation.rely.FieldStrategy;
import org.dromara.easyes.annotation.rely.FieldType;
import org.dromara.easyes.annotation.rely.IdType;
import java.time.LocalDateTime;
/**
* es 数据模型
*/
@Data
@Accessors(chain = true)
@Settings(shardsNum = 3, replicasNum = 2)
@IndexName(value = "easyes_document", keepGlobalPrefix = true)
public class Document {
/**
* es 中的唯一 id
*/
@IndexId(type = IdType.CUSTOMIZE)
private String id;
/**
* 文档标题,默认为 keyword 类型,可进行精确查询
*/
private String title;
/**
* 文档内容,指定为 TEXT 类型,使用 IK 分词器
* 支持高亮显示,高亮结果映射到 highlightContent 字段
*/
@HighLight(mappingField = "highlightContent")
@IndexField(fieldType = FieldType.TEXT, analyzer = Analyzer.IK_SMART)
private String content;
/**
* 创建者,字段策略为非空时才更新
*/
@IndexField(strategy = FieldStrategy.NOT_EMPTY)
private String creator;
/**
* 创建时间
*/
@IndexField(fieldType = FieldType.DATE, dateFormat = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime gmtCreate;
/**
* 高亮返回值被映射的字段
*/
private String highlightContent;
/**
* 文档点赞数
*/
private Integer starNum;
/**
* 地理位置经纬度坐标,例如: "40.13933715136454,116.63441990026217"
*/
@IndexField(fieldType = FieldType.GEO_POINT)
private String location;
}
4. Mapper 接口
package org.dromara.easyes.sample.mapper;
import org.dromara.easyes.core.kernel.BaseEsMapper;
import org.dromara.easyes.sample.entity.Document;
/**
* Mapper 接口,继承 BaseEsMapper 即可获得所有 CRUD 方法
*/
public interface DocumentMapper extends BaseEsMapper<Document> {
}
5. 启动类配置
package org.dromara.easyes.sample;
import org.dromara.easyes.spring.annotation.EsMapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 启动类
*/
@SpringBootApplication
@EsMapperScan("org.dromara.easyes.sample.mapper")
public class EasyEsApplication {
public static void main(String[] args) {
SpringApplication.run(EasyEsApplication.class, args);
}
}
6. 业务使用示例
package org.dromara.easyes.sample.controller;
import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
import org.dromara.easyes.sample.entity.Document;
import org.dromara.easyes.sample.mapper.DocumentMapper;
import org.easysearch.action.search.SearchResponse;
import org.easysearch.search.aggregations.Aggregations;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
@RestController
public class SampleController {
@Resource
private DocumentMapper documentMapper;
/**
* 初始化插入数据
*/
@GetMapping("/insert")
public Integer insert() {
int count = 0;
// 插入 5 条测试数据
for (int i = 1; i <= 5; i++) {
Document document = new Document();
document.setId(String.valueOf(i));
document.setTitle("测试" + i);
document.setContent("测试内容" + i);
document.setCreator("创建者" + i);
document.setGmtCreate(LocalDateTime.now());
document.setStarNum(i * 10);
count += documentMapper.insert(document);
}
return count;
}
/**
* 根据标题精确查询
*/
@GetMapping("/listDocumentByTitle")
public List<Document> listDocumentByTitle(@RequestParam String title) {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.eq(Document::getTitle, title);
return documentMapper.selectList(wrapper);
}
/**
* 高亮搜索
*/
@GetMapping("/highlightSearch")
public List<Document> highlightSearch(@RequestParam String content) {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.match(Document::getContent, content);
return documentMapper.selectList(wrapper);
}
/**
* 查询所有数据
*/
@GetMapping("/selectAll")
public List<Document> selectAll() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
return documentMapper.selectList(wrapper);
}
/**
* 聚合查询 - 按创建时间和点赞数分组统计
*/
@GetMapping("/aggByDateAndStar")
public Aggregations aggByDateAndStar() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.groupBy(Document::getGmtCreate)
.max(Document::getStarNum)
.min(Document::getStarNum);
SearchResponse response = documentMapper.search(wrapper);
return response.getAggregations();
}
/**
* 使用 SQL 语句查询文档
*/
@GetMapping("/queryBySQL")
public String queryBySQL(@RequestParam(required = false) String title) {
String sql;
if (title != null && !title.isEmpty()) {
sql = String.format("SELECT * FROM dev_easyes_document WHERE title = '%s'", title);
} else {
sql = "SELECT * FROM dev_easyes_document LIMIT 10";
}
return documentMapper.executeSQL(sql);
}
}
7. 快速测试
启动应用后,可以通过以下接口测试:
# 1. 插入测试数据
curl http://localhost:8080/insert
# 2. 查询所有数据
curl http://localhost:8080/selectAll
# 3. 根据标题精确查询
curl "http://localhost:8080/listDocumentByTitle?title=测试1"
# 4. 高亮搜索
curl "http://localhost:8080/highlightSearch?content=测试"
# 5. SQL 查询
curl "http://localhost:8080/queryBySQL?title=测试1"
# 6. 聚合查询
curl http://localhost:8080/aggByDateAndStar
05 | 相关链接
- Easy-Es 官方网站:https://easy-es.cn
- Gitee 仓库:https://gitee.com/dromara/easy-es
- GitHub 仓库:https://github.com/dromara/easy-es
- Easysearch 官方网站:https://infinilabs.cn/products/easysearch
06 | 特别致谢
在此,极限科技要特别感谢 Easy-Es 项目的核心开发者“老汉”和各位贡献者和维护者们。正是因为有了你们的辛勤付出、专业精神以及对开源事业的热忱奉献,Easy-Es 项目才能在国内外获得如此广泛的认可和应用。
也感谢你们对国产技术生态建设的信任与支持。此次 Easy-Es 与 Easysearch 的深度整合,正是双方通力合作、互利共赢的最佳体现。
我们相信,在 Easy-Es 项目团队的持续推动下,国产开源软件必将迎来更加辉煌的明天。极限科技将继续致力于提供优质的国产技术解决方案,与 Easy-Es 项目团队携手共进,为中国开源生态的发展贡献更多力量!
关于 Easy-Es
Easy-Es(简称 EE)是一款基于 Elasticsearch(简称 ES)官方提供的 ElasticsearchClient 打造的 ORM 开发框架,在 ElasticsearchClient 的基础上,只做增强不做改变,为简化开发、提高效率而生,您如果有用过 Mybatis-Plus(简称 MP),那么您基本可以零学习成本直接上手 EE,EE 是 MP 的 ES 平替版,在有些方面甚至比 MP 更简单,同时也融入了更多 ES 独有的功能,助力您快速实现各种场景的开发。
Easy-Es for Easysearch 是一款简化 Easysearch 国产化搜索引擎操作的开源框架,全自动智能索引托管。同时也是国内首家专门针对 Easysearch 客户端简化的工具。它简化 CRUD 及其它高阶操作,可以更好的帮助开发者减轻开发负担。底层采用 Easysearch Java Client,保证其原生性能及拓展性。
项目地址:https://gitee.com/dromara/easy-es/tree/easy-es4easySearch
关于极限科技
极限科技(全称:极限数据(北京)科技有限公司)是一家专注于实时搜索与数据分析的软件公司。
旗下品牌:极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验,为用户提供安全、稳定、高性能的国产搜索解决方案。
作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。
本文地址:http://elasticsearch.cn/article/15626