查询Logseq数据 querying-logseq-data

此技能自动调用,帮助用户构建Logseq的Datalog查询,优化查询性能,理解查询语法,涵盖高级查询模式和聚合查询。

低代码开发 0 次安装 0 次浏览 更新于 3/3/2026

name: querying-logseq-data version: 1.0.0 description: > 专家在为Logseq DB图数据库构建Datalog查询。当用户需要帮助 编写Logseq查询,理解Datalog语法,优化查询性能, 或使用Datascript查询引擎时自动调用。涵盖高级查询模式,拉取语法, 聚合查询和数据库特定查询技术。 allowed-tools: 读取,搜索,全局搜索,网络获取,网络搜索

查询Logseq数据

何时使用此技能

此技能在以下情况下自动调用:

  • 用户想要为Logseq构建Datalog查询
  • 关于:find:where:in子句的问题
  • 拉取语法问题(拉取?e [*])
  • 查询优化或性能问题
  • 聚合查询(计数,求和,平均值,最小值,最大值)
  • 规则定义或可重用的查询逻辑
  • 将简单查询语法转换为完整的Datalog
  • 用户在Logseq上下文中提及“Datalog”,“查询”,“datascript”

参考材料:查看{baseDir}/references/query-patterns.md以获取常见查询示例。

您是Logseq数据库图的Datalog查询专家。

Datalog查询基础

基本查询结构

[:find ?variable          ; 返回什么
 :in $ ?input-var         ; 输入($ = 数据库)
 :where                   ; 条件
 [?entity :attribute ?value]]

查找规范

;; 返回所有匹配项作为元组
[:find ?title ?author ...]

;; 返回为集合(单个变量)
[:find [?title ...] ...]

;; 返回单个值
[:find ?title . ...]

;; 返回单个元组
[:find [?title ?author] ...]

;; 拉取实体数据
[:find (pull ?e [*]) ...]
[:find (pull ?e [:block/title :block/tags]) ...]

常见查询模式

查找所有页面

[:find (pull ?p [*])
 :where
 [?p :block/tags ?t]
 [?t :db/ident :logseq.class/Page]]

查找具有特定标签/类别的块

[:find (pull ?b [*])
 :where
 [?b :block/tags ?t]
 [?t :block/title "Book"]]

按属性值查找

;; 精确匹配
[:find (pull ?b [*])
 :where
 [?b :user.property/author "Stephen King"]]

;; 带变量绑定
[:find ?title ?author
 :where
 [?b :block/title ?title]
 [?b :user.property/author ?author]
 [?b :block/tags ?t]
 [?t :block/title "Book"]]

按状态查找任务

[:find (pull ?t [*])
 :where
 [?t :block/tags ?tag]
 [?tag :db/ident :logseq.class/Task]
 [?t :logseq.property/status ?s]
 [?s :block/title "In Progress"]]

按日期范围查找

;; 本周到期的任务
[:find (pull ?t [*])
 :in $ ?start ?end
 :where
 [?t :block/tags ?tag]
 [?tag :db/ident :logseq.class/Task]
 [?t :logseq.property/deadline ?d]
 [(>= ?d ?start)]
 [(<= ?d ?end)]]

高级查询技术

聚合

;; 按作者统计书籍数量
[:find ?author (count ?b)
 :where
 [?b :block/tags ?t]
 [?t :block/title "Book"]
 [?b :user.property/author ?author]]

;; 求和,最小值,最大值,平均值
[:find (sum ?rating) (avg ?rating) (min ?rating) (max ?rating)
 :where
 [?b :block/tags ?t]
 [?t :block/title "Book"]
 [?b :user.property/rating ?rating]]

规则(可重用的查询逻辑)

;; 定义规则
[[(has-tag ?b ?tag-name)
  [?b :block/tags ?t]
  [?t :block/title ?tag-name]]

 [(is-task ?b)
  [?b :block/tags ?t]
  [?t :db/ident :logseq.class/Task]]]

;; 在查询中使用规则
[:find (pull ?b [*])
 :in $ %
 :where
 (has-tag ?b "Important")
 (is-task ?b)]

否定

;; 查找没有评分的书籍
[:find (pull ?b [*])
 :where
 [?b :block/tags ?t]
 [?t :block/title "Book"]
 (not [?b :user.property/rating _])]

或子句

;; 查找高优先级或逾期的任务
[:find (pull ?t [*])
 :in $ ?today
 :where
 [?t :block/tags ?tag]
 [?tag :db/ident :logseq.class/Task]
 (or
   [?t :logseq.property/priority "High"]
   (and
     [?t :logseq.property/deadline ?d]
     [(< ?d ?today)]))]

递归查询

;; 查找一个块的所有后代
[[(descendant ?parent ?child)
  [?child :block/parent ?parent]]
 [(descendant ?parent ?child)
  [?child :block/parent ?p]
  (descendant ?parent ?p)]]

[:find (pull ?c [*])
 :in $ % ?root-id
 :where
 [?root :block/uuid ?root-id]
 (descendant ?root ?c)]

拉取语法

选择性属性

;; 特定属性
(pull ?e [:block/title :block/tags])

;; 嵌套拉取引用
(pull ?e [:block/title {:block/tags [:block/title]}])

;; 所有属性
(pull ?e [*])

;; 限制嵌套结果
(pull ?e [:block/title {:block/children [:block/title] :limit 5}])

反向引用

;; 查找引用此实体的所有块
(pull ?e [:block/title {:block/_refs [:block/title]}])

数据库特定查询模式

使用类别

;; 查找所有类别(被标记为标签的标签)
[:find (pull ?c [*])
 :where
 [?c :block/tags ?t]
 [?t :db/ident :logseq.class/Tag]]

;; 查找类别层次结构
[:find ?parent-name ?child-name
 :where
 [?child :logseq.property.class/extends ?parent]
 [?child :block/title ?child-name]
 [?parent :block/title ?parent-name]]

使用属性

;; 查找所有用户定义的属性
[:find (pull ?p [*])
 :where
 [?p :block/tags ?t]
 [?t :db/ident :logseq.class/Property]
 [?p :db/ident ?ident]
 [(clojure.string/starts-with? (str ?ident) ":user.property")]]

;; 查找具有类型的属性值
[:find ?prop-name ?type
 :where
 [?p :block/tags ?t]
 [?t :db/ident :logseq.class/Property]
 [?p :block/title ?prop-name]
 [?p :logseq.property/type ?type]]

日记查询

;; 查找所有日记页面
[:find (pull ?j [*])
 :where
 [?j :block/tags ?t]
 [?t :db/ident :logseq.class/Journal]]

;; 查找特定日期的日记
[:find (pull ?j [*])
 :in $ ?date-str
 :where
 [?j :block/tags ?t]
 [?t :db/ident :logseq.class/Journal]
 [?j :block/title ?date-str]]

查询优化提示

  1. 将最具选择性的子句放在最前面 - 尽早缩小结果范围
  2. 使用索引属性 - :db/ident, :block/uuid是索引的
  3. 避免在拉取中使用通配符 - 指定需要的属性
  4. 使用规则处理复杂逻辑 - 更好的可读性和潜在的缓存
  5. 在可能的情况下限制结果 - 为大型数据集添加限制
;; 优化查询示例
[:find (pull ?b [:block/title :user.property/rating])
 :in $ ?min-rating
 :where
 ;; 最具选择性的第一个
 [?b :user.property/rating ?r]
 [(>= ?r ?min-rating)]
 ;; 然后按标签过滤
 [?b :block/tags ?t]
 [?t :block/title "Book"]]

Logseq查询UI与原始Datalog

简单查询(UI)

{{query (and [[Book]] (property :rating 5))}}

等效Datalog

[:find (pull ?b [*])
 :where
 [?b :block/tags ?t]
 [?t :block/title "Book"]
 [?b :user.property/rating 5]]

高级查询块

#+BEGIN_QUERY
{:title "5-Star Books"
 :query [:find (pull ?b [*])
         :where
         [?b :block/tags ?t]
         [?t :block/title "Book"]
         [?b :user.property/rating 5]]
 :result-transform (fn [result] (sort-by :block/title result))
 :view (fn [rows] [:ul (for [r rows] [:li (:block/title r)])])}
#+END_QUERY

常见陷阱

  1. MD与DB属性差异

    • MD::block/content, :block/name
    • DB::block/title, :block/tags
  2. 属性命名空间

    • 用户属性::user.property/name
    • 系统属性::logseq.property/name
  3. 标签与类别术语

    • 在UI中:“标签”
    • 在模式中:“类别”(:logseq.class/*
  4. 日期处理

    • 日期链接到日记页面
    • 使用日期函数进行比较,而不是字符串