Specific tag(s) + current calendar week

Trying to figure out the advanced query syntax for what I hope is a simple use case. The query criteria I want to implement are:

  1. Find all blocks (including children)
  2. Created or edited during the current calendar week (not the preceding 7 days)
  3. Containing both a specified tag (“activity log” for the purpose of this post) and any one of a group of secondary tags (“activity log” AND “major issue”, where “major issue” is a subcategory of “activity log” entries), but not limited to those tags.
  4. collapsed-children: false and not tabular format

Note that the reason for not simply searching on the secondary tag is that the tag can be used for other purposes, so it might be more useful to think of the secondary as the primary tag and “activity log” as specifying that you want that event logged. Same result either way.

I am very, very new to this syntax, but I have extensive prior development experience so I feel like I’m banging up against a window trying to get started.

  • When it comes to Logseq queries, your case is far from a simple one:
    • Working with dates is hard in most scenarios.
      • Logseq doesn’t currently provide a dedicated date type.
        • For now there are some substitutes.
        • This will change in the coming database version.
    • There is generally no proper creating/editing date saved for blocks.
      • Could enable such dates, but they get lost on every reindexing.
      • Could work instead with journal dates or custom properties.
    • There is no easy concept of calendar week.
      • There is no function provided for days of the week.
      • There are some advanced rules that can perform the needed calculations.
    • Extensive prior development experience helps, but not much.
      • Be prepared for plenty of banging up, even after you become old to this.
  • I would suggest the following:
    • Start by creating separate queries for each one of the criteria, before attempting their combination into a single query.
      • Better begin with the tags and leave the dates for later.
    • Share here any of your efforts, so as we have something specific to help with.
      • Example blocks also help, especially when the results are different than the expected ones.

Yeah, I have passing familiarity with the date issue because of prior experience with a TODO query. I think I’m going to try a “where” clause of:

  • Contains “activity-log” tag AND
  • Contains [“subtag1” or “subtag2” or “subtag3”] AND
  • Does not contain “logged”

I’ll just have to remember to mark anything I’ve already reported as “logged”. The sad part is that, thanks to dates, I won’t have a static record over time of what I’ve reported, unless I copy it into an email.

Anyway, let me try building something up and see what I get.

Ok, here’s as far as I’ve gotten. I can get this to work with one tag (though it’s pulling the full page context and not the block and any children–that’s a separate concern). There will be five of these queries on a report page, for each of five potential issue types (“major-issues”, “time-savers”, etc.). I would change the inputs to reflect each issue type in the five queries.

What I’m hanging up on is how to specify a tag as the query condition and how to nest the and and not conditions properly.

#+BEGIN_QUERY
{ 
:title  [:b "Major Issues"]
:query [
    :find (pull ?b [*])
    :where 
        (and 
            // contains tag1 ("activity-log")
            // contains tag2 ("major-issue")
            // not contains "logged"
        )
]
:inputs ["activity-log" "major-issue"]
:collapsed? false
:remove-block-children? true
}
#+END_QUERY
  • To pass the :inputs, an :in clause is also needed (typically above :where) like this:
    :in $ ?tag1-name ?tag2-name
    
  • The top-level of :where is already an implied and, therefore should remove (and) and use something like this:
    [?tag1 :block/name ?tag1-name]
    [?tag2 :block/name ?tag2-name]
    [?logged :block/name "logged"]
    [?b :block/refs ?tag1]
    [?b :block/refs ?tag2]
    (not [?b :block/refs ?logged])
    
1 Like

Ok, query is currently:

#+BEGIN_QUERY
{ 
:title  [:b "Major Issues"]
:query [
    :find (pull ?b [*])
    :in $ ?tag1-name ?tag2-name
    :where 
            [?tag1 :block/name ?tag1-name]
            [?tag2 :block/name ?tag2-name]
            [?logged :block/name "logged"]
            [?b :block/refs ?tag1]
            [?b :block/refs ?tag2]
            (not [?b :block/refs ?logged])
]
:inputs ["activity-log" "major-issue"]
:collapsed? false
:remove-block-children? true
}
#+END_QUERY

The query executes without error, but it does not return any results. There is one test block I have in a journal entry from yesterday that says, in full: #activity-log #major-issue Test issue.

If the test block is not returned, it means that the remaining tag (#logged) doesn’t exist yet. Either:

  • use tag #logged
  • create page logged
  • move line [?logged :block/name "logged"] inside the existing (not), i.e.:
    (not
      [?logged :block/name "logged"]
      [?b :block/refs ?logged]
    )
    
1 Like

That was it. Thank you.

Can I ask if there’s a way to limit the returned information only to the block in which the tag occurs (and any child blocks) rather than including the full page context?

For the purpose of marking a solution, here’s the final query (minus the follow-up question regarding the scope of the returned data):

#+BEGIN_QUERY
{ 
:title  [:b "Major Issues"]
:query [
    :find (pull ?b [*])
    :in $ ?tag1-name ?tag2-name
    :where 
            [?tag1 :block/name ?tag1-name]
            [?tag2 :block/name ?tag2-name]
            [?b :block/refs ?tag1]
            [?b :block/refs ?tag2]
            (not
                [?logged :block/name "logged"] 
                [?b :block/refs ?logged]
            )
]
:inputs ["activity-log" "major-issue"]
:collapsed? false
:remove-block-children? true
}
#+END_QUERY

Note that “major-issue” could be any of several issue-type tags.

Not sure what you mean by “full page context”. You may prefer the table view. If you want proper visual control of the output, you can play with :view

I have included :group-by-page? false and :beadcrumb-show? false, but if you look at the screenshot you see the two instances of “Notes” (from two different journal pages). I just want a bulleted list of the blocks without the references to where they came from.

I will look at the :view options.

Could be easier with custom.css, something like this:

.custom-query .foldable-title ,
.custom-query .breadcrumb.block-parents {
  display: none;
}

No, I’m an idiot. I typed “beadcrumb-show” instead of “breadcrumb-show”. Everything appears to be where it needs to be now.

Thank you for your patience and expertise.