Looking for some thoughts regarding Dataview and repeated properities

What I’m trying to do

I use Obsidian for meeting notes. When I have a recurring meeting, I use a single note and create a H1 level header with the date as a property. When the attendees of the meeting change, below the Date header, I add an Attendees property to capture who attends the meeting. I use the single note approach as it provides context and reference without having to have multiple notes open.

Each morning I create a note for each meeting, or add a new Date H1 header in my recurring meetings

Example meeting notes file

---
Type: Meeting
tags:
 - "#Meeting/Recurring"
---

# Date:: 2025-03-14T09:00
Attendees:: [[John]], [[Paul]], [[George]]

*meeting notes*

# Date:: 2025-03-21T09:00
Attendees:: [[Paul]], [[George]], [[Ringo]]

*meeting notes*

# Date:: 2025-03-28T09:00
Attendees:: [[George]], [[Ringo]], [[John]]

*meeting notes*

I use Dataview to tabulate the upcoming meetings, including who is attending, so that I can be prepared for the meeting.

I’m struggling to create a table that shows the one upcoming meeting with just the list of the attendees to that meeting. It would be trivial if Dataview could reference the H1 header.

Things I have tried

This is my current attempt. It works, but the list of attendees is everyone who has ever attended the meeting, as opposed to the list of those attending the upcoming meeting. Every attendee has a dedicated note, with properties to define who they are, which are referenced in the query below.

TABLE WITHOUT ID firstvalue(rows.file.link) AS "Meeting", 
	dateformat(max(rows.Date), "ccc HH:mm") AS "When", 
	choice(contains(rows.file.frontmatter.tags, "Meeting/Recurring"), "Yes", "") AS "Recurring",
	rows.Attendees AS "Who", 
	rows.Attendees.Companies AS "From",
	rows.Attendees.Title AS "Role"
FROM !"Templates"
FLATTEN Date
WHERE Type = "Meeting" AND (max(Date) >= (date(now) - dur(1 h))) AND (max(Date) < (date(now) + dur(7 days)))
FLATTEN unique(flat(Attendees)) AS Attendees
GROUP By Date
SORT (rows.Date) ASC
Meeting When Recurring Who Role
Meeting Fri 09:00 Yes George The Beatles
John The Beatles
Paul The Beatles
Ringo The Beatles

For the meeting dated 2025-03-28, Paul should not be listed.

I’ve tried using separate meeting notes for each meeting instance, and of course, the DQL is easy enough - but it breaks my workflow, so I’ve gone back to trying to solve this. Any suggestions?

Thanks

Alan

Any inline fields within a note belongs to either of these two contexts: the note itself, or the list/task context. There is no particular context for headings.

This means that in your example all of the attendees are grouped together related to the note context. Besides manually parsing the note file manually, there is no fixing this with that structure.

A better structure would be to group each meeting in separate list items, or similar. That would create a better context to group your meetings. So one structure which make your queries a lot easier would be something like:

- (Date:: 2025-03-14T09:00) - (Attendees:: [[John]], [[Paul]], [[George]] )
  - Meeting notes
  - More meeting notes
- (Date:: 2025-03-21T09:00) - (Attendees:: [[Paul]], [[George]], [[Ringo]])
  - Boring...
  - More boring stuff...

```dataview
TABLE WITHOUT ID dateformat(item.Date, "yyyy-MM-dd HH:mm") as Date,
  item.Attendees as Attendees,
  item.children.text as Notes
WHERE file = this.file
FLATTEN file.lists as item
WHERE item.Date AND item.Attendees
```

This would give you an output like:

And hopefully you get how that query works, and is a lot easier to structure and work with.

Thank you - I’ve adapted one set of meeting notes and it appears to work. Certainly the query looks simpler and clear enough for me to adapt to my needs.

I appreciate your insights, thank you.

1 Like

I’ve landed on a hybrid approach that gives me everything and more… I’d struggled to integrate my existing, non-recurring meeting notes with the list based approach and when exploring the available metadata, noted that Lists capture the preceding header.

I’m now keeping Date as a header in recurring notes, and then making Attendees a list item below the header. With this approach I can track the header info and still get the Attendees broken out. I also get the added bonus that the link in a table is actually a link to the header in the file, not just the file - which is better than I had before!

---
Type: Meeting
tags:
 - "#Meeting/Recurring"
---

# Date:: 2025-03-14T09:00
 - Attendees:: [[John]], [[Paul]], [[George]]

*meeting notes*

# Date:: 2025-03-21T09:00
 - Attendees:: [[Paul]], [[George]], [[Ringo]]

*meeting notes*

# Date:: 2025-03-28T09:00
 - Attendees:: [[George]], [[Ringo]], [[John]]

*meeting notes*

My query is a little complex to get the date from notes with Date in frontmatter, or Date from the header link - but that aside it’s pretty simple.

TABLE WITHOUT ID item.header AS "Meeting", 
	dateformat(When, "ccc HH:mm") AS "Date",
	choice(contains(file.frontmatter.tags, "Meeting/Recurring"), "Yes", "") AS "Recurring",
	item.Attendees AS "Attendees"
FROM !"Templates"
FLATTEN file.lists AS item
WHERE Type = "Meeting" AND item.Attendees
FLATTEN choice( contains( file.frontmatter.tags, "Meeting/Recurring"), date( replace( replace( meta(item.header).subpath,"Date ", ""), " ",":")), date(file.frontmatter.Date)) AS "When"
WHERE date(When) >= (date(now) - dur(1 h)) AND date(When) < (date(now) + dur(7 days))
SORT When DESC

And now my output is

Meeting When Recurring Who Role
Meeting > Date 2025-03-28T09:00 Fri 09:00 Yes George The Beatles
John The Beatles
Ringo The Beatles

It’s a minor change in my workflow for recurring meetings, making Attendees a list item, and a minor change for regular meetings, moving Attendees out of frontmatter and making them a list item at the top of the note. But with those two changes appears to meet all my needs.

Again, thank you for your insights on using lists, that made the difference for me.

1 Like

I do believe you could extract the date easier than you’ve done, and you have some strangeness related to using file.frontmatter.*, but there is a quick note you need to be aware of when it comes to doing FLATTEN file.lists as item, and that is to limit your query as much as possible before you do the FLATTEN.

Imagine a vault of 100 000 files, where each file have 10 list items, but only a 1000 of those files are meetings. (Translate into better number for your use case, but you’ll get the idea).

With your current setup, you only eliminate the template files, lets say 1000(?) files, you’re now done to 99 000 files, which you flatten into 10 rows for each file making it 990 000 rows of items (with the file information attached). Then you decide to only use the 1000 meeting files, aka 10 000 rows of items being meetings, and only those having attendees.


I hope you understand that switching the order of these lines (or even duplicating some of the logic) makes for a better query:

FROM !"Templates"
WHERE Type = "Meeting" AND Attendees
FLATTEN file.lists AS item
WHERE item.Attendees

Now you’ll first go down to the 99 000 files, then the 1000 files (and loose some because there are no attendees), and then you expand into 10 000 item rows (and possible loose even more due to the others having attendees not in a list item).

2 Likes

Thank you again - your proposal significantly improves the performance.

I have about 2000 notes and many lists. Moving that line up made a significant change in performance - from tolerable, but frustrating to near-instantaneous…

I’ll have another look at the date extraction - I iterated my way to it.

Thank you!

1 Like

Actually, I ended up using a date filter - most of my notes were meetings, with attendees, but the filtering before flattening made a huge difference.

Thanks

1 Like