Sort deadline query chronologically

Hello,

I use the advanced query for the next 7 days deadline.
I’d like to sort the answer chronologically by deadline (not registration date).
Is there a syntax for that ?

Thanks very much !

4 Likes

I use the following. I don’t claim to be an expert on the query language, which I do not find intuitive, but it seems to sort by date (note the sort-by statement)

However, it would be absolutely great if standard queries were able to sort by deadline / schedule (rather than date created). It would put Logseq far ahead of other apps (Obsidian, Roam, RemNote). Currently none of them can do this.

It would also be great if Org-style scheduled tasks, and dates represented as page references were treated in exactly the same way.

{:title [:h1 "📆 near TODOs (next 7 days, scheduled or deadline)"] 
     :query [:find (pull ?block [*])
          :in $ ?start ?next
          :where
          (or
            [?block :block/scheduled ?d]
            [?block :block/deadline ?d])
          [(>= ?d ?start)]
          [(<= ?d ?next)]]
        :result-transform (fn [result]
                            (sort-by (fn [d]
                                       (get d :block/scheduled) (get d :block/scheduled) ) result))
  :inputs [:today :7d-after]
  :collapsed? false}

   ]
  }
6 Likes

Thanks Hulk (and agree with you, this possibility should be a great strength for logseq over the other apps).

On my side what you propose doesn’t sort by deadlines/schzdule date.

1 Like

Sorting by scheduled date:

#+BEGIN_QUERY
{:title ["📆 near TODOs (next 7 days, scheduled or deadline)"] 
     :query [:find (pull ?b [*])
          :in $ ?start ?next
          :where
          (or
            [?b :block/scheduled ?d]
            [?b :block/deadline ?d]
          )
          [(>= ?d ?start)]
          [(<= ?d ?next)]
  ]
  :result-transform (fn [result] (sort-by (fn [d] (get d :block/scheduled) ) result))
  :inputs [:today :7d-after]
  :collapsed? false}
#+END_QUERY

Sorting by deadline:

#+BEGIN_QUERY
{:title ["📆 near TODOs (next 7 days, scheduled or deadline)"] 
     :query [:find (pull ?b [*])
          :in $ ?start ?next
          :where
          (or
            [?b :block/scheduled ?d]
            [?b :block/deadline ?d]
          )
          [(>= ?d ?start)]
          [(<= ?d ?next)]
  ]
  :result-transform (fn [result] (sort-by (fn [d] (get d :block/deadline) ) result))
  :inputs [:today :7d-after]
  :collapsed? false}
#+END_QUERY

Sort by scheduled then deadline

#+BEGIN_QUERY
{:title ["📆 near TODOs (next 7 days, scheduled or deadline)"] 
     :query [:find (pull ?b [*])
          :in $ ?start ?next
          :where
          (or
            [?b :block/scheduled ?d]
            [?b :block/deadline ?d]
          )
          [(>= ?d ?start)]
          [(<= ?d ?next)]
  ]
  :result-transform (fn [result] (sort-by (juxt (fn [d] (get d :block/scheduled) ) (fn [d] (get d :block/deadline) ) ) result))
  :inputs [:today :7d-after]
  :collapsed? false}
#+END_QUERY

Sort by deadline then scheduled

#+BEGIN_QUERY
{:title ["📆 near TODOs (next 7 days, scheduled or deadline)"] 
     :query [:find (pull ?b [*])
          :in $ ?start ?next
          :where
          (or
            [?b :block/scheduled ?d]
            [?b :block/deadline ?d]
          )
          [(>= ?d ?start)]
          [(<= ?d ?next)]
  ]
  :result-transform (fn [result] (sort-by (juxt (fn [d] (get d :block/deadline) ) (fn [d] (get d :block/scheduled) ) ) result))
  :inputs [:today :7d-after]
  :collapsed? false}
#+END_QUERY

Hope this helps anyone!

9 Likes

Thanks. I wasn’t sure how to get this to work for both schedules and deadlines.

These are such neat queries, they should be included in the logseq manual.

N

4 Likes

I think this one I slightly different but could be useful too.
Sort by date of deadline or scheduled:

:result-transform (fn [result]
       (sort-by (fn [b]
             (or (get b :block/scheduled) (get b :block/deadline))) result))
4 Likes

Hello! Sorry for reopening this thread. But is there a way for {:title [“:calendar: near TODOs (next 7 days, scheduled or deadline)”] to exclude Today tasks? I have a built in query for the tasks I scheduled for today but I would also like to see tasks for the next 7 days. Thanks so much!

What a coincidence, I just solved this yesterday. My default queries for your reference:

:default-queries
 {:journals [
   {:title "🔨 DUE"
    :query [:find (pull ?h [*])
            :in $ ?today
            :where
            [?h :block/page ?p]
            [?p :block/journal? true]
            [?h :block/marker ?marker]
            [(contains? #{"LATER" "TODO" "WAITING"} ?marker)]
            (not [?t :block/name "daily"] [?h :block/refs ?t])
            [?h :block/deadline ?d]
            [(< ?d ?today)]
           ]
    :inputs [:today]
    ;:result-transform (fn [result] (sort-by (fn [h] (get h :block/deadline)) result))
    :result-transform (fn [result] (sort-by (juxt (fn [h] (get h :block/priority "Z")) (comp - (fn [i] (get i :block/deadline)))) result))
    :breadcrumb-show? false
    :collapsed? true}

   {:title "🔨 WIP"
    :query [:find (pull ?h [*])
            :in $ ?today
            :where
            [?h :block/marker ?marker] [(contains? #{"NOW" "DOING"} ?marker)]
            (not-join [?h] [?h :block/refs ?t] [?t :block/name "daily"])
            [?h :block/page ?p] [?p :block/journal? true]
            (or
              (not [?h :block/deadline ?today])
              [(missing? $ ?h :block/deadline)]
            )
           ]
    :inputs [:today]
    ;:result-transform (fn [result] (sort-by (fn [h] (get h :block/deadline)) result))
    :result-transform (fn [result] (sort-by (juxt (fn [h] (get h :block/deadline)) (fn [i] (get i :block/priority "Z"))) result))
    :breadcrumb-show? false
    :collapsed? false}

   {:title "🔨 DAILY"
    :query [:find (pull ?h [*])
            :where
            [?h :block/marker ?marker]
            [(contains? #{"NOW" "DOING", "TODO"} ?marker)]
            [?t :block/name "daily"]
            [?h :block/refs ?t]
            [?h :block/page ?p]
            [?p :block/journal? true]
           ]
    :inputs []
    :result-transform (fn [result] (sort-by (fn [h] (get h :block/deadline)) result))
    :breadcrumb-show? false
    :collapsed? false}

   {:title "🔨 TODAY"
    :query [:find (pull ?h [*])
            :in $ ?today
            :where
            [?h :block/page ?p]
            [?p :block/journal? true]
            [?h :block/marker ?marker]
            [(contains? #{"NOW" "LATER" "DOING" "TODO" "WAITING"} ?marker)]
            (not [?t :block/name "daily"] [?h :block/refs ?t])
            [?h :block/deadline ?d]
            [(= ?d ?today)]
           ]
    :inputs [:today]
    ;:result-transform (fn [result] (sort-by (fn [h] (get h :block/deadline)) result))
    :result-transform (fn [result] (sort-by (juxt (fn [h] (get h :block/priority "Z")) (fn [i] (get i :block/deadline))) result))
    :breadcrumb-show? false
    :collapsed? false}

   {:title "📅 COMING"
    :query [:find (pull ?h [*])
            :in $ ?today ?next
            :where
            [?h :block/marker ?marker]
            [(contains? #{"LATER" "TODO"} ?marker)]
            (not [?t :block/name "daily"]
            [?h :block/refs ?t])
            [?h :block/page ?p]
            [?p :block/journal? true]
            [?h :block/deadline ?d]
            [(< ?d ?next)]
            [(> ?d ?today)]
           ]
    :inputs [:today :7d-after]
    ;:result-transform (fn [result] (sort-by (fn [h] (get h :block/deadline)) result))
    :result-transform (fn [result] (sort-by (juxt (fn [h] (get h :block/deadline)) (fn [i] (get i :block/priority "Z"))) result))
    :breadcrumb-show? false
    :collapsed? true}

   {:title "📅 WAITING"
    :query [:find (pull ?h [*])
            :in $ ?today ?next
            :where
            [?h :block/marker ?marker]
            [(contains? #{"WAITING"} ?marker)]
            [?h :block/page ?p]
            [?p :block/journal? true]
            [?h :block/deadline ?d]
            [(< ?d ?next)]
            [(> ?d ?today)]
           ]
    :inputs [:today :7d-after]
    ;:result-transform (fn [result] (sort-by (fn [h] (get h :block/deadline)) result))
    :result-transform (fn [result] (sort-by (juxt (fn [h] (get h :block/deadline)) (fn [i] (get i :block/priority "Z"))) result))
    :breadcrumb-show? false
    :collapsed? true}

   {:title "📅 BACKLOG"
    :query [:find (pull ?h [*])
            :in $ ?next
            :where
            [?h :block/marker ?marker]
            [(contains? #{"LATER" "TODO"} ?marker)]
            (not [?t :block/name "daily"]
            [?h :block/refs ?t])
            [?h :block/page ?p]
            [?p :block/journal? true]
            [?h :block/deadline ?d]
            [(>= ?d ?next)]
           ]
    :inputs [:7d-after]
    ;:result-transform (fn [result] (sort-by (fn [h] (get h :block/deadline)) result))
    :result-transform (fn [result] (sort-by (juxt (fn [h] (get h :block/deadline)) (fn [i] (get i :block/priority "Z"))) result))
    :breadcrumb-show? false
    :collapsed? true}

   {:title "📅 WITHOUT DEADLINE"
    :query [:find (pull ?h [*])
            :where
            [?h :block/marker ?marker]
            [(contains? #{"TODO" "LATER" "DOING" "NOW" "WAITING"} ?marker)]
            (not [?h :block/deadline _])
            [?h :block/page ?p]
            [?p :block/journal? true]
            (not [?t :block/name "daily"]
            [?h :block/refs ?t])
            (not [?t :block/name "kaizen"]
            [?h :block/refs ?t])
           ]
    :inputs []
    :result-transform (fn [result] (sort-by (fn [h] (get h :block/id)) result))
    :breadcrumb-show? false
    :collapsed? true}
 ]}

1 Like

Thanks! I’m going to try out some of these. :smile:

Easy. Change this [(>= ?d ?start)] to this [(> ?d ?start)]
The variable ?start gets filled with today’s date. (see inputs)
We change the date of the schedule/deadline (?d) from being greater than or equal to (>=) today. To being greater than (>) today.

fantastic. Thank you!

Could you help me with “priority by date” of either of schedule or deadline?

s1 ;; scheduled on first day
s3 d1 ;; scheduled on third day deadlined on first day
s1 d3
s2
d3
s3
1 Like

I’m not sure I understand the question? Could you elaborate on what you want to see?

The query should choose the minimal parameter between scheduled and deadline to place a task in a sequence. In my previous example S1 and S3D3 shows in the sequence for the same “day”, because the minimal parameter D1 has the same date as the schedule for the first task (S1)

T1 S: 06-01
T2 S: 06-05 D: 06-01
T3 S: 06-02 ;; T3 goes after 

This seems already answered:

No, that doesn’t actually work for this.
What you need is a min function.
Here’s the result transform to use:

:result-transform (fn [result] 
(sort-by 
  (min 
    (fn [d] (get d :block/scheduled 99999999) ) 
    (fn [d] (get d :block/deadline 99999999) ) 
  )
 result
)
)

Result with or:

Result with min:

Edit: for the second sort column you might want the max I suppose? Idk just an idea.
You could surround it by a (juxt a b) function.
With a being the (min ...) and b being the (max ...)

1 Like

Thank you. Idk about columns, i don’t use them.

Sorry, column isn’t the right word here haha.
Second value to sort on.

For example I have two tasks.
One has a scheduled date of today and a deadline date of tomorrow.
The second has a deadline date of today and a scheduled date of next week.

With what we have now we only know to sort them on “today” as a value. But there is no distinction between task 1 and 2, both have value “today”.
A second sort value would be the date of tomorrow or next week.
We would then sort the tasks 1, then 2, instead of arbitrarily.

Edit:

:result-transform (fn [result] 
(sort-by 
  (juxt
    (min 
      (fn [d] (get d :block/scheduled 99999999) ) 
      (fn [d] (get d :block/deadline 99999999) ) 
    )
    (max
      (fn [d] (get d :block/scheduled 11111111) ) 
      (fn [d] (get d :block/deadline 11111111) ) 
    )
  )
  result
)
)

Note: changed the 99999999 to 11111111 as you want the value and not the default unless the value is empty…

Normally scheduled should trump deadline. But if you want to treat them equally, you are right.

1 Like

I tried more tasks, so the query from your previous reply doesn’t work.
Screenshot_20230614_184516