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

在这个场景中对知识库中文件计数还是比较简单可以实现,只需要进行对数据库查询时增加对知识库空间ID的筛查就可以实现
大致SQL查询语句
SELECT
space_code as code,
COUNT(*) AS code_count
FROM
kb_page
WHERE
type != 'FOLDER'
AND status = 'PUBLISHED'
AND tenant_id = #{tenantId}
AND space_code IN
<foreach collection="spaceCodesList" item="spaceCode" open="(" separator="," close=")">
#{spaceCode}
</foreach>
GROUP BY
space_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二、为什么要这么写
三、函数拆解
四、总结一句话 通过“前后补逗号再精确匹配”的技巧,避免了 LIKE 的模糊误差,从而可靠地判断某条记录的 full_parent_code 里是否包含指定的 folderCode,即该记录是否位于该文件夹之下。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。