Dataview to aggregate all mentions of 3 links into a table with 3 columns

I did my best to research this on my own but couldn’t find an answer. I really like Ness Labs Plus Minus Next journaling and I wanted to create a weekly review that follows this format.

Here is what I’m trying to do:

  • On Sunday, I look through my daily notes and anything else created/finished in the last week.
  • As I’m looking through them, I add one of these links to the bullet: [[+]], [[-]], [[→]].
  • Use dataview in my weekly review template to create a table with +, -, and → at the top of each column.
  • in Each column is a list of text with the places in the last week that has any of those links.
  • A link to the file it came from would be great too.

(perhaps I need to use more specific links like [[+|week 22-2023]] or something like that but I’m also hoping I can visit the [[+]] page and see all the plus’ I’ve ever added in one place.)

There might be a better way to accomplish this and I’m certainly open to suggestions. Basically, I want to create this plus, minus, forward list each week and would love those entries tied to their original day. I could do it manually as well but hoping to create a little more automation/context around the reviews.

Could you show some examples of actual links in your daily notes, and how are your daily notes named/tagged/… ? How are the daily notes linked to your weekly, if any?

We need to see some markup in order to help you with any query, and if you’ve got some of the query to start us of it would be better. This should be doable, but we need a little more information as suggested above.

I’m not sure if you’ve chosen the optimal markup using ordinary lists with the plus/minus links. I’m kind of thinking it might be very nice to use decorated tasks where you use + - → as the status character. This would make the gathering of the weekly review a rather simple task query.

Not entirely sure on the table format, but if you presented it as tasks you’d also get the link back for free.

Then your query could possibly look something like:

## Plus
```dataview
TASK FROM "daily notes"
WHERE ... this week ...
  AND status = "+"
```

Where you would need to fill in the blanks to select current week somehow, and duplicate to the other sections. Another benefit of using decorated tasks would be that you could style them within the daily notes themselves to make it very clear how the different tasks are categorised.

Thanks so much for the fast reply/suggestions. I’m pretty new and my code might be a mess but I’ll do my best.

In my daily note I have a log heading. I write things like:

  • went on a walk with friend.
  • exercised 3 days this week.
  • Wrote out my course plan in Obsidian.
  • I missed my deadline to sign up for course.
  • Ate a lot of garbage.

Later in the week, I would look through my notes and add links like so:

  • went on a walk with friend
  • exercised 3 days this week. [[+]]
  • Wrote out my course plan in Obsidian. [[+]]
  • I missed my deadline to sign up for course. [[-]]
  • Ate a lot of garbage. [[-]]

My hope was to have them in columns similar to the image. I’m not exactly sure what this is doing it kind of does what I want with just plus:

```dataview
TABLE rows.L.text AS "Plus"
FLATTEN file.lists
AS L WHERE contains(L.text, "[[+]]")
GROUP BY file.link AS "From"
```

Here is what I get from the above:

I’m shooting for another 2 columns, one for “Minus” and one for “Forward”. Like so:

But what I really want to do is avoid the “From” column and link directly from the text to the note so it would look like this:

Thanks again for your help. I hope this is a little clearer. Cheers!

This is not the cleanest query I’ve written as it depends on filtering file.lists and then filtering on their outlinks. But I ran the following query on a file which had the list you presented as an example:

```dataview
TABLE WITHOUT ID
  map(
    filter(
      file.lists,
      (l) => l.outlinks AND
             filter(
               l.outlinks,
               (o) => meta(o).display = "+")
    ),
    (m) => regexreplace(m.text, "\[\[.\]\]", "")
  ) as Plus,
  map(filter(file.lists, (l) => l.outlinks AND
    filter(l.outlinks, (o) => meta(o).display = "-")), (m) =>
      regexreplace(m.text, "\[\[.\]\]", "") ) as Minus, 
  map(filter(file.lists, (l) => l.outlinks AND
    filter(l.outlinks, (o) => meta(o).display = "→")), (m) =>
      regexreplace(m.text, "\[\[.\]\]", "") ) as Next 
WHERE file = this.file
```

The column expression for Plus, Minus and Next are the same, I’ve just expanded the one for Plus in a slight hope that it illustrates what is the input to the various map and filter’s.

The query gave this output:

The thought behind this is as follows:

  • For each column we want to filter out list items that have one of the three status characters as an outlink from that item. So to do this we need to do the following:
    • We need to filter out the file.lists matching our requirements so we can map out the text, m, without the actual link
  • When filtering the file.lists, we’re only interested in items, l, which have outlinks, and where there are filtered outlink
  • When filter the l.outlinks we’re only interested in outlinks, o, which have a display part equal to either of our status characters

This monstrosity is then repeated for each of the other status characters, and we get the output you want. The only thing now is to exchange the WHERE file = this.file with some expression matching the weeks daily notes. (And possibly to remove the WITHOUT ID to display the file link again)

Here is a full file with the links rewritten as tasks status:

- went on a walk with friend
- [p] exercised 3 days this week.
- [p] Wrote out my course plan in Obsidian.
- [c] I missed my deadline to sign up for course. 
- [c] Ate a lot of garbage. 
- [>] Going to eat more garbage.

```dataview
TABLE WITHOUT ID
  map(
    filter(
      file.tasks,
      (t) => t.status = "p"
    ),
    (m) => m.text
  ) as PlusTask,
  map(filter(file.tasks, (t) => t.status = "c"), 
    (m) => m.text) as Minus,
  map(filter(file.tasks, (t) => t.status = ">"), 
    (m) => m.text) as Next
 WHERE file = this.file
```

Or presented as tasks:

```dataview
TASK
WHERE file = this.file
  AND contains(list("p", "c", ">"), status)
GROUP BY object(
  "p", "%%0%% Plus",
  "c", "%%1%% Minus",
  ">", "%%2%% Next")[status]
```

I’ve used p, c and > instead of your character, since in my setup, the - is used for marking deleted tasks and I didn’t have any setup for + and as status characters. With my extra CSS this displays as:

That last section where they’re also displayed as tasks, links back to the origin of the task (as all task text does in a task list).

If you compare these queries with those in my previous reply, it should be clear which one I would favor regarding complexity and readability and so on. :smiley:

1 Like

Thanks so much @holroy! This certainly gets me much closer to a solution and might just be the way I end up going. Thanks for breaking things down so clearly. Cheers!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.