请教题主,能否使用dataview实现块状内容的聚合并且将这些内容进行排列,类似于gallery视图那样,具体的效果图就是这样
请教下,笔记的yaml写成如下,能正常返回数据
file:菜名: 麻辣猪蹄
非常喜欢: 小明
不喜欢: 二狗
但“非常喜欢”似乎不能有多个值,例如写成 非常喜欢: 小明,小华
,就不会返回数据。
请问有解决办法吗?
你是想用上面的代码吗,那个代码是用 、
分割的
请问表格的样式是怎么设置的?我的表格样式还是默认的
大佬,请问一下 dataviewjs 能不能查询出当前笔记中所有高亮的内容呢?
```dataviewjs
//定义一个函数,接受一个markdown字符串作为参数
function extractHighlight(markdown) {
//定义一个空数组,用来存放高亮部分
let highlights = [];
//定义一个正则表达式,匹配被==包裹的部分
let regex = /==(.+?)==/g;
//定义一个变量,用来存放正则表达式的匹配结果
let match;
//使用循环,遍历所有的匹配结果
while (match = regex.exec(markdown)) {
//把匹配结果中的第一个捕获组(也就是高亮部分)添加到数组中
highlights.push(match[1]);
}
//返回数组
return highlights.filter(p=>p!='(.+?)');
}
dv.list(extractHighlight(await app.vault.readRaw(dv.current().file.path)))
```
提一嘴,你敢相信上面那个函数是 newbing 生成的吗 ,太离谱了
那确实没办法,chatgpt 的资料好像到 2021 还是 2022 年就停止了,还不能联网,newbing 还是基于 chatgpt 呢。
以下是 newbing 的回答,真的是强的离谱
Obsidian是一个笔记软件,Dataview是Obsidian的一个社区插件,可以用来查询和展示笔记中的元数据。Dataview有两种查询语法:Dataview Query Language (DQL) 和 DataviewJS。DQL是一种简单的语言,可以用来筛选和排序笔记。DataviewJS是一种基于JavaScript的语言,可以用来编写更复杂的查询和自定义视图。
DQL的基本格式是:
TABLE|LIST|TASK [columns]
FROM [files]
WHERE [filter]
SORT BY [field] ASC|DESC
其中:
-
TABLE
、LIST
、TASK
是三种不同的视图类型,分别显示表格、列表和任务。 -
[columns]
是要显示的字段或表达式,用逗号分隔。 -
[files]
是要查询的文件范围,可以是文件夹、标签或其他条件。 -
[filter]
是要应用的过滤条件,可以使用逻辑运算符(如AND
、OR
、NOT
)和比较运算符(如=
、<
、>
)组合字段或表达式。 -
[field]
是要排序的字段或表达式,可以有多个,用逗号分隔。 -
ASC|DESC
是升序或降序的标志。
例如,如果你想查询所有标签为 #book 的笔记,并按照评分降序显示标题和作者,你可以写:
TABLE file.name as Title, author as Author
FROM #book
SORT BY rating DESC
如果你想查询所有包含未完成任务的笔记,并按照创建日期升序显示标题和任务内容,你可以写:
TASK file.name as Title, task as Task
WHERE contains(tasks, t -> !t.completed)
SORT BY file.ctime ASC
更多关于DQL的信息,请参考¹ 和²。
DataviewJS的基本格式是:
// JavaScript code to query and display data
其中:
- 你可以使用
dv.pages()
函数来获取所有或部分笔记的元数据对象。 - 你可以使用 JavaScript 的数组方法(如
filter()
、map()
、sort()
)来处理数据。 - 你可以使用
dv.table()
、dv.list()
、dv.taskList()
函数来显示不同类型的视图。 - 你可以使用 Luxon 库中的
DateTime
对象和函数来处理日期时间数据。
例如,如果你想查询所有标签为 #movie 的笔记,并按照评分降序显示标题和导演,并且对于评分高于 8 的电影,在标题后面加上一个爱心符号 ,你可以写:
let movies = dv.pages("#movie");
movies.sort((a, b) => b.rating - a.rating);
let rows = movies.map(m => [
m.rating > 8 ? `${m.file.name} ❤️ ` : m.file.name,
m.director
]);
dv.table(["Title", "Director"], rows);
更多关于DataviewJS的信息,请参考¹ 和³。
源: 与必应的对话, 2023/2/25(1) How to get started with Obsidian Dataview and DataviewJS. How to get started with Obsidian Dataview and DataviewJS | by Jacqui Read | OS TechBlog | Medium 访问时间 2023/2/25.
(2) DataView Query for tasks with certain tag - Resolved help - Obsidian Forum. DataView Query for tasks with certain tag - Resolved help - Obsidian Forum 访问时间 2023/2/25.
(3) Dataview Date Formatting - Resolved help - Obsidian Forum. Dataview Date Formatting - Resolved help - Obsidian Forum 访问时间 2023/2/25.
明白了,谢谢。不过我现在想实现下述需求,例如:小明(名字以外的描述性文字)、小华(名字以外的描述性文字)
请问应该怎样修改代码呢?
大佬,这个JS代码渲染的内容导出时总是一片空白,能出手帮忙解决下不?我水平有限,实在无能为力
```dataviewjs
const files = app.vault.getMarkdownFiles()
.filter(p=>p.parent.path.includes("")) //目标路径,例如A/B
.filter(p=>p.name.includes("")) //目标文件名
.sort(function(x,y){return y.stat.mtime-x.stat.mtime}) //按修改时间降序排列,升序请改成:.sort(function(x,y){return x.stat.mtime-y.stat.mtime}),即:直接直接对调xy的位置
const prompt = "关键词A"
const prompt2 = "关键词B"
const fileObject = files.map(async (file) => {
const fileLink = "[["+file.name.split(".")[0]+"]]"
const content = await app.vault.cachedRead(file)
return {fileLink, content}
})
Promise.all(fileObject).then(files => {
let values = new Set(files.reduce((acc, file) => {
const lines = file.content.split("\n").filter(line => line.match(new RegExp(prompt, "i")) || line.match(new RegExp(prompt2, "i")))
if (lines[0] && !file.fileLink.includes("啊啊啊") && !file.fileLink.includes("模板-") && !file.fileLink.includes("啊啊啊2") && !file.fileLink. includes("测试") && !file.fileLink.includes("测试2")) {
if (acc[0]) {
return [...acc, [file.fileLink, lines.join("\n")]]
} else {
return [[file.fileLink, lines.join("\n")]]
}
}
return acc
}, []))
dv.header(2, prompt)
dv.table(["file", "所在行"], Array.from(values))
})
```
额,我有点没看懂这是做什么的
按关键词提取 关键词所在行内容 并汇总成表格
```dataviewjs
let files = dv.pages('#目录')
extractKeywords(['复数'],files)
async function extractKeywords(keywordArr,files) {
let values = []
for(let file of files) {
let content = (await app.vault.readRaw(file.file.path)).split('\n')
keywordArr.forEach((k)=>{
content.filter(p=>p.includes(k))
?.forEach(p=>values.push([file.file.link,p.trim()]))
})
}
dv.table(["file", "所在行"], values)
}
```
问题是什么啊
我库里的笔记一万多条,这段代码貌似渲染比较费时,三分钟往上了,而且导出来仍是空白。
你没对第一行做筛选吗
不然试试这个吧
```dataviewjs
let files = dv.pages('#目录')
extractKeywords(['复数'],files)
async function extractKeywords(keywordArr,files) {
let paths = files.map(p=>p.file.path)
files = app.vault.getMarkdownFiles().filter(p=>paths.includes(p.path))
let values = []
for(let file of files) {
let content = (await app.vault.cachedRead(file)).split('\n')
keywordArr.forEach((k)=>{
content.filter(p=>p.includes(k))
?.forEach(p=>values.push([`[[${file.name}]]`,p.trim()]))
})
}
dv.table(["file", "所在行"], values)
}
```
我的使用就是针对整个库进行提取,试了这个新版本的,ob直接崩了(上个版本的ob不会崩,只是渲染费时,至少需要三分钟)
我目前在用的自用版本,渲染较快,基本3秒就能出结果。但渲染就是无法导出来
那就奇怪了,我也有2500的文件,全库也不过两三秒就渲染了,那只好请求场外援助了
```dataviewjs
let keyword = '复数'
let results = await omnisearch.search(keyword)
let vaules = []
for(let r of results) {
for(let m of r.matches) {
let i = m.match.indexOf(keyword)
if(i!=-1) {
let content = await app.vault.readRaw(r.path)
let line = getLineNumber(content, i+m.offset)
vaules.push([`[[${r.path}|${r.basename}]]`, line])
}
}
}
dv.table(['file','line'],vaules)
function getLineNumber(str, pos) {
var lines = str.split("\n")
var count = 0
for (var i = 0; i < lines.length; i++) {
count += lines[i].length + 1 // add 1 for the newline character
if (count > pos) {
return lines[i] // line numbers start from 1
}
}
}
```
可能有些重复的,对了,要安装 Omnisearch 插件