| name | siyuan-notes |
| description | 思源笔记查询工具,如果用户的请求涉及查找、检索、浏览他们的笔记内容,就应该使用这个技能,例如:查询我的xxx |
技能使用指南
推荐调用方式
方式1:使用Bash工具
node index.js search "工作总结" 10
node index.js recent 7
node index.js check
方式2:使用node -e执行JS代码(使用显示的 skill Base directory 作为 cwd)
node -e "
const siyuan = require('./index.js');
(async () => {
const results = await siyuan.searchNotes('工作总结', 10);
console.log(siyuan.formatResults(results));
})();
"
注意事项:
- 直接执行index.js时:会自动从其所在目录加载.env文件,无需特殊路径处理
- 使用node -e时:用技能执行时显示的 "Base directory for this skill" 路径作为cwd参数
- 路径中包含空格时需要引号
- 不要用cd命令,直接用cwd参数控制工作目录
- 尽可能使用 node -e执行而非创建临时 js 文件
快速使用指南
核心 API 函数
const siyuan = require('./index.js');
await siyuan.searchNotes('关键词', 20, 'p');
await siyuan.searchNotes('关键词', 10, 'h');
await siyuan.getRecentBlocks(7, 'updated');
await siyuan.searchTasks('[ ]', 7);
siyuan.formatResults(results);
常见查询场景
1. 搜索工作总结/开发内容
await siyuan.searchNotes('工作', 15);
await siyuan.searchNotes('开发', 10);
await siyuan.searchNotes('总结', 10, 'h');
await siyuan.getRecentBlocks(7, 'updated');
2. 任务管理
await siyuan.searchTasks('[ ]', 7);
await siyuan.searchTasks('[x]', 30);
await siyuan.searchTasks('', 7);
3. 文档导航
await siyuan.listDocuments();
await siyuan.getDocumentBlocks('文档ID');
await siyuan.getDocumentHeadings('文档ID');
4. 标签和引用
await siyuan.searchByTag('重要', 10);
await siyuan.getBacklinks('块ID', 20);
命令行使用
node index.js search "工作" 10
node index.js search "总结" 5 h
node index.js recent 7
node index.js recent 14 p
node index.js tasks "[ ]" 7
node index.js docs
node index.js tag "重要"
查询策略选择
何时使用 API 函数
- 简单搜索: 单个关键词搜索
- 常规查询: 获取最近内容、文档列表等
- 快速原型: 验证查询思路
- 标准化操作: 任务管理、标签查询等
何时使用 SQL
- 复杂条件: 多个 AND/OR 条件组合
- 跨表查询: 需要 JOIN 多个表
- 统计分析: COUNT、AVG、GROUP BY 等
- 性能优化: 需要精确控制查询逻辑
实际应用示例
查找工作总结 (混合策略)
const siyuan = require('./index.js');
const workResults = await siyuan.searchNotes('工作', 10);
const summaryResults = await siyuan.searchNotes('总结', 5, 'h');
const complexResults = await siyuan.executeSiyuanQuery(`
SELECT content, hpath, created, type, subtype
FROM blocks
WHERE (content LIKE '%工作%' OR content LIKE '%总结%' OR content LIKE '%汇报%')
AND created >= '20251201000000'
AND type IN ('p', 'h', 'l')
AND length > 10
ORDER BY updated DESC
LIMIT 25
`);
const allResults = [...workResults, ...summaryResults, ...complexResults];
const uniqueResults = allResults.filter(
(item, index, self) => index === self.findIndex((t) => t.id === item.id),
);
return siyuan.formatResults(uniqueResults.slice(0, 20));
项目进展查询 (SQL 为主)
const projectQuery = `
SELECT content, type, subtype, hpath, created, updated
FROM blocks
WHERE (
content LIKE '%项目名称%'
OR content LIKE '%功能模块%'
OR hpath LIKE '%项目路径%'
)
AND created >= '20251201000000'
ORDER BY updated DESC, type DESC
LIMIT 30
`;
const projectResults = await siyuan.executeSiyuanQuery(projectQuery);
const titles = projectResults.filter((item) => item.type === 'h');
const paragraphs = projectResults.filter((item) => item.type === 'p');
const tasks = projectResults.filter((item) => item.type === 'l');
return {
summary: `找到 ${projectResults.length} 条相关内容`,
titles: siyuan.formatResults(titles.slice(0, 5)),
keyContent: siyuan.formatResults(paragraphs.slice(0, 10)),
tasks: siyuan.formatResults(tasks.slice(0, 5)),
};
时间线分析 (统计查询)
const activityAnalysis = await siyuan.executeSiyuanQuery(`
SELECT
DATE(substr(created, 1, 8)) as work_date,
COUNT(*) as content_count,
COUNT(DISTINCT root_id) as doc_count,
SUM(CASE WHEN type = 'l' THEN 1 ELSE 0 END) as task_count
FROM blocks
WHERE created >= strftime('%Y%m%d%H%M%S', datetime('now', '-7 days'))
AND (content LIKE '%工作%' OR content LIKE '%开发%' OR content LIKE '%项目%')
GROUP BY DATE(substr(created, 1, 8))
ORDER BY work_date DESC
`);
return siyuan.formatStructuredResults(activityAnalysis);
sql要求
-
SQL 语法规范:
- 在默认的情况下,用户可以在思源的嵌入块中输入 SQL 代码查询,此时 SQL 查询语句必须以
select * from blocks 开头:只允许查询 block 表,且不允许单独查询字段
- 面向开发者的高级用法:用户还可以调用后端 API 接口,发送 SQL 查询,此时是可以使用更普遍的 SQL 语法结构的(查询别的表,返回特定字段)
- 使用 SQLite 的语法,如
strftime 函数处理时间。
- 默认情况下,查询结果最多返回 64 个块,除非明确指定了
limit xxx
-
输出:将查询语句放在一个 ```SQL 的 markdown 代码块当中,方便用户直接复制
表结构
blocks 表:
-
id: 内容块 ID,格式为 时间-随机字符,例如 20210104091228-d0rzbmm。
-
parent_id: 双亲块 ID,格式同 id
-
root_id: 文档块 ID,格式同 id
-
box: 笔记本 ID,格式同 id
-
path: 内容块所在文档路径,例如 /20200812220555-lj3enxa/20210808180320-abz7w6k/20200825162036-4dx365o.sy
-
hpath: 人类可读的内容块所在文档路径,例如 /0 请从这里开始/编辑器/排版元素
-
name: 内容块名称
-
alias: 内容块别名
-
memo: 内容块备注
-
tag: 标签,例如 #标签1 #标签2# #标签3#
-
content: 去除了 Markdown 标记符的文本
-
fcontent: 存储容器块第一个子块的内容
-
markdown: 包含完整 Markdown 标记符的文本
-
length: markdown 字段文本长度
-
type: 内容块类型
d: 文档, h: 标题, m: 数学公式, c: 代码块, t: 表格块, l: 列表块, b: 引述块, s: 超级块,p:段落块,av:树形视图(俗称数据库,注意区分,这只是一个内容块的叫法)
-
subtype: 特定类型的内容块还存在子类型
- 标题块的
h1 到 h6
- 列表块的
u (无序), t (任务), o (有序)
-
ial: 内联属性列表,形如 {: name="value"},例如 {: id="20210104091228-d0rzbmm" updated="20210604222535"}
-
sort: 排序权重,数值越小排序越靠前
-
created: 创建时间,格式为 YYYYMMDDHHmmss,例如 20210104091228
-
updated: 更新时间,格式同 created
refs 表:
id: 引用 ID,格式为 时间-随机字符,例如 20211127144458-idb32wk
def_block_id: 被引用块的块 ID,格式同 id
def_block_root_id: 被引用块所在文档的 ID,格式同 id
def_block_path: 被引用块所在文档的路径,例如 /20200812220555-lj3enxa/20210808180320-fqgskfj/20200905090211-2vixtlf.sy
block_id: 引用所在内容块 ID,格式同 id
root_id: 引用所在文档块 ID,格式同 id
box: 引用所在笔记本 ID,格式同 id
path: 引用所在文档块路径,例如 /20200812220555-lj3enxa/20210808180320-fqgskfj/20200905090211-2vixtlf.sy
content: 引用锚文本
attributes 表:
查询要点提示
-
所有 SQL 查询语句如果没有明确指定 limit,则会被思源查询引擎默认设置 limit 64
-
块属性格式相关
- 块 ID 格式统一为
时间-随机字符, 例如 20210104091228-d0rzbmm
- 块的时间属性,如 created updated 的格式为
YYYYMMDDHHmmss 例如 20210104091228
-
块之间的关系
-
Daily Note:又称日记,每日笔记,是一种特殊的文档块
- daily note 文档有特殊属性:
custom-dailynote-<yyyyMMdd>=<yyyyMMdd>;被标识了这个属性的文档块(type='d'),会被视为是对应日期的 daily note
- 例如
custom-dailynote-20240101=20240101 的文档,被视为 2024-01-01 这天的 daily note 文档
- 请注意! daily note (日记)是一个文档块!如果要查询日记内部的内容,请使用
root_id 字段来关联日记文档和内部的块的关系
-
书签:含有属性 bookmark=<书签名> 的块会被加入对应的书签
SQL 示例
-
查询所有文档块
select * from blocks where type='d'
-
查询所有二级标题块
select * from blocks where subtype = 'h2'
-
查询某个文档的子文裆
select * from blocks
where path like '%/<当前文档id>/%' and type='d'
-
随机漫游某个文档内所有标题块
SELECT * FROM blocks
WHERE root_id LIKE '<文档 id>' AND type = 'h'
ORDER BY random() LIMIT 1
-
查询含有关键词「唯物主义」的段落块
select * from blocks
where markdown like '%唯物主义%' and type ='p'
ORDER BY updated desc
-
查询过去 7 天内没有完成的任务(任务列表项)
注:思源中,任务列表项的 markdown 为 * [ ] Task text 如果是已经完成的任务,则是 * [x] Task Text
SELECT * from blocks
WHERE type = 'l' AND subtype = 't'
AND created > strftime('%Y%m%d%H%M%S', datetime('now', '-7 day'))
AND markdown like'* [ ] %'
AND parent_id not in (
select id from blocks where subtype = 't'
)
-
查询某个块所有的反链块(引用了这个块的所有块)
select * from blocks where id in (
select block_id from refs where def_block_id = '<被引用的块ID>'
) limit 999
-
查询某个时间段内的 daily note(日记)
注意由于没有指定 limit,最大只能查询 64 个
select distinct B.* from blocks as B join attributes as A
on B.id = A.block_id
where A.name like 'custom-dailynote-%' and B.type='d'
and A.value >= '20231010' and A.value <= '20231013'
order by A.value desc;
-
查询某个笔记本下没有被引用过的文档,限制 128 个
select * from blocks as B
where B.type='d' and box='<笔记本 BoxID>' and B.id not in (
select distinct R.def_block_id from refs as R
) order by updated desc limit 128