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

如何优雅统计知识库文件个数与子集下不同文件夹文件个数

简单场景:存在一个知识库,需要统计知识库下文件的个数

在这个场景中对知识库中文件计数还是比较简单可以实现,只需要进行对数据库查询时增加对知识库空间ID的筛查就可以实现

大致SQL查询语句

        SELECTspace_code as code,COUNT(*) AS code_countFROMkb_pageWHEREtype != 'FOLDER'AND status = 'PUBLISHED'AND tenant_id = #{tenantId}AND space_code IN<foreach collection="spaceCodesList" item="spaceCode" open="(" separator="," close=")">#{spaceCode}</foreach>GROUP BYspace_code;

现在有一个新的场景,需要统计在每个知识库下,存在不同层级的文件夹📁,需要统计不同层级文件夹下文件的个数,如何进行实现?

最开始考虑的是,文件夹能实现父子级别关联,数据库会存在一个code和parentCode进行关联。可以通过递归的方式进行深度检索,从而计算出不同文件夹下的文件个数。但是这个方案会存在性能问题,假如文件夹数量和层级众多,不是特别可行。

最终采取的计数方案是,数据库中存在一个对每一个文件都拥有一个全路径编码,不管当前文件的类型是word,excel,ppt,md等等等等。都会为其生成一个全路径编码,例如:1111,2222,3333,4444. 这个编码意味着当前该文件的级别是在第四级。

交代完上述的方案设计,如何进行代码层面的计数实现:

            for (PageTreeResp item : result) {if (PageTypes.FOLDER.name().equals(item.getType())) {int fileCount = countFilesByFullParentCode(item.getCode(), item.getSpaceCode(), sysUserInfo.getTenantId());item.setCodeCount(String.valueOf(fileCount));}}## 具体的代码计算逻辑/*** 使用数据库 full_parent_code 统计文件夹下所有子孙文件数量(排除文件夹本身,type != FOLDER)* 保证同一租户、同一空间内统计。*/private int countFilesByFullParentCode(String folderCode, String spaceCode, String tenantId) {LambdaQueryWrapper<KbPage> wrapper = new LambdaQueryWrapper<>();wrapper.eq(KbPage::getTenantId, tenantId);wrapper.eq(KbPage::getSpaceCode, spaceCode);wrapper.eq(KbPage::getStatus, KBPageStatus.PUBLISHED.name());// full_parent_code 中以逗号分隔父级编码,使用分隔符匹配避免误匹配wrapper.apply("INSTR(CONCAT(',', full_parent_code, ','), CONCAT(',', {0}, ',')) > 0", folderCode);// 只统计非文件夹类型wrapper.ne(KbPage::getType, KbPageTypes.FOLDER.name());return Math.toIntExact(kbPageMapper.selectCount(wrapper));}

上述查询逻辑的详细解析

一、先看整体 SQL 生成出来长什么样
假设
folderCode = “abc”
full_parent_code 里存的值是 “root,abc,xyz”

那么这一行最终被拼成:

-- 伪 SQL
WHERE ...AND INSTR(CONCAT(',', full_parent_code, ','), ',abc,') > 0

二、为什么要这么写

  1. full_parent_code 存的是“从根到当前节点”的父节点编码,用英文逗号分隔,例如:
    root,abc,xyz
  2. 需求:找出“abc”这个文件夹下面的所有子孙节点(包括子文件夹里的文件)。
    换句话说只要 full_parent_code 里出现过 abc 就算命中。
  3. 如果直接写简单的 LIKE ‘%abc%’,当存在编码为 abc1、xabc 等节点时也会被错误匹配(模糊匹配会把包含子串的都选出来)。
  4. 因此把两端也补上逗号,再匹配 “,abc,” 就能保证只匹配完整的一段编码,不会误伤。

三、函数拆解

  • CONCAT(‘,’, full_parent_code, ‘,’)
    给原来的字符串前后各加一个逗号 → “,root,abc,xyz,”

  • CONSTR(‘,’, {0}, ‘,’)
    把传入的 folderCode 前后也加逗号 → “,abc,”

  • INSTR(str, substr)
    MySQL 内置函数:返回 substr 在 str 中第一次出现的位置(从 1 开始计数),找不到则返回 0。

  • INSTR(…) > 0
    只要大于 0 就说明找到了,于是这条记录就是 folderCode 的子孙。

四、总结一句话
通过“前后补逗号再精确匹配”的技巧,避免了 LIKE 的模糊误差,从而可靠地判断某条记录的 full_parent_code 里是否包含指定的 folderCode,即该记录是否位于该文件夹之下。

http://www.dtcms.com/a/344276.html

相关文章:

  • Vue3源码reactivity响应式篇之Ref
  • Oracle APEX 经典报表中的Checkbox
  • 期货Level2五档订单簿0.25秒级高频分时及日频历史行情数据使用指南
  • Docker 部署 MySQL 8.0 完整指南:从拉取镜像到配置远程访问
  • 高级SQL优化 | 告别 Hive 中 GROUP BY 的大 KEY 数据倾斜!PawSQL 自适应优化算法详解
  • MsSQL 函数,实现数字转换成人民币大写
  • IDEA基础配置优化指南(中英双版)
  • matlab中随机森林算法的实现
  • AI重塑职业教育:个性化学习计划提效率、VR实操模拟强技能,对接就业新路径
  • 在Excel和WPS表格中如何隐藏单元格的公式
  • 视觉语言对比学习的发展史:从CLIP、BLIP、BLIP2、InstructBLIP(含MiniGPT4的详解)
  • 一分钟了解六通道 CAN(FD) 集线器
  • 第二阶段WinFrom-6:文件对话框,对象的本地保存,序列化与反序列化,CSV文件操作,INI文件读写
  • 【虚拟化】磁盘置备方式的性能损耗对比
  • k8s应用的包管理Helm工具
  • 基于国产麒麟操作系统的Web数据可视化教学解决方案
  • 【Java SE】深入理解继承与多态
  • 使用 YAML 文件,如何优雅地删除 k8s 资源?
  • Apache Druid SSRF漏洞复现(CVE-2025-27888)
  • 孤独伤感视频素材哪里找?分享热门伤感短视频素材资源网站
  • Sklearn 机器学习 房价预估 使用GBDT训练模型
  • 【Linux我做主】细说进程地址空间
  • Ansible入门:自动化运维基础
  • docker 打包
  • 前端项目打包+自动压缩打包文件+自动上传部署远程服务器
  • 设计模式笔记
  • 开题报告被退回?用《基于大数据的慢性肾病数据可视化分析系统》的Hadoop技术,一次通过不是梦
  • Matplotlib 可视化大师系列(五):plt.pie() - 展示组成部分的饼图
  • 故障诊断:基于大模型的实现方法与开源实践(从入门到精通)
  • Matplotlib 可视化大师系列(一):plt.plot() - 绘制折线图的利刃