在之前的项目中,我们实现了一个名为
lucene-plus
的组件,用以封装lucene,并使其与Spring Boot框架集成。然而,在实际使用过程中,我们发现lucene-plus
的架构设计存在诸多不足,不符合日常开发习惯,更重要的是它缺乏数据在多节点间的同步机制。虽然网络磁盘等技术提供了一种可能的解决方案,但我们认为这不是最优的方案。因此,我们决定重新设计并实现一个名为lucene-candy
的新组件,提高团队的使用体验,同时也尝试寻求lucene实例数据同步的新方案。
lucene-candy的核心功能
实体与索引的ORM映射:
lucene-candy为开发者提供了实体与索引之间的ORM映射功能,这意味着开发者无需关心如何将实体对象转换为Lucene的Document对象,以及如何将搜索结果映射回实体对象。Lucene-Candy会自动处理这些转换过程,大大降低了开发者的学习成本和使用门槛。简化lucene API:
lucene-candy对Lucene的增删改查API进行了简化封装,使得开发者能够更加方便地使用Lucene的各种功能。同时,Lucene-Candy还实现了自动化管理Lucene的Reader/Writer,确保索引的稳定性和一致性。多节点数据同步方案:
lucene-candy提供了两套完整的多节点数据同步方案,确保在多个节点上运行的lucene实例能够保持数据的一致性。配置如下:
lucene-candy:
data-sync: default #数据同步方式:default、tcc、msg(选填)
如何使用lucene-candy
使用lucene-candy非常简单,只需要在Spring Boot项目中引入相关的依赖,并进行简单的配置即可。下面是一个简单的示例:
- 引入依赖:
<dependency>
<groupId>cn.juque</groupId>
<artifactId>lucene-candy</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
- 在application-*.yml添加配置(单节点可以忽略所有的选填项):
lucene-candy:
data-path: D:\\candy\\ # 存放数据的目录(必填)
secret: 123456fdew # 多实例的情况下,实例的可信赖凭据(选填)
ip-protocol: http # 数据同步的http 或https协议(选填)
ip: 127.0.0.1:8080 # 指定当前实例的ip端口(必填)
ip-cluster: '' # 多实例情况下,其他实例的ip端口(选填)
data-sync: default #数据同步方式:default、tcc、msg(选填)
- 定义实体,注解@Index绑定指定的索引,注解@Field绑定指定的文档字段:
package cn.juque.lucenecandy.entity;
import cn.juque.lucenecandy.core.annotation.Field;
import cn.juque.lucenecandy.core.annotation.Index;
import cn.juque.lucenecandy.core.base.BaseEntity;
import cn.juque.lucenecandy.core.enums.DataTypeEnum;
import lombok.Data;
@Data
@Index(value = "jdf_config_info")
public class ConfigInfo extends BaseEntity {
/**
* 配置名称
*/
@Field(value = "config_name")
private String configName;
/**
* 域
*/
@Field(value = "scope")
private Integer scope;
/**
* 配置编码
*/
@Field(value = "config_code")
private String configCode;
/**
* 配置值
*/
@Field(value = "config_value")
private String configValue;
/**
* 有效标识
*/
@Field(value = "valid_flag", type = DataTypeEnum.INT)
private Integer validFlag;
/**
* 是否允许同步
*/
@Field(value = "sync_flag", type = DataTypeEnum.INT)
private Integer syncFlag;
/**
* 备注
*/
@Field(value = "remark")
private String remark;
}
- 新增操作
ConfigInfo configInfo = new ConfigInfo();
configInfo.setId(IdUtil.fastSimpleUUID());
configInfo.setConfigName("bb");
configInfo.setConfigCode("bb45");
configInfo = this.indexHelper.addDocument(configInfo);
Assert.assertTrue(configInfo.getVersion() > 0);
*更新操作
ConfigInfo configInfo = new ConfigInfo();
configInfo.setId(ID);
configInfo.setConfigName("哈哈哈");
configInfo.setConfigCode("bb45");
this.indexHelper.updateDocumentById(configInfo);
- 删除操作
DeleteByIdsWrapperBuilder<ConfigInfo> deleteByIdsWrapperBuilder = new DeleteByIdsWrapperBuilder<>(ConfigInfo.class, CollUtil.newArrayList("1"));
this.indexHelper.deleteByIds(deleteByIdsWrapperBuilder.build());
- 查询操作
QueryWrapperBuilder<ConfigInfo> builder = new QueryWrapperBuilder<>(ConfigInfo.class);
List<ConfigInfo> list = this.indexHelper.search(builder.build());
Assert.assertTrue(CollUtil.isNotEmpty(list));
- 分页查询操作
PageInfo pageInfo = new PageInfo();
pageInfo.setPage(1);
pageInfo.setLimit(10);
QueryWrapperBuilder<ConfigInfo> builder = new QueryWrapperBuilder<>(ConfigInfo.class);
builder
.pageInfo(pageInfo)
.matchStr(ConfigInfo::getConfigName, "bb", MatchTypeEnum.TERM, BooleanClause.Occur.MUST)
.addField(ConfigInfo::getConfigName, ConfigInfo::getConfigCode);
List<ConfigInfo> list = this.indexHelper.searchByPage(builder.build());
Assert.assertTrue(CollUtil.isNotEmpty(list));
在上述示例中,IndexHelper
是lucene-candy提供的一个核心类,它封装了与lucene的交互逻辑,包括索引的创建、文档的添加、搜索以及删除等。开发者只需要通过IndexHelper
来操作实体对象,无需关心底层的Lucene细节。