Querying Logseq Data
When to Use This Skill
This skill auto-invokes when:
-
User wants to build a Datalog query for Logseq
-
Questions about :find , :where , :in clauses
-
Pull syntax questions (pull ?e [*])
-
Query optimization or performance issues
-
Aggregation queries (count, sum, avg, min, max)
-
Rule definitions or reusable query logic
-
Converting simple query syntax to full Datalog
-
User mentions "Datalog", "query", "datascript" with Logseq context
Reference Material: See {baseDir}/references/query-patterns.md for common query examples.
You are an expert in Datalog queries for Logseq's database-based graphs.
Datalog Query Fundamentals
Basic Query Structure
[:find ?variable ; What to return :in $ ?input-var ; Inputs ($ = database) :where ; Conditions [?entity :attribute ?value]]
Find Specifications
;; Return all matches as tuples [:find ?title ?author ...]
;; Return as collection (single variable) [:find [?title ...] ...]
;; Return single value [:find ?title . ...]
;; Return single tuple [:find [?title ?author] ...]
;; Pull entity data [:find (pull ?e [*]) ...] [:find (pull ?e [:block/title :block/tags]) ...]
Common Query Patterns
Find All Pages
[:find (pull ?p [*]) :where [?p :block/tags ?t] [?t :db/ident :logseq.class/Page]]
Find Blocks with Specific Tag/Class
[:find (pull ?b [*]) :where [?b :block/tags ?t] [?t :block/title "Book"]]
Find by Property Value
;; Exact match [:find (pull ?b [*]) :where [?b :user.property/author "Stephen King"]]
;; With variable binding [:find ?title ?author :where [?b :block/title ?title] [?b :user.property/author ?author] [?b :block/tags ?t] [?t :block/title "Book"]]
Find Tasks by Status
[: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 with Date Ranges
;; Tasks due this week [: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)]]
Advanced Query Techniques
Aggregations
;; Count books by author [:find ?author (count ?b) :where [?b :block/tags ?t] [?t :block/title "Book"] [?b :user.property/author ?author]]
;; Sum, min, max, avg [:find (sum ?rating) (avg ?rating) (min ?rating) (max ?rating) :where [?b :block/tags ?t] [?t :block/title "Book"] [?b :user.property/rating ?rating]]
Rules (Reusable Query Logic)
;; Define rules [[(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]]]
;; Use rules in query [:find (pull ?b [*]) :in $ % :where (has-tag ?b "Important") (is-task ?b)]
Negation
;; Find books without rating [:find (pull ?b [*]) :where [?b :block/tags ?t] [?t :block/title "Book"] (not [?b :user.property/rating _])]
Or Clauses
;; Find high priority or overdue tasks [: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)]))]
Recursive Queries
;; Find all descendants of a block [[(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 Syntax
Selective Attributes
;; Specific attributes (pull ?e [:block/title :block/tags])
;; Nested pulling for refs (pull ?e [:block/title {:block/tags [:block/title]}])
;; All attributes (pull ?e [*])
;; Limit nested results (pull ?e [:block/title {:block/children [:block/title] :limit 5}])
Reverse References
;; Find all blocks referencing this entity (pull ?e [:block/title {:block/_refs [:block/title]}])
DB-Specific Query Patterns
Working with Classes
;; Find all classes (tags that are themselves tagged as Tag) [:find (pull ?c [*]) :where [?c :block/tags ?t] [?t :db/ident :logseq.class/Tag]]
;; Find class hierarchy [:find ?parent-name ?child-name :where [?child :logseq.property.class/extends ?parent] [?child :block/title ?child-name] [?parent :block/title ?parent-name]]
Working with Properties
;; Find all user-defined properties [: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 property values with type [: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]]
Journal Queries
;; Find all journal pages [:find (pull ?j [*]) :where [?j :block/tags ?t] [?t :db/ident :logseq.class/Journal]]
;; Find journal for specific date [:find (pull ?j [*]) :in $ ?date-str :where [?j :block/tags ?t] [?t :db/ident :logseq.class/Journal] [?j :block/title ?date-str]]
Query Optimization Tips
-
Put most selective clauses first - Narrow down results early
-
Use indexed attributes - :db/ident , :block/uuid are indexed
-
Avoid wildcards in pull - Specify needed attributes
-
Use rules for complex logic - Better readability and potential caching
-
Limit results when possible - Add limits for large datasets
;; Optimized query example [:find (pull ?b [:block/title :user.property/rating]) :in $ ?min-rating :where ;; Most selective first [?b :user.property/rating ?r] [(>= ?r ?min-rating)] ;; Then filter by tag [?b :block/tags ?t] [?t :block/title "Book"]]
Logseq Query UI vs Raw Datalog
Simple Query (UI)
{{query (and [[Book]] (property :rating 5))}}
Equivalent Datalog
[:find (pull ?b [*]) :where [?b :block/tags ?t] [?t :block/title "Book"] [?b :user.property/rating 5]]
Advanced Query Block
#+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
Common Gotchas
MD vs DB attribute differences
-
MD: :block/content , :block/name
-
DB: :block/title , :block/tags
Property namespacing
-
User properties: :user.property/name
-
System properties: :logseq.property/name
Tag vs Class terminology
-
In UI: "Tags"
-
In schema: "Classes" (:logseq.class/* )
Date handling
-
Dates link to journal pages
-
Compare using date functions, not strings