【已解决】Dataview能否查询并引用到特定小标题的链接?

解决方案链接

在此感谢lazyloong的无私支持!谢谢!

本帖第21楼-lazyloong提供的解决代码

本贴第22楼-根据个人实际需求调整的解决代码:

```dataviewjs
let files = dv.pages().filter(p=>/日志-\d{2,4}年\d{1,2}月\d{1,2}日/.test(p.file.name)) 
let projects = {} 
for(let i of files) { 
	let content = await app.vault.readRaw(i.file.path) 
	content = content.match(/#### \[\[ABC\]\] ?情况跟进 #工作\/进展/g) 
	if(!content) continue 
	content = content.map(p=>/\[\[(.*?)\]\]/.exec(p)) 
	content.map(p=>projects[p[1]]?projects[p[1]].push(i.file.name):projects[p[1]]=[i.file.name]) 
} 
for(let i in projects) { 
	dv.paragraph('### 情况跟进') 
	dv.list(dv.array(projects[i])
	    .sort(p=>moment(/\d{2,4}年\d{1,2}月\d{1,2}日/.exec(p)[0],'YYYY年MM月DD日').valueOf(),'desc')
	    .map(p=>`[[${p}#${i} 情况跟进 工作/进展]]`)) }

代码实现结果:

如下为原帖:
各位大神好,我才接触Dataview插件,查找了论坛中关于Dataview的各类方法,这里还是有一个问题需要请教:

1 遇到的问题

我是从事项目管理工作的,涉及到同时管理多个项目,日常通过日记来记录各个项目发生的事。
由于需要周期性的开会,所以每隔一段时间,日记中都会有一组以项目为名的三级标题和段落。
我尝试了论坛中各种类型的代码,还是无法将【某项目】所有【会议】的小标题链接显示出来
文件结构见上图:

2 预期的效果

我希望能通过较少的代码量来实现如下的效果:

  1. 根据时间早晚排序,列出【某项目】(是由[[ ]]包含的项目链接)包含 #工作/进展 标签的链接列表/表格。
  2. 通过鼠标移动到对应链接,能够快速预览当时的内容。

还请各位大神指点迷津,谢谢!

3 已尝试但未解决的方案

3.1 dataviewjs的.task尝试

在这个尝试中,我看到dataview能够显示定位至具体小标题的链接,这是我想实现的第2步的功能

```dataviewjs
	dv.table(["任务","笔记名"],
		dv.pages("#待办").file.tasks
		.where(t => (!t.completed))
		.map(b => ["[ ] - " + b.text,b.link])
	)

image

3 已尝试但未解决的方案

3.2 dataview 的LIST尝试

在这个尝试中,我看到dataview能够查询到包含【项目】链接内容的文件,但显示的列表中的链接,无法直接预览定位到对应的小标题

```dataview
	LIST file.text From [[某项目]] and #工作/进展 
	sort file.mtime desc limit (5)

image

3 已尝试但未解决的方案

3.3 dataviewjs 的.list尝试

在这个尝试中,我看到dataviewjs能够查询到包含 #工作/进展 标签的文件,但无法查询具体某项目的文件,列表中的标题并不是链接,无法预览

```dataviewjs
let tag = 'test'
let files = dv.pages("#工作/进展") 
let c = [] 
	for(let i of files) { 
	let text = await app.vault.readRaw(i.file.path) 
c.push(...text.split('\n').filter(p=>p.includes("#工作/进展"))) 
} 
dv.list(c) 

3 已尝试但未解决的方案

3.4 dataviewjs 的const尝试

在这个尝试中,我看到dataviewjs能够查询到包含 #工作/进展 标签的文件,但无法查询具体某项目的文件,列表中的标题并不是链接,无法预览(与上一个尝试一样)

```dataviewjs 
const term = "#工作/进展" 
const files = app.vault.getMarkdownFiles() 
const arr = files.map(async(file) => { 
const content = await app.vault.cachedRead(file) 
const lines = content.split("\n").filter(line => line.contains(term)) 
return lines 
}) 
Promise.all(arr).then(values => 
dv.list(values.flat())) 

或者换一种思路,以项目笔记文件为主的方式去记录项目信息:

  1. 为项目创建项目笔记文件,记录这个项目所有相关的内容(包括日程安排)
  2. 日志文件通过 dataview 动态从项目文件中抓取日程信息展示

有规律的文本直接用正则啦

```dataviewjs
let files = dv.pages().filter(p=>/日志-\d\d年\d\d月\d\d日/.test(p.file.name))
let projects = {}
for(let i of files) {
    let content = await app.vault.readRaw(i.file.path)
    content = content.match(/#### \[\[(.*?)\]\] ?情况跟进 #工作\/进展/g)
    content = content.map(p=>/\[\[(.*?)\]\]/.exec(p))
    content.map(p=>projects[p[1]]?projects[p[1]].push(i.file.name):projects[p[1]]=[i.file.name])
}
for(let i in projects) {
    dv.paragraph('## '+i)
    dv.paragraph('### 情况跟进')
    dv.list(projects[i].map(p=>`[[${p}#${i}情况跟进 工作/进展]]`))
}
```
1 个赞

之前有考虑过这种记录方式,这种方式记录需要在一次多项目会议上切换较多次笔记,日志文件中也要重新对各项目新增的内容挂链接,同一个会议的相同决策或要求需要反复粘贴,对于我来说可能有点麻烦,但是在没找到更好的解决办法前确实是一个可行方案。

感谢回复!!

感谢,我照抄什么都没显示出来,可能要消化一下

非常感谢!!! :grinning:

我现在日志上的项目内容(关键节点)是通过 dataview 动态从项目文件里面抓的,主要是回顾今天有哪些项目更新过内容(关键节点)。

如果是在一个多项目的会议,我可能会另外建一个meeting note. 在这个meeting note里面通过连接,或者 dataview 将相关项目抓过来展示。这样会议期间的展示以meeting note 为主,需要讨论具体的项目时,就点击项目链接进入。

1 个赞

啊,怎么会有问题呢,是我的测试文件不一样吗

好了,我知道了,你的文件名的年是 4 位数,所以没检索出文件 :rofl:

```dataviewjs
let files = dv.pages().filter(p=>/日志-\d{2,4}年\d{1,2}月\d{1,2}日/.test(p.file.name))
let projects = {}
for(let i of files) {
    let content = await app.vault.readRaw(i.file.path)
    content = content.match(/#### \[\[(.*?)\]\] ?情况跟进 #工作\/进展/g)
    content = content.map(p=>/\[\[(.*?)\]\]/.exec(p))
    content.map(p=>projects[p[1]]?projects[p[1]].push(i.file.name):projects[p[1]]=[i.file.name])
}
for(let i in projects) {
    dv.paragraph('## '+i)
    dv.paragraph('### 情况跟进')
    dv.list(projects[i].map(p=>`[[${p}#${i}情况跟进 工作/进展]]`))
}
```
1 个赞

匈牙利大叔这个视频讲笔记组织方式的,对理清笔记的组织思路很有帮助。建议有空可以看看

重新思考我的PKM第5部分–你如何组织你的笔记?_哔哩哔哩_bilibili

1 个赞

:confounded:报错

能不能理解为本来在我日志笔记中的会议内容,单独成为了一个新的以会议为主的笔记?
在笔记头部设置Dataview的YAML信息,实现内容的抓取?
对Dataview了解不深刻,感觉特别像是把一个block变成了一个笔记。

诶,原来不是所有日志里都有这样的标题啊

```dataviewjs
let files = dv.pages().filter(p=>/日志-\d{2,4}年\d{1,2}月\d{1,2}日/.test(p.file.name))
let projects = {}
for(let i of files) {
    let content = await app.vault.readRaw(i.file.path)
    content = content.match(/#### \[\[(.*?)\]\] ?情况跟进 #工作\/进展/g)
    if(!content) continue
    content = content.map(p=>/\[\[(.*?)\]\]/.exec(p))
    content.map(p=>projects[p[1]]?projects[p[1]].push(i.file.name):projects[p[1]]=[i.file.name])
}
for(let i in projects) {
    dv.paragraph('## '+i)
    dv.paragraph('### 情况跟进')
    dv.list(projects[i].map(p=>`[[${p}#${i}情况跟进 工作/进展]]`))
}
```
1 个赞

对的。

我的理解,每个笔记应该尽量围绕同一个/同一类目的来记录或展示内容。比如:

  • 日志,记录或展示跟日期相关的内容,比如当天创建的笔记,当天有过更新的内容,当天完成的任务等
  • 项目笔记:记录或展示跟这个项目相关的所有信息
  • 会议笔记:记录或展示跟这次会议相关的所有信息

我现在在 Obsidian 写的笔记,基本可以做到在一个笔记文件记录,在其他笔记文件按需要连接/dataview 抓取过来展示

1 个赞

可以试下这个,看能否实现需求。用途:汇总【指定小标题下的全部内容】,包括task、列表、普通文本等

```dataviewjs
//输入目标小标题(含#),例如:#### 项目进度条
const header = '#### 小标题名称'

// 按【路径或文件夹、文件名、标签】筛选并按修改时间降序排列
const pages = dv.pages('"00数据管理" or ""').filter(p => p.file.name.includes("") && !p.file.path.includes("template")).filter(p => p.file.name.includes("") || p.file.name.includes("")).sort(p=>p.file.mtime,"desc");

// This regex will return text from the Summary header, until it reaches
// the next header, a horizontal line, or the end of the file
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())
    }
}
```
1 个赞

非常感谢!

抱歉昨天回复次数超限了,这个代码能够列出带链接的列表了,我对代码做了简单的修改,把具体项目筛选出来后,还是有2个小问题想再请教一下:

  1. 鼠标移至链接上时,预览窗口并没有定位至对应的小标题,这个和.task的预览不太一样(详见3.1 的图片)
  2. 日志链接是日期从早到晚的,这个能怎么处理调整成倒序吗?

再次感谢!

1 个赞

谢谢!

我研究一下~ :grinning: