【DataviewJS】对日记进行自动复盘

我是22年中开始在 Obsidian 中写日记的,记录了大半年后,发现周期性复盘时仍需要去一篇篇翻看,着实耽误时间,而日记的内容却又是比较固定的分类(工作、学习、生活、大事件、感触),所以就在想怎么能把本周或本月在工作、生活上完成的事情自动聚合在相应分类下,便于复盘时的回顾。

最终,通过 Obsidian 中的 Dataview 插件解决了这个问题。正好最近有朋友也有类似的问题,所以就决定把自己的方法分享出来。

最终效果

每天正常写日记,在复盘页面中自动对日记中的内容进行分类汇总查看。

实现步骤

下面我以月度复盘为例讲一下具体怎么实现的,周度和年度的,都是类似的方法,稍微调整下最后的代码即可

日记的配置

  • 创建日记,按不同维度设置标题,比如:工作、生活、学习、大事件…
  • 每篇日记的不同维度的标题格式需要保持一致,可以直接设置统一的模板,这样每次创建出来的就

复盘页的配置

  1. 建立一个复盘笔记

  2. 粘贴具体的代码到笔记中

    • 一段代码只会检索一个维度下的内容,上方的图中有多个维度,需要粘贴多段代码,配置完后,每次仅需要替换月份即可
    • 将下面的代码复制到复盘笔记中,记得把开头改成```dataviewjs
//定义一个月份,查询这个月份的数据
let month=6
let year=2024

//定义一个变量,用于按此变量查询笔记中的具体标题:输入目标小标题(含#),例如:#### 项目进度条
const header = '#### 工作'

// 定义一个用于变量,用于存储指定范围内的笔记:按月份筛选笔记,并按修改时间降序排列
const pages = dv.pages('"日记"').where(b => moment(b.file.name).year()==year&&moment(b.file.name).month()==(month-1)).sort(p=>dv.date(p.file.name),"desc");

// 定义一个正则表达式,用于后续匹配指定笔记中的指定内容:某个笔记中从指定标题到下一个标题/横线/文章结尾的所有内容
const regex = new RegExp(`\n${header}\r?\n(.*?)(\n#### |\n---|$)`, 's')

//对所有查询出来的页面提取指定内容并显示出来
for (const page of pages) {
        //根据查询到的笔记获取对应的文件
    const file = app.vault.getAbstractFileByPath(page.file.path)
    
    // 读取文件正文
    const contents = await app.vault.read(file)
    
    // 获得正文中的指定内容
    const summary = contents.match(regex)
    
    //显示指定内容
            //显示空结果:if (summary) {
            //不显示空结果:if (summary && summary[1].trim()) {
    if (summary && summary[1].trim()) {
        // 显示对应文件链接,或者用这个也行dv.header(2, '[[' + file.basename + ']]')
        dv.span("**"+page.file.link+"**")
        //显示对应正文内容
        dv.paragraph(summary[1].trim())
    }
}
  1. 粘贴之后,对如下的几处地方进行调整,这里以4级标题的工作为例,具体情况请自行修改

其他日记相关文章

5 个赞


楼主代码搞上去 没反应了啊 什么情况啊

  • 是否安装了 dataview 插件,并且开启了DataviewJS 的功能。
  • 对应日记中的格式是否正确
  • 都没问题的看下 dataviewjs 查询出来的是空还是报错了
1 个赞

查询出来是空的,代码如下

//定义一个月份,查询这个月份的数据 
let month=10
let year=2024 

//定义一个变量,用于按此变量查询笔记中的具体标题:输入目标小标题(含#),例如:#### 项目进度条 
const header = '## 工作日志' 

// 定义一个用于变量,用于存储指定范围内的笔记:按月份筛选笔记,并按修改时间降序排列 
const pages = dv.pages('"2024年日记"').where(b => moment(b.file.name).year()==year&&moment(b.file.name).month()==(month-1)).sort(p=>dv.date(p.file.name),"desc"); 

// 定义一个正则表达式,用于后续匹配指定笔记中的指定内容:某个笔记中从指定标题到下一个标题/横线/文章结尾的所有内容 
const regex = new RegExp(`\n${header}\r?\n(.*?)(\n# |\n---|$)`, 's') 

//对所有查询出来的页面提取指定内容并显示出来 
for (const page of pages) {

//根据查询到的笔记获取对应的文件 
     const file = app.vault.getAbstractFileByPath(page.file.path) 
  
// 读取文件正文 
const contents = await app.vault.read(file)

// 获得正文中的指定内容 
const summary = contents.match(regex) 

//显示指定内容 //显示空结果:if (summary) { 
//不显示空结果:if (summary && summary[1].trim()) {  
if (summary && summary[1].trim()) { 
  
  // 显示对应文件链接,或者用这个也dv.header(2, '[[' + file.basename + ']]') 
  dv.span("**"+page.file.link+"**") 

//显示对应正文内容
  dv.paragraph(summary[1].trim()) 
}
}

可以截几张文件目录结构和日记内容的图,只看dataviewjs 的话很难看出是哪的问题

已解决,空格及文件夹问题

帮忙贴下没问题的代码,我也是空结果,多谢

//定义一个月份,查询这个月份的数据 
let month=10
let year=2024 

//定义一个变量,用于按此变量查询笔记中的具体标题:输入目标小标题(含#),例如:#### 项目进度条 
const header = '## 工作日志' 

// 定义一个用于变量,用于存储指定范围内的笔记:按月份筛选笔记,并按修改时间降序排列 
const pages = dv.pages('"日记/2024年日记/2024年10月日记"').where(b => moment(b.file.name).year()==year&&moment(b.file.name).month()==(month-1)).sort(p=>dv.date(p.file.name),""); 

// 定义一个正则表达式,用于后续匹配指定笔记中的指定内容:某个笔记中从指定标题到下一个标题/横线/文章结尾的所有内容 
const regex = new RegExp(`\n${header}\r?\n(.*?)(\n# |\n---|$)`, 's') 

//对所有查询出来的页面提取指定内容并显示出来 
for (const page of pages) {

//根据查询到的笔记获取对应的文件 
     const file = app.vault.getAbstractFileByPath(page.file.path) 
  
// 读取文件正文 
const contents = await app.vault.read(file)

// 获得正文中的指定内容 
const summary = contents.match(regex) 

//显示指定内容 //显示空结果:if (summary) { 
//不显示空结果:if (summary && summary[1].trim()) {  
if (summary && summary[1].trim()) { 
  
  // 显示对应文件链接,或者用这个也dv.header(2, '[[' + file.basename + ']]') 
  dv.span("**"+page.file.link+"**") 

//显示对应正文内容
  dv.paragraph(summary[1].trim()) 
}
}

我的日记在文件夹20-Diary下,内容在类似2024-10-10文档标题## 工作模型下,但是结果还是没法显示。帮忙看下问题在哪里。多谢

//定义一个月份,查询这个月份的数据 
let month=10
let year=2024 

//定义一个变量,用于按此变量查询笔记中的具体标题:输入目标小标题(含#),例如:#### 项目进度条 
const header = '## 工作模型' 

// 定义一个用于变量,用于存储指定范围内的笔记:按月份筛选笔记,并按修改时间降序排列 
const pages = dv.pages('"20-Diary"').where(b => moment(b.file.name).year()==year&&moment(b.file.name).month()==(month-1)).sort(p=>dv.date(p.file.name),""); 

// 定义一个正则表达式,用于后续匹配指定笔记中的指定内容:某个笔记中从指定标题到下一个标题/横线/文章结尾的所有内容 
const regex = new RegExp(`\n${header}\r?\n(.*?)(\n## |\n---|$)`, 's') 

//对所有查询出来的页面提取指定内容并显示出来 
for (const page of pages) {

//根据查询到的笔记获取对应的文件 
     const file = app.vault.getAbstractFileByPath(page.file.path) 
  
// 读取文件正文 
const contents = await app.vault.read(file)

// 获得正文中的指定内容 
const summary = contents.match(regex) 

//显示指定内容 //显示空结果:if (summary) { 
//不显示空结果:if (summary && summary[1].trim()) {  
if (summary && summary[1].trim()) { 
  
  // 显示对应文件链接,或者用这个也dv.header(2, '[[' + file.basename + ']]') 
  dv.span("**"+page.file.link+"**") 

//显示对应正文内容
  dv.paragraph(summary[1].trim()) 
}
}

我也不是太熟,10月日记得在文件夹下才行。

多谢您,我再试试看。我日记都在20-diary下

20-diary 这个文件夹是在根目录下么,如果上层还有文件夹需要都写出来,如 dv.pages(‘“xxx/20-Diary”’)

我修改成了汇总多个月份的代码:

// 定义年份和月份范围,查询这个范围内的数据
let startMonth = 0; // 1月
let endMonth = 11; // 12月
let year = 2023;

// 定义一个变量,用于按此变量查询笔记中的具体标题:输入目标小标题(含#),例如:#### 项目进度条
const header = '## 💼工作模型';

// 定义一个用于变量,用于存储指定范围内的笔记:按月份筛选笔记,并按修改时间降序排列
const pages = dv.pages('"20-Diary"')
  .where(b => {
    const fileDate = dv.date(b.file.name);
    return fileDate && fileDate.year === year && fileDate.month >= startMonth && fileDate.month <= endMonth;
  })
  .sort(p => p.file.ctime, 'desc');

// 定义一个正则表达式,用于后续匹配指定笔记中的指定内容:某个笔记中从指定标题到下一个标题/横线/文章结尾的所有内容
const regex = new RegExp(`\n${header}\\r?\\n(.*?)(\\n##|\\n---|\\$)`, 's');

// 对所有查询出来的页面提取指定内容并显示出来
for (const page of pages) {
  // 根据查询到的笔记获取对应的文件
  const file = app.vault.getAbstractFileByPath(page.file.path);

  // 读取文件正文
  const contents = await app.vault.read(file);

  // 获得正文中的指定内容
  const summary = contents.match(regex);

  // 显示指定内容
  if (summary && summary[1].trim()) {
    // 显示对应文件链接
    dv.span("**" + `[[${page.file.path}]]` + "**");

    // 显示对应正文内容
    dv.paragraph(summary[1].trim());
  }
}
1 个赞