【已解决】如何用dataview筛选出上周日记(一共7个笔记)中的所有2级标题的内容

需求:

用dataview(最好不要是js语言)筛选出上周一周的日记中所有2级标题(如## 今日待办)的内容

目前尝试的代码:

TABLE
from "300生活/320日程+日记"
where file.cday <= date("2023-12-31")
where file.cday >= date("2023-12-25")
sort file.name asc

遇到的问题

有两天的日记(2023年12月27和28日)是2024年1月1日创建的,不包含在该时间段内,所以希望用每个笔记中我自己填写的creation_date属性来筛选,而非笔记的创建日期来筛选。

据我所知,仅用 Dataview 的 DQL 无法读取原文。

creation_date属性来筛选

DataviewJS 汇总全文及特定标题下内容并解决图片显示痛点“汇总标题下内容”。
该引出帖代码会更新,请使用最新代码。

首行 term 改为 term = '今日待办'。文档筛选行改为:

let files = dv.pages(`"文件目录"`).filter(p=> moment('2023-12-31').unix() - moment(`${p.creation_date}`).unix() < 604800)

依你提供的代码,用 moment('2023-12-31') 表示 2023-12-31 这一周。

另外,如果你的每个文档都是日期命名(非中文),可将 p.creation_date 改为 p.file.name,不用再手动填写 creation_date

确保在 Dataview 插件设置启用 Enable JavaScript Queries,用 ```dataviewjs 代码块将代码包裹。


本话题求助已解决,根据后续楼层反馈更新本楼。提醒:

  • 若出现不显示,尝试刷新代码块或重启 Ob。
  • 自定属性使用 moment() 为防意外,可写 moment(`${ }`) 放花括号里,如本代码所示。

谢谢大佬的详细解答!

我按照您说的将enable JS queries打开了,也用```将代码块包裹了起来。但仍未成功
目前尝试的代码有:
【代码块1】:

let term = '## 今日待办'; dv.paragraph(`## 汇总 ${term}`)
let files = dv.pages(`"300生活/320日程+日记"`).filter(p=> moment('2023-12-31').unix() - moment(p.creation_date).unix() < 604800)

效果如图:

【代码块2】

let term = '## 今日待办'; dv.paragraph(`## 今日待办 ${term}`)
let files = dv.pages(`"300生活/320日程+日记"`).filter(p=> moment('2023-12-31').unix() - moment(p.creation_date).unix() < 604800)

效果如图:

【代码块3】

let term = '## 今日待办'; dv.paragraph(`## 今日待办 ${term}`)
let files = dv.pages(`"300生活/320日程+日记"`).filter(p=> moment('2023-12-31').unix() - moment(p.file.name).unix() < 604800)

效果跟代码块2一样。

现在问题是出在哪里了呀?

我确实是只放了两行代码,
因为我看您的这篇帖子( DataviewJS 汇总全文及特定标题下内容并解决图片显示痛点 - 经验分享 - Obsidian 中文论坛)需求比我的多,我就试了试删掉那些我不需要的代码(具体删掉的代码见下)

let rgx = /\[.*?\]\((?!http)(.+)|\[\[(.+?)\|(.*?\d+)?/
function extract(str) { let r = []; str.replace(rgx, (m, p1, p2)=> {r.push(p1||p2)}); return r[0] }
files.map(async p=> {
    let fc = app.metadataCache.getFileCache(app.vault.getAbstractFileByPath(p.file.path)).headings
        .filter(p=> p.level == 2)  // 二级标题数组
    let i = fc.findIndex(p=> p.heading == term)  // 获取标题等于 term 的索引
    let A = ( await app.vault.readRaw(p.file.path) ).split('\n')  // 分块
    A = fc[i+1] ? A.slice(fc[i].position.end.line+1, fc[i+1].position.end.line) : A.slice(fc[i].position.end.line+1)  // 截取

    A = A.map(p=> p.split( /!|\)|\]\]/ ).map(p=> rgx.test(p) ? extract(p) : p) )  // 再分块
    let B = p.file.outlinks.filter(p=> p.embed && !/\.md$/.test(p.path))
    for (let i = 0; i < A.length; i++) { for (let j = 0; j < B.length; j++) { let b = B[j].path.split('/');
        let dp = /.*?(?:\|)?(.*?)(?:\|)?(\d+)/.exec(B[j].display)
        let src = encodeURI(`${app.vault.adapter.basePath}/${B[j].path}`)
        A[i] = A[i].map(p=> {
            let boo = p.replace( /\.\// ).includes('/') ? p.endsWith(b.slice(-2).join('/')) : p.endsWith(b.slice(-1))
            if (boo) { return dp ? `<img width='${dp[2]}' src='${src}'>` : `<img src='${src}'>` } else { return p }
    })}; A[i] = A[i].join('')  // 合块
    }; dv.paragraph(`##### ${p.file.link}\n${A.join('\n\n')}`)  // 再合块、输出
})

我发现删掉这些和不删的效果是一样的,所以才确定这些代码可能真的对这个功能的实现没影响

好的,但是我一开始删掉也是因为,我把您的整段代码粘贴进去后,按照您说的改完‘今日待办’和路径后它显示不出来查询结果。具体效果如下

此外,我的文件名是按照obsidian自带的日期格式,即‘YYYY-MM-DD_dddd’。
obsidian版本为1.4.16。麻烦了

我加了dataviewjs的大佬

大佬我觉得问题应该是出在第一行代码

let term = '今日待办'; dv.paragraph(`## 汇总 ${term}`)

我的文件夹结构长这样,然后每天的日记中都有‘## 今日待办’
image

我不太明白dv.paragraph(## 汇总 ${term})的作用是什么,刚刚查了很多还是没看懂

嗯嗯那个我也试了,但还是没有查询结果,只是代码摆在那里,效果如图

我昨天也试了一个其他的代码,具体如下。但目前还没能解决筛选出上周7天的日记中‘## 今日待办’的部分。底下的代码会把我所有的日记(从11月到1月)的今日待办全筛选出来。

const header = '## 今日待办'
//const pages = dv.pages('"300生活/320日程+日记"').filter(p=> moment('2023-12-31').unix() - moment(p.file.name).unix() < 604800)
const pages = dv.pages('"300生活/320日程+日记"').filter(p=> moment('2023-12-31').unix() - moment(p.creation_date).unix() < 604800).sort(p=>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)
    // Read the file contents
    const contents = await app.vault.read(file)
    // Extract the summary via regex
    const summary = contents.match(regex)
    //显示全部包括空结果if (summary) {
    //不显示空结果if (summary && summary[1].trim()) {
    if (summary && summary[1].trim()) {
        // Output the header and summary
        dv.header(2, page.file.link)
        //或者dv.header(2, '[[' + file.basename + ']]')
        dv.paragraph(summary[1].trim())
    }
}

大佬知道应该如何在这个代码的基础上继续筛选吗

p.creation_date 也试了,没有问题。

这两个档放进你的文件目录,看下能不能显示。

---
creation_date: 2023-12-25
---
## 今日待办

2023-12-25
---
creation_date: 2023-12-31
---
## 今日待办

2023-12-31

大佬我刚刚试了一下,好像还是不行诶

真的非常感谢大佬的帮助!虽然还没能解决但也学到了很多,我还是从头速成一下JS然后看看有啥办法可以解决吧,祝大佬2024天天开心,诸事顺意!

大佬好!我刚刚又重启了一下obsidian发现您的代码又可以显示出筛选内容了,但就是还是我之前的所有日记,而非只有上周7天的

let term = '今日待办'; dv.paragraph(`## 汇总 ${term}`)
let files = dv.pages(`"300生活/320日程+日记"`).filter(p=> moment('2023-12-31').unix() - moment(p.creation_date).unix() < 604800).sort(p=>p.file.name,"desc");
let rgx = /\[.*?\]\((?!http)(.+)|\[\[(.+?)\|(.*?\d+)?/
function extract(str) { let r = []; str.replace(rgx, (m, p1, p2)=> {r.push(p1||p2)}); return r[0] }
files.map(async p=> {
    let fc = app.metadataCache.getFileCache(app.vault.getAbstractFileByPath(p.file.path)).headings
        .filter(p=> p.level == 2)  // 二级标题数组
    let i = fc.findIndex(p=> p.heading == term)  // 获取标题等于 term 的索引
    let A = ( await app.vault.readRaw(p.file.path) ).split('\n')  // 分块
    A = fc[i+1] ? A.slice(fc[i].position.end.line+1, fc[i+1].position.end.line) : A.slice(fc[i].position.end.line+1)  // 截取
    A = A.map(p=> p.split( /!|\)|\]\]/ ).map(p=> rgx.test(p) ? extract(p) : p) )  // 再分块
    let B = p.file.outlinks.filter(p=> p.embed && !/\.md$/.test(p.path))
    for (let i = 0; i < A.length; i++) { for (let j = 0; j < B.length; j++) { let b = B[j].path.split('/');
        let dp = /.*?(?:\|)?(.*?)(?:\|)?(\d+)/.exec(B[j].display)
        let src = encodeURI(`${app.vault.adapter.basePath}/${B[j].path}`)
        A[i] = A[i].map(p=> {
            let boo = p.replace( /\.\// ).includes('/') ?p.endsWith(b.slice(-2).join('/')) : p.endsWith(b.slice(-1))
            if (boo) { return dp ? `<img width='${dp[2]}' src='${src}'>` : `<img src='${src}'>` } else { return p }
    })}; A[i] = A[i].join('')  // 合块
    }; dv.paragraph(`##### ${p.file.link}\n${A.join('\n\n')}`)  // 再合块、输出
})

试试把 moment(p.creation_date) 改为 moment(`${p.creation_date}`)

啊啊啊谢谢大佬!!我终于解决了>_<!! :sob:

解决了就行。我也会持续更新,若遇到问题可以先重新回原帖粘贴代码试试。