查询展示笔记元数据

table this
where file = this.file

示例

  1. 创建时间最近三天的笔记
table file.ctime as "创建日期"
where date(today) - file.ctime <= dur(3 day)
sort file.ctime desc

文档元数据操作

有两种方式添加元数据:

  • 文档属性
  • 内联字段

文档属性

添加文档属性,以key:value的形式。

身高      177cm

内联字段

以键值对形式存在

1. 单独成行
身高::177cm
2. 行内字段插入某一行
示例:[体重::52kg]
示例:(年龄::22)
// ==== 1. 收集任务 ====
let tasks1 = dv.pages('"插件学习"').file.tasks;
let tasks = [...tasks1]
	//...tasks2, ...tasks3, ...tasks4, ...tasks5];
// 查询路径条件
let basePaths = `(path includes CYG-Works)`;
 
let today = dv.date("today");
let tomorrow = dv.date("tomorrow");
let oneWeekLater = today.plus({ days: 6 });
console.log(tasks)
// 获取所有任务文件夹中的文件
const pages = dv.pages('"Tasks"');
 
// 创建一个对象来存储标签分类
const tagMap = {};
 
// 遍历每个文件
pages.forEach(page => {
    if (page.file.tags) {
        page.file.tags.forEach(tag => {
            // 如果标签不存在于tagMap中,初始化为一个空数组
            if (!tagMap[tag]) {
                tagMap[tag] = [];
            }
            // 将文件名添加到对应标签的数组中
            tagMap[tag].push(page.file.name);
        });
    }
});
 
// 输出结果
// 遍历每个标签并创建一个表格
Object.entries(tagMap).forEach(([tag, tasks]) => {
    dv.header(3, `Tag: ${tag}`); // 显示标签作为标题
    dv.table(["Task Name"], tasks.map(task => [task])); // 显示任务列表
});
 
// ==== 1. 收集任务 ====
let tasks1 = dv.pages('"插件学习"').file.tasks;
let tasks = [...tasks1]
	//...tasks2, ...tasks3, ...tasks4, ...tasks5];
// 查询路径条件
let basePaths = `(path includes 插件学习)`;
 
let today = dv.date("today");
let tomorrow = dv.date("tomorrow");
let oneWeekLater = today.plus({ days: 6 });
// ==== 2. 分类任务 ====
let expiredTasks = tasks.filter(t => t.status === " " && (
    (t.due && dv.date(t.due).toJSDate() < today.toJSDate()) ||
    (t.scheduled && dv.date(t.scheduled).toJSDate() < today.toJSDate())
));
let ongoingTasks = tasks.filter(t => t.status === "/");
let todoTasks = tasks.filter(t => t.status === " ");
console.log(tasks[0])
// 获取所有任务文件夹中的文件
const pages = dv.pages('"CYG-Works/IT工单"');

// 创建一个对象来存储标签分类
const tagMap = {};

// 遍历每个文件
pages.forEach(page => {
    // 确保文件中有标签
    if (page.file.tags) {
        // 遍历每个标签
        page.file.tags.forEach(tag => {
            // 如果标签不存在于tagMap中,初始化为0
            if (!tagMap.hasOwnProperty(tag)) {
                tagMap[tag] = 0;
            }
            // 增加该标签的计数
            tagMap[tag] += 1;
        });
    }
});

// 输出结果
// 创建一个表格显示标签及其对应的文件数量
dv.table(["Tag", "Count"], 
    Object.entries(tagMap).map(([tag, count]) => [tag, count])
);

table file.name as "Task Name", file.tags as "Tags"
from "CYG-Works"
flatten file.tags as tag sort tag

笔记库查询代码汇总

模板库 js

  1. 用于 日常笔记模板 >> 今日任务动态
// ============================================
// 今日任务动态查询
// 功能:根据当前日记的 journal-date 日期,查找相关任务笔记
// ============================================
 
// --- 第1步:获取当前日记的日期 ---
// dv.current() 获取当前正在查看的笔记(即这篇日记)
// ["journal-date"] 读取日记 frontmatter 中的 journal-date 字段
const raw = dv.current()["journal-date"];
 
// 将日期统一转为 "yyyy-MM-dd" 字符串格式
// 如果 raw 是 Dataview 日期对象(有 toFormat 方法),就格式化
// 否则直接转字符串(兼容文本格式的日期)
const dateStr = typeof raw?.toFormat === "function" 
  ? raw.toFormat("yyyy-MM-dd") 
  : String(raw);
 
// 将字符串转为 Dataview 日期对象,用于范围比较
const start = dv.date(dateStr);
// 计算次日,用于创建日期的区间查询 [当天, 次日)
const end = start.plus({ days: 1 });
 
 
// ============================================
// 辅助函数:递归渲染任务树(含子任务缩进)
// ============================================
function renderTasks(tasks, depth = 0) {
  let lines = [];
  
  for (const t of tasks) {
    // 根据层级生成缩进(depth=0 不缩进,depth=1 一个Tab,以此类推)
    const indent = "\t".repeat(depth);
    
    // 根据完成状态显示不同复选框
    // t.completed 为 true 表示已完成([x]),false 表示未完成([ ])
    const checkbox = t.completed ? "- [x] " : "- [ ] ";
    
    // 拼接缩进 + 复选框 + 任务文本
    lines.push(indent + checkbox + t.text);
    
    // 递归处理子任务(如果存在)
    // ?. 是可选链,避免 subtasks 不存在时报错
    if (t.subtasks?.length > 0) {
      lines = lines.concat(renderTasks(t.subtasks, depth + 1));
    }
  }
  
  return lines;
}
 
 
// ============================================
// 辅助函数:过滤出顶层任务(排除重复子任务)
// ============================================
// Dataview 的 p.file.tasks 会扁平化返回所有任务
// 子任务既会出现在父任务的 subtasks 中,也会作为独立项出现
// 这个函数去重,只保留根级任务
function getRootTasks(allTasks) {
  const subLines = new Set();
  
  // 收集所有子任务的行号
  for (const t of allTasks) {
    if (t.subtasks) {
      for (const s of t.subtasks) {
        subLines.add(s.line);
      }
    }
  }
  
  // 过滤:只保留不在 subLines 中的任务(即不是任何任务的子任务)
  return allTasks.filter(t => !subLines.has(t.line));
}
 
 
// ============================================
// 主查询:构建表格
// ============================================
dv.table(
  // 表头
  ["任务", "待办项"],
  
  // 从指定文件夹查询所有笔记
  dv.pages('"CYG-Works/需求任务-Tasks"')
    
    // --- 筛选条件(满足任一即可)---
    .where(p => {
      // 条件1:笔记创建日期等于 journal-date 当天
      // cday = creation day(创建日期)
      // 用 >= start 且 < end 实现"等于当天"(避免时区问题)
      if (p.file.cday >= start && p.file.cday < end) return true;
      
      // 条件2:笔记中任意任务项的文本包含该日期
      // tasks 只匹配任务列表(- [ ] / - [x]),不匹配普通列表
      // 适用于任务中标注了截止日期(🗓️)或创建日期(➕)的场景
      return p.file.tasks.some(t => t.text.includes(dateStr));
    })
    
    // --- 排序:按修改日期倒序(最新的在前)---
    // mday = modification day(修改日期)
    .sort(p => p.file.mday, "desc")
    
    // --- 映射输出 ---
    .map(p => [
      // 第1列:笔记链接(可点击跳转)
      p.file.link,
      
      // 第2列:该笔记中的所有任务(层级渲染)
      // 1. getRootTasks 去重,只保留顶层任务
      // 2. renderTasks 递归渲染,带子任务缩进
      // 3. join("\n") 用换行拼接,表格内显示为多行
      renderTasks(getRootTasks(p.file.tasks)).join("\n")
    ])
);
  1. 用于 日常笔记模板 >> 工作日志
// ============================================
// 时间队列查询
// 功能:从任务笔记的"时间队列"中,查找与 journal-date 日期相关的记录
// ============================================
 
// --- 第1步:获取当前日记的日期 ---
// dv.current() 获取当前正在查看的笔记(即这篇日记)
// ["journal-date"] 读取日记 frontmatter 中的 journal-date 字段
const raw = dv.current()["journal-date"];
 
// 将日期统一转为 "yyyy-MM-dd" 字符串格式
// 如果 raw 是 Dataview 日期对象(有 toFormat 方法),就格式化
// 否则直接转字符串(兼容文本格式的日期)
const dateStr = typeof raw?.toFormat === "function" 
  ? raw.toFormat("yyyy-MM-dd") 
  : String(raw);
 
 
// ============================================
// 辅助函数:递归收集子列表内容
// ============================================
// 参数 item:当前列表项(Dataview 的 list item 对象)
// 参数 depth:当前层级(0=直接子项,1=孙项,以此类推)
function collectChildren(item, depth = 0) {
  let lines = [];
  
  // item.children 包含该列表项的所有子项
  // 注意:如果 item 没有子项,item.children 可能为 undefined,用 || [] 兜底
  for (const child of (item.children || [])) {
    // 根据层级生成缩进:层级越深,缩进越多
    // depth=0 时缩进1个空格,depth>0 时用 Tab 缩进
    const prefix = depth > 0 ? "\t".repeat(depth) : " ";
    
    // 使用子项自身的符号(如 - [ ]),如果没有则 fallback 到父项符号或 "-"
    const symbol = child.symbol || item.symbol || "-";
    
    // 拼接缩进 + 符号 + 子项文本
    lines.push(prefix + symbol + " " + child.text);
    
    // 递归收集孙项、曾孙项...
    lines = lines.concat(collectChildren(child, depth + 1));
  }
  
  return lines;
}
 
 
// ============================================
// 主查询:构建表格数据
// ============================================
 
// 存储表格行数据
const rows = [];
 
// 从指定文件夹查询所有笔记,按文件名降序排列
// 降序排列让最新的笔记排在前面(假设文件名包含日期或序号)
const pages = dv.pages('"CYG-Works/需求任务-Tasks"').sort(p => p.file.name, "desc");
 
// 遍历每个笔记
for (const page of pages) {
  
  // --- 筛选:找出包含目标日期的顶层普通列表项 ---
  // page.file.lists 获取笔记中所有列表项(普通列表 + 任务列表)
  // 
  // 匹配条件(三个条件同时满足):
  //   1. !item.task:排除任务列表(只保留普通列表项,如 "- 2026-05-09 11:19")
  //   2. item.text.includes(dateStr):文本中包含当前日记日期
  //   3. item.parent === undefined:只匹配顶层列表项
  //      避免子内容里的日期被误匹配(如备注中提到其他日期)
  const entries = page.file.lists.where(item => 
    !item.task && 
    item.text.includes(dateStr) && 
    item.parent === undefined
  );
  
  // --- 处理匹配到的每个时间记录 ---
  // first 标记:同一笔记的多个时间记录,只在第一行显示笔记链接
  // 这样表格更简洁,避免链接重复
  let first = true;
  
  for (const entry of entries) {
    // entry.text 是时间记录本身的文本(如 "- 2026-05-09 11:19")
    // .trim() 去掉首尾空格
    const time = entry.text.trim();
    
    // 递归收集该时间记录下的所有子项内容
    // 用 join("\n") 把多行内容拼接成一个字符串,便于在表格单元格内显示
    const content = collectChildren(entry).join("\n");
    
    // 添加到表格行
    rows.push([
      // 第1列:笔记链接(同一笔记只显示一次,后续为空字符串)
      first ? page.file.link : "",
      // 第2列:时间记录文本(如 "- 2026-05-09 11:19")
      time,
      // 第3列:子项内容(多行,用换行拼接)
      // 如果 content 为空,显示 "—" 作为占位符
      content || "—"
    ]);
    
    // 后续同一笔记的记录不再显示链接
    first = false;
  }
}
 
 
// ============================================
// 渲染表格
// ============================================
dv.table(
  // 表头
  ["任务", "时间", "内容"],
  // 表格数据
  rows
);