Understanding Page and Block Relations in LogSeq (Part 2)
In Part 1, we explored the fundamental concepts of page and block relationships in LogSeq. This continuation delves deeper into implementing these connections through advanced queries, providing practical examples for both simple and complex relationship patterns.
Quick Recap
Before we dive into advanced queries, let’s briefly recall the three primary types of relationships in LogSeq:
- Type A: Block-to-Block relations
- Type B: Block-to-Page relations
- Type C: Page-to-Page relations
First-Degree Relations
First-degree relations represent direct connections between elements in LogSeq. We’ll examine each type using Clojure query syntax, focusing on the predicates that define these relationships.
Block-to-Block Relations (Type A)
- Linear Relations: Find blocks with ancestor-descendant relationships
[?descendant :block/parent ?parent][?parent :block/parent ?ancestor]
;; Note: This query traverses two levels of hierarchy;; For deeper nesting, additional :block/parent predicates would be needed
- Content References: Find blocks that reference other blocks in their content
[?a :block/refs ?b]
Block-to-Page Relations (Type B)
- Containment Relations: Find blocks contained within specific pages
[?block :block/page ?page][?page :block/name ?pageName]
- Content References: Find blocks that reference pages in their content
[?block :block/refs ?page][(missing? $ ?page :block/page)]
Page-to-Page Relations (Type C)
- Linear Relations: Find pages with namespace relationships
[?descendant :block/namespace ?parent][?parent :block/namespace ?ancestor]
- Metadata References: Find pages that reference other pages in their metadata
[?a :block/tags ?b]
Second-Degree Relations Deep Dive
Second-degree relations combine two first-degree relations to reveal indirect connections in your knowledge graph. Let’s explore the various patterns and their implementations.
Block → Block → Block (Type A → A)
e.g. 1-1 Ancestor-Descendant Block to Block References
Description: Find referenced block (Block C) that are mentioned by ancestor block (Block A) of a given descendant block (Block B)
Used First-Degree Methods: A.1, A.2
Predicate: is ‘Block A’ lineal related to ‘Block B’ as ancestor-descendant AND ‘Block A’ mention ‘Block C’ in content
Conclusion: ‘Block B’ is related to ‘Block C’
[?descendant :block/parent ?parent] ;; Block B is a descendant[?parent :block/parent ?ancestor] ;; Block A is the ancestor[?ancestor :block/refs ?blockC] ;; Block A references Block C
Block → Block → Page (Type A → B)
e.g. 2-1 Parent-Child Block to Page References
Description: Find pages (Page C) referenced by parent blocks (Block A) of a given block (Block B)
Used First-Degree Methods: A.1, B.3
Predicate: is ‘Block A’ lineal related to ‘Block B’ as parent-child AND ‘Block A’ mention ‘Page C’ in content
Conclusion: ‘Block B’ is related to ‘Page C’
[?child :block/parent ?parent] ;; Block B is child of Block A[?parent :block/refs ?page] ;; Block A references Page C[(missing? $ ?page :block/page)] ;; Confirm it's a page reference
e.g. 2-2 Block References Across Pages
Description: Find block (Block C) referenced by block (Block A) on a specific page (Page B)
Used First-Degree Methods: A.2, B.1
Predicate: is ‘Block A’ lineal related to ‘Page B’ AND ‘Block A’ mention ‘Block C’ in content
Conclusion: ‘Page B’ is related to ‘Block C’
[?blockA :block/page ?page] ;; Block A is on Page B[?page :block/name ?pageName] ;; Get the page name[?blockA :block/refs ?blockC] ;; Block A references Block C
Block → Page → Page (Type B → B)
e.g. 3-1 Discovering co-referenced pages
Description: Find pairs of pages (Page B, Page C) referenced together in the same block
Used First-Degree Methods: B.3, B.3
Pedicate: is ‘Block A’ mention ‘Page B’ in content AND ‘Block A’ mention ‘Page C’ in content
Conclusion: ‘Page B’ is related to ‘Page C’
[?block :block/refs ?pageA] ;; Block references first page[?block :block/refs ?pageB] ;; Same block references second page[(missing? $ ?pageA :block/page)] ;; Confirm they're page references
Block → Page → Page Type C (Type B → C)
e.g. 4-1 Finding topic connections through page metadata
Description: Find pages (Page C) tagged by pages (Page B) containing specific blocks (Block A)
Used First-Degree Methods: B.1, C.2
Pedicate: is ‘Block A’ lineal related to ‘Page B’ AND ‘Page B’ mention ‘Page C’ in metadata
Conclusion: ‘Block A’ is related to ‘Page C’
[?block :block/page ?pageB] ;; Block A is on Page B[?pageB :block/name ?pageName] ;; Get Page B's name[?pageB :block/tags ?pageC] ;; Page B tags Page C
Page → Page → Page (Type C → C)
e.g. 5-1 Metadata Chains
Description: Discovering indirect topic relationships
Used First-Degree Methods: C.2, C.2
Pedicate: is ‘Page A’ mention ‘Page B’ in metadata AND ‘Page B’ mention ‘Page C’ in metadata
Conclusion: ‘Page A’ is related to ‘Page C’
;; Pattern 1: Metadata Chains[?a :block/tags ?b] ;; Page A tags Page B[?b :block/tags ?c] ;; Page B tags Page C
e.g. 5-2 Finding topic relationships across namespace hierarchies
Description: Find pages (Page C) tagged by ancestor pages (Page A) of a page (Page B)
Used First-Degree Methods: C.1, C.2
Pedicate: is ‘Page A’ lineal related to ‘Page B’ as ancestor-descendant AND ‘Page A’ mention ‘Page C’ in metadata
Conclusion: ‘Page B’ is related to ‘Page C’
[?descendant :block/namespace ?parent] ;; match parent namespace from descendant (Page B)[?parent :block/namespace ?ancestor] ;; match parent to ancestor (page A)[?ancestor :block/alias ?actualPage] ;; Handle page aliases[?actualPage :block/tags ?pageC] ;; Ancestor (page A) has tags (Page C)
Important Implementation Notes
- Alias Handling
;; Always include alias handling for pages that use aliases[?page :block/alias ?actualPage]
- Hierarchy Depth
- Deep hierarchies require explicit parent predicates
- Add additional
:block/parent
or:block/namespace
predicates as needed - TODO: check if LogSeq support recursive predicates to simplify deep hierarchies
- Logical Flow Considerations
- While predicate order doesn’t affect query execution, maintain logical relationship patterns
- Example: Prefer querying ancestor metadata rather than descendant metadata when establishing relationships
- Consider the semantic meaning of relationships when combining different types
Future Development Roadmap
To make these relationships more actionable, we’re planning several enhancements:
-
Relationship Weighting System
- Assign different weights based on relation types
- Consider frequency and recency of connections
- Weight direct references higher than indirect ones
-
Page Evaluation Metrics
- Centrality measures for identifying key pages
- Connection density analysis
- Topic cluster identification
- Temporal relationship patterns
-
Query Pattern Library
- Predefined queries for common relationship patterns
- Custom rule definitions for complex relationships
- Performance-optimized query templates
These developments aim to help users better understand and utilize the knowledge connections within their LogSeq graphs.