前缀文档树:智能文档管理新方案,新增 Tags 面板联动

前缀文档树功能说明

一、核心功能与价值

前缀文档树可自动聚合同名前缀文档,与传统文档树相比:
● 传统文档树:需人工维护层级结构
● 前缀文档树:仅需规范文档命名,自动收集同前缀文档
→ 特别适合管理系列文章(如《如何...》《高中物理...》等)

二、工作原理

1. 前缀匹配规则

● 打开文档时自动扫描工作空间内所有文件
● 筛选与当前文档前缀相同的文件(如打开《高中物理·力学》会显示所有“高中物理”开头的文档)
● 智能显示最长前缀匹配结果
● 以日记为例:

image.png

2. 竖线分级功能

● 用竖线“|”分割文档名创建虚拟层级(例:“物理 | 高中 | 力学”):
→ 系统独立匹配每个关键词段
→ 同系列文档(如“力学 | 物理 | 高中”)打开任意篇即可互相关联

● 分级特性说明(例:“物理 | 高中 | 力学例题集一”):
→ “物理”和“高中”自动加入 tags 面板
→ 最后段“力学例题集一”作为文档显示名

3. Tags 面板联动

● 集中显示所有前缀集合(每个前缀相当于类别标签)
● 点击标签可快速定位该类别中最新更新的文档
● 与前缀文档树协同实现双向管理:
→ 前缀文档树:按名称聚合内容
→ Tags 面板:提供跨类别快速切换

三、技术优势

● 即时响应:前缀匹配操作瞬间完成
● 零维护成本:文档物理存放位置不影响功能

四、最佳实践

配合快速笔记功能

  1. 通过快捷指令创建新文档
  2. 系统自动生成时间目录(例:f2025-06/xx 文档)

→ 双重管理优势:
● 前缀文档树:按内容主题聚合文档
● 时间目录:按创建时间追溯历史版本
● 彻底免除手动维护目录层级的负担

image.png

  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    27807 引用 • 116593 回帖 • 1 关注
3 操作
player 在 2025-07-09 16:28:28 更新了该帖
player 在 2025-07-09 16:27:42 更新了该帖
player 在 2025-06-27 19:01:16 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • suxiang999 1 赞同

    感觉论坛没啥流量的样子呀

    而且分区也挺乱滴,求助、分享、写日记,都显示在一块,帖子容易沉呐

    或许可以尝试广撒网呢,B 站、红书、知乎、甚至百度贴吧,全都发布一遍呢 (・ω・)ノ

  • MasterYS 1 评论

    书签 + 应该也能实现类似功能吧

    1 回复
    不大清楚,应该侧重不同。
    player
  • FlyingY 1 评论

    感觉有点问题,我的日记每个都给我列了前缀,感觉应该设置阈值,前缀少于几篇不进行收集这样,如果显示全部可以在查看页面做一个切换按钮,是按阈值显示还是显示全部

    1 回复
    目前从数量上限制,不从前缀长度限制。如果文档数量少,比如 5、6 个,前缀长度只有 1 也可以显示
    player
  • player

    可以配置显示多少条。另外你点击第其中一个,比如第一个,最后一个,会自动重新扩展两边的前缀文件。

  • wilsons 1 赞同 6 评论

    确实可以

    书签 + 实现

    async function main() { let content = await kit.sql(`select content from blocks where id='{{CurDocId}}'`); content = content[0]?.content; if (content) { // 竖线分级功能 let keywords = content.split('|'); keywords = keywords.map(word => `content like '%${word}%'`); // 前缀匹配规则 let prefixArr = []; let str = content; while (str.length > 0) { prefixArr.push(str); str = str.slice(0, -1); // 每次去掉最后一个字符 } prefixArr = prefixArr.map(word => `content like '${word}%'`); // 合并SQL keywords = [...keywords, ...prefixArr]; const like = keywords.join(' or '); let result = await kit.sql(`select * from blocks where type='d' and id!='{{CurDocId}}' and (${like}) limit 500`); return result.map(block => block.id); } } return main();
    1 回复
    3 操作
    wilsons 在 2025-07-01 22:26:06 更新了该回帖
    wilsons 在 2025-07-01 22:17:25 更新了该回帖
    wilsons 在 2025-07-01 15:35:49 更新了该回帖
    强啊,W 佬
    MasterYS
    @MasterYS 之前仅支持竖线分级功能,现在也支持前缀匹配规则了。
    wilsons
    @wilsons 收到,只要把 let keywords = content.split('|'); 中的 | 替换掉就行了吧
    MasterYS
    @MasterYS 没懂你意思,我之前的版本,前缀匹配会删除 | 分割前的字符,新版去掉了
    wilsons
    @wilsons 我以为是你说,如果把代码里的 | 换成别的特殊符号或者文字,也可以作为分割。
    MasterYS
    @MasterYS 不是,楼主功能有 2 个,前缀匹配规则和竖线分级,现在也实现了 2 个功能,第一版仅支持一个。且我又实现了一个标题分词 +tag 模仿相似文章功能,见最新回复贴。
    wilsons
  • player

    👍

  • 前缀文档树,嵌入块方式实现

    [js] 告别 select * from blocks!嵌入块多字段查询来了

    相似文章(标题分词 +tag 实现)

    [js] 告别 select * from blocks!嵌入块多字段查询来了

    相似文章(书签 + 版)

    // 相似文章 // api see https://api.yesapi.cn/docs-api-App.Scws.GetWords.html const appKey = ''; // 是否使用标签筛选 const useTag = true; async function main() { const doc = await kit.sql(`select content, tag from blocks where id='{{CurDocId}}'`); let content = doc[0]?.content; let tag = doc[0]?.tag; if (content) { // 获取分词 const words = await requestApi('https://hn.api.yesapi.net', {s:'App.Scws.GetWords', return_data:0, yesapi_allow_origin: 1, text: content, app_key: appKey, sign:''}); let keywords = words?.data?.words?.map(word => word?.word) || []; keywords = keywords.map(word => `content like '%${word}%'`); // 生成like sql const like = keywords.join(' or '); // 生成tag sql if(tag && useTag) { const tags = tag.split(/\s+/)?.filter(Boolean); const tagLike = tags.map(tag => `tag like '%${tag}%'`).join(' or '); tag = tags.length > 0 ? `or (${tagLike})` : ''; } let result = await kit.sql(`select * from blocks where type='d' and id!='{{CurDocId}}' and ((${like}) ${tag||''}) order by content limit 500`); return result.map(block => block.id); } } async function requestApi(url, data, method = 'POST') { return await (await fetch(url, {method: method, body: JSON.stringify(data||{})})).json(); } return main();
    1 回复
    1 操作
    wilsons 在 2025-07-02 19:47:28 更新了该回帖
  • player

    👍👍

  • player

    新增 Tags 面板联动

请输入回帖内容 ...