当前位置: 首页 > news >正文

【ES】【实战】----index索引数量过大,后缀加日期处理 实战过程 xxxx_20250906

前言:

要实现按天创建索引(如article_20250906)的需求,我们需要通过 Easy-Es 的索引名称处理器来动态生成索引名。以下是具体实现方案:

1. 自定义索引名称处理器

packagecom.zgb.config;importorg.dromara.easyes.core.handler.IndexNameHandler;importjava.time.LocalDate;importjava.time.format.DateTimeFormatter;/** * 文章索引名称处理器 * 实现按天动态生成索引名,格式为: article_yyyyMMdd * @author 架构师 */publicclassArticleIndexNameHandlerimplementsIndexNameHandler{/** * 动态生成索引名称 * @return 格式化后的索引名称 */@OverridepublicStringdynamicIndexName(){// 获取当前日期并格式化为yyyyMMddStringdateSuffix=LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));// 返回拼接后的索引名return"article_"+dateSuffix;}}

2. 修改实体类的索引配置

在你提供的Article实体类上添加动态索引处理器配置:

packagecom.zgb.entity;importcom.fasterxml.jackson.annotation.JsonFormat;importcom.zgb.config.ArticleIndexNameHandler;importlombok.Data;importorg.dromara.easyes.annotation.*;importorg.dromara.easyes.annotation.rely.FieldType;importjava.time.LocalDateTime;importjava.util.List;/** * 文章索引实体类 * 按天创建索引,格式为article_yyyyMMdd * @author 架构师 */@Data@IndexName(value="article",// 基础索引名dynamicIndexHandler=ArticleIndexNameHandler.class,// 指定动态索引处理器keepGlobalPrefix=false// 不保留全局前缀,使用处理器生成的完整名称)publicclassArticle{/** * 文章ID */@IdprivateStringid;/** * 文章标题 * 分词,可搜索,权重较高 */@HighLight(mappingField="titleHighLight")// 高亮配置@IndexField(fieldType=FieldType.TEXT,analyzer="ik_max_word",searchAnalyzer="ik_smart",boost=2.0f)privateStringtitle;/** * 标题高亮结果 */privateStringtitleHighLight;/** * 文章内容 * 分词,可搜索 */@HighLight(mappingField="contentHighLight")@IndexField(fieldType=FieldType.TEXT,analyzer="ik_max_word",searchAnalyzer="ik_smart")privateStringcontent;/** * 内容高亮结果 */privateStringcontentHighLight;/** * 文章摘要 */@IndexField(fieldType=FieldType.TEXT,analyzer="ik_max_word")privateStringsummary;/** * 文章作者 */@IndexField(fieldType=FieldType.KEYWORD)privateStringauthor;/** * 创建时间 */@IndexField(fieldType=FieldType.DATE,dateFormat="yyyy-MM-dd HH:mm:ss")@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")privateLocalDateTimecreateTime;/** * 文章类型 * 如: 原创、转载、翻译 */@IndexField(fieldType=FieldType.KEYWORD)privateStringtype;/** * 文章标签 */@IndexField(fieldType=FieldType.KEYWORD)privateList<String>tags;/** * 点赞数 */@IndexField(fieldType=FieldType.INTEGER)privateIntegerlikeCount;/** * 分享数 */@IndexField(fieldType=FieldType.INTEGER)privateIntegershareCount;/** * 预览数 */@IndexField(fieldType=FieldType.INTEGER)privateIntegerviewCount;}

3. 配置文件调整

spring:easy-es:enable:trueaddress:127.0.0.1:9200# 单机版配置,分布式版使用逗号分隔多个地址username:elasticpassword:123456connection-timeout:5000socket-timeout:30000global-config:process-index-name:false# 关闭全局处理,由自定义处理器接管db-config:id-type:custom# 自定义ID生成策略# 不设置table-prefix,避免与动态索引名冲突

4. 索引管理工具类

packagecom.zgb.util;importcom.zgb.entity.Article;importorg.dromara.easyes.core.biz.EsIndexParam;importorg.dromara.easyes.core.manager.IndexManager;importorg.springframework.stereotype.Component;importjavax.annotation.Resource;importjava.time.LocalDate;importjava.time.format.DateTimeFormatter;/** * 文章索引管理工具类 * 用于创建和管理按天分割的文章索引 * @author 架构师 */@ComponentpublicclassArticleIndexManager{@ResourceprivateIndexManagerindexManager;/** * 创建指定日期的文章索引 * @param date 指定日期 * @return 是否创建成功 */publicbooleancreateIndex(LocalDatedate){StringindexName="article_"+date.format(DateTimeFormatter.ofPattern("yyyyMMdd"));// 构建索引参数,使用提供的Article实体类EsIndexParamesIndexParam=EsIndexParam.builder().indexName(indexName).clazz(Article.class)// 关联实体类,确保映射关系正确.build();// 创建索引returnindexManager.createIndex(esIndexParam);}/** * 创建今天的文章索引 * @return 是否创建成功 */publicbooleancreateTodayIndex(){returncreateIndex(LocalDate.now());}/** * 删除指定日期的文章索引 * @param date 指定日期 * @return 是否删除成功 */publicbooleandeleteIndex(LocalDatedate){StringindexName="article_"+date.format(DateTimeFormatter.ofPattern("yyyyMMdd"));returnindexManager.deleteIndex(indexName);}/** * 判断指定日期的索引是否存在 * @param date 指定日期 * @return 是否存在 */publicbooleanexistsIndex(LocalDatedate){StringindexName="article_"+date.format(DateTimeFormatter.ofPattern("yyyyMMdd"));returnindexManager.existsIndex(indexName);}}

5. 定时任务自动创建索引 IndexAutoCreateTask

packagecom.zgb.task;importcom.zgb.util.ArticleIndexManager;importlombok.RequiredArgsConstructor;importorg.springframework.scheduling.annotation.Scheduled;importorg.springframework.stereotype.Component;/** * 索引自动创建定时任务 * 确保每天都有对应的索引可用 * @author 架构师 */@Component@RequiredArgsConstructorpublicclassIndexAutoCreateTask{privatefinalArticleIndexManagerindexManager;/** * 每天凌晨1点创建当天的索引 * 防止当天第一次插入数据时才创建索引可能带来的性能问题 */@Scheduled(cron="0 0 1 * * ?")publicvoidcreateTodayIndex(){// 先判断索引是否已存在,避免重复创建if(!indexManager.existsIndex(LocalDate.now())){booleanresult=indexManager.createTodayIndex();if(result){System.out.println("成功创建当天文章索引: article_"+LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")));}else{System.err.println("创建当天文章索引失败");}}}}

6. 按日期范围查询的Service实现

/** * 按日期范围查询文章 * @param keyword 搜索关键词 * @param startDate 开始日期 * @param endDate 结束日期 * @param pageNum 页码 * @param pageSize 每页条数 * @return 分页结果 */publicPageInfo<Article>searchByDateRange(Stringkeyword,LocalDatestartDate,LocalDateendDate,IntegerpageNum,IntegerpageSize){// 构建查询条件LambdaEsQueryWrapper<Article>wrapper=newLambdaEsQueryWrapper<>();// 设置关键词匹配(标题、内容或摘要)if(keyword!=null&&!keyword.isEmpty()){wrapper.match(Article::getTitle,keyword).or().match(Article::getContent,keyword).or().match(Article::getSummary,keyword);}// 处理日期范围索引查询if(startDate!=null&&endDate!=null){// 构建索引名称通配符StringstartMonth=startDate.format(DateTimeFormatter.ofPattern("yyyyMM"));StringendMonth=endDate.format(DateTimeFormatter.ofPattern("yyyyMM"));if(startMonth.equals(endMonth)){// 同一月份,使用更精确的通配符wrapper.index("article_"+startMonth+"*");}else{// 跨月份,使用年份通配符Stringyear=startDate.format(DateTimeFormatter.ofPattern("yyyy"));wrapper.index("article_"+year+"*");}// 同时添加创建时间过滤,确保数据准确性wrapper.ge(Article::getCreateTime,startDate.atStartOfDay()).le(Article::getCreateTime,endDate.atTime(23,59,59));}elseif(startDate!=null){// 只指定开始日期wrapper.index("article_"+startDate.format(DateTimeFormatter.ofPattern("yyyyMM"))+"*").ge(Article::getCreateTime,startDate.atStartOfDay());}elseif(endDate!=null){// 只指定结束日期wrapper.index("article_"+endDate.format(DateTimeFormatter.ofPattern("yyyyMM"))+"*").le(Article::getCreateTime,endDate.atTime(23,59,59));}// 按点赞数和创建时间排序wrapper.orderByDesc(Article::getLikeCount).orderByDesc(Article::getCreateTime);// 执行查询returnarticleEsMapper.pageQuery(wrapper,pageNum,pageSize);}

实现说明

  1. 索引动态生成:通过ArticleIndexNameHandler实现了按天生成索引名的功能,与你提供的Article实体类完美结合

  2. 索引管理

    • 工具类ArticleIndexManager专门用于管理按天创建的索引
    • 定时任务确保每天凌晨自动创建当天索引,避免业务高峰期创建索引影响性能
  3. 查询优化

    • 单天查询自动使用当天索引(如article_20250906
    • 跨天查询使用通配符匹配多个索引,并结合创建时间过滤保证数据准确性
    • 保持了原有实体类的所有字段和注解配置,不影响原有的搜索功能

这种实现方式既满足了按天分割索引的需求,又完整保留了你提供的Article实体类的所有特性,包括字段映射、分词策略和高亮配置等。

http://www.jsqmd.com/news/317432/

相关文章:

  • c++的RAII
  • 2026深圳办公室出租推荐:产业园区与电商孵化空间深度解析
  • 2026年湖北旅游攻略路线推荐:深度评测与排名,涵盖自然与人文场景核心痛点
  • 2026年当下知名的推拉窗设计需要多少钱,六轨断桥推拉窗/门窗/安全门窗/断桥铝门窗,推拉窗直销厂家选哪家
  • 2026年1月安徽高端偶联剂/钛酸酯偶联剂/钛酸异丙酯/交联剂/钛酸酯交联剂/钛酸正丁酯采购终极指南:赋能材料未来
  • 2026年快充充电宝品牌推荐与深度解析:便携大容量安全选购权威指南
  • Nodejs+vue微信小程序的大学生专业认证考试资源共享平台
  • 大模型Memory系统完全指南:从技术原理到工程实践的全面解析(建议收藏)
  • Nodejs+vue志愿者活动报名服务小程序设计与开发
  • 从零开始学大模型评估:DeepResearchEval框架全面解析与实战(收藏必学)
  • 大视觉语言模型完全指南:多模态虚假新闻检测技术详解与学习路径
  • 微调之后还能做什么?大模型后训练完全指南:从理论到实践,小白也能懂
  • 强烈安利9个AI论文软件,本科生轻松搞定毕业论文!
  • 2026年选矿设备厂家推荐:基于多场景实测评价,解决效率与兼容性核心痛点
  • 亲测好用!继续教育10款一键生成论文工具深度测评
  • 2026 最新液位计/变送器/传感器/过程仪表/流量计品牌 TOP5 评测!技术赋能工业精准测控,权威榜单发布
  • 2026年高性价比健身教练培训基地有哪些?
  • 2026年选矿设备厂家推荐:技术趋势与合规标准评价,针对能耗与安全痛点指南
  • 冷轧钢带生产厂选哪家好,深入分析优质企业
  • Python接口测试实践:参数化测试、数据驱动测试和断言的使用
  • 一文教你Jenkins整合Jmeter实现自动化接口测试
  • 易卡随行:JAVA打造智能名片管理新体验
  • 2026年学习桌椅终极选型指南:TOP5品牌双升降能力与门店售后深度测评
  • 国产操作系统全解析:深度认识银河麒麟系统及其与Windows的本质差异
  • 企业破产重整律师事务所费用怎么收,为你盘点靠谱品牌
  • 2026年度必选优质叶黄素品牌TOP10推荐,好用易吸收不踩雷,照选难踩坑!
  • 学术诚信护城河:paperzz 论文查重如何让你的论文告别重复率焦虑
  • JAVA赋能易卡随行:重构名片管理新生态
  • 2026年温室大棚厂家推荐:农业生产趋势评测,涵盖智能与节能场景痛点
  • 汉堡王在哪里点更便宜?2026全攻略