美人儿呀
(Wrwe)
1
在「页面A」这个文档中,有以下内容(代码框内的)。
我希望能用 dataview 查询出「学习Python」这个任务所有后代任务中已完成任务的情况。
以表格显示,表格的第1列是已完成的任务名称,第2列是任务完成时间,第3列是任务完成所花费的时间(time属性后面的值)。
我用GPT写了半天,一直都是错的。dataviewjs 也不行,不知道怎么操作。
- [ ] 学习 Python
- [ ] 学习第一章
- [x] 学习第一节 ✅ 2024-11-15 (time::40m)
- [ ] 学习第二节
- [x] 学习第 2.1 小节 (time::65m) ✅ 2024-11-25
- [x] 学习第 2.2 小节 (Time:: 30m) ✅ 2024-11-21
- [ ] 学习第三节
- [ ] 学习第四节了
- [ ] 学习第 4.1 小节
- [ ] 学习 JS
- [x] 学习第一节 (Time:: 20m) ✅ 2024-11-01
Probe
(Probe)
2
大致是类似下面这样子:
```dataviewjs
const mainTaskName = "学习 Python"; // 目标任务名称
const completedTasks = [];
// 获取所有页面
const pages = dv.pages(`"仓库下的/有可能含有目标主任务的笔记目录"`);
// console.log(pages);
// 遍历每个页面的任务
let taskResult = [];
for (const page of pages) {
for (const task of page.file.tasks) {
console.log(task);
if (task.text === mainTaskName) {
recursiveProcessTask(task);
}
}
}
function recursiveProcessTask(task) {
// 遍历子任务
console.log(task);
for (const child of task.children) {
// 检查子任务是否已完成
if (child.completed) {
// 将已完成的任务信息添加到结果数组
let taskShortName = child.text.split(/\(Time/i)[0].split(/(✅|➕)/)[0];
taskResult.push([taskShortName, child.completion, child.time || child.Time]);
}
// 递归处理子任务
if (child.children && child.children.length > 0) {
recursiveProcessTask(child);
}
}
}
// 输出表格
dv.table(["已完成任务名称", "完成时间", "完成所花费的时间"], taskResult);
```
这个只是基本的, 还没想好 “要是上层任务和下层任务都记录了时间” 怎么办
此外, 大小写 (time::65m)
(Time:: 30m)
最好还是统一了吧, 否则麻烦
PS.
我自己的体会, 直接问 GPT 或许也能成功, 但是细节总是差点
适合干这种事的工具也许是, 收集一些 dv 资料 (md 格式就行, 不必非得是 js 格式) 之后:
- 问 Obsidian Copilot (全库 QA 模式)
- 或 Obsidian Smart Connections 同理
- 好处是一边问着, 一边就测试了
- 问 Cursor
@Codebase 模式
- 或 Windsurf 同理
- 这个好处是它们就是为了代码优化的, 且可以专门指定某个 “专管 dv 的子目录” 拿 Cursor 打开, 嵌入速度快, 语料的主题集中
折腾这一通 RAG 后, 这类 dv 问题直接就能问出来吗? 好了不少, 但还是难做到一次成功… 尚需研究…
美人儿呀
(Wrwe)
3
这个65分钟换成 「1小时、5分钟」 的格式,好奇怪,有办法调整一下吗?
美人儿呀
(Wrwe)
4
另外,像「完成所花费的时间」能否像notion那样做页下总数统计?
Probe
(Probe)
5
「1小时、5分钟」 的格式
因为 duration 对象默认会被 format 成这个人类可读形态, 改成 task.time.minutes 就好了
能否像notion那样做页下总数统计?
不知道 notion 具体怎么做的, 如果只把上面时间加起来, 那倒是简单
实际上这可能还得看具体需求, task 多级路径上是否既有规划又有实际完成时间, 当父级 task 和子级都写时间, 是以谁为准, 等等
```dataviewjs
const mainTaskName = "学习 Python"; // 目标任务名称
const completedTasks = [];
// 获取所有页面
const pages = dv.pages(`"仓库下的/有可能含有目标主任务的笔记目录"`);
// console.log(pages);
// 遍历每个页面的任务
let taskResult = [];
for (const page of pages) {
for (const task of page.file.tasks) {
console.log(task);
if (task.text === mainTaskName) {
recursiveProcessTask(task);
}
}
}
function recursiveProcessTask(task) {
// 遍历子任务
console.log(task);
for (const child of task.children) {
// 检查子任务是否已完成
if (child.completed) {
// 将已完成的任务信息添加到结果数组
let taskShortName = child.text.split(/\(Time/i)[0].split(/(✅|➕)/)[0];
taskResult.push([taskShortName, child.completion, child.time.minutes]);
}
// 递归处理子任务
if (child.children && child.children.length > 0) {
recursiveProcessTask(child);
}
}
}
taskResult.push([`Total: ${mainTaskName}`,
taskResult.map(task => task[1]).reduce((a, b) => a > b ? a : b),
taskResult.reduce((total, task) => total + task[2], 0)
]);
// 输出表格
dv.table(["已完成任务名称", "完成日期", "花费时间(min)"], taskResult);
```