Using Aliases in Dataview

What I’m trying to do

I have people notes with Aliases, and I have meetings where they are in YAML Frontmatter as participants. I am trying to create a dataview table inside my people note asking “which meetings have I had with this person, using their aliases”

Things I have tried

A shortened example People note might be

John Johnson
---
aliases: John Johnson, John J., John
---

And then an example meeting note might be

2023-01-02 - Meeting
---
type: meeting_notes
participants: John J., Suzy S., Carl C.
---

A regular dataview query that works is:

TABLE file.cday as "Created"
WHERE type = "meeting_notes" WHERE participants = "John Johnson"

Which gives me just that person, and only if they’re the only participant. So the 2 problems I want to solve are 1) I can’t have multiple participants, or 2) search with aliases from the person file. To solve the second problem. Two examples that aren’t working for me are

TABLE file.cday as "Created"
WHERE type = "meeting_notes" WHERE contains(file.aliases, participants)

and using “this.file.frontmatter.aliases” instead of “file.aliases”

Any thoughts?

It all comes down to markup in the frontmatter. What you’ve listed are fields defined as a single text (or string), and not a list (or array) of different names. This causes issues for you when defining them, and when trying to match against them.

Please check the following markup, and see if you spot the differences:

---
Tags: f55779
p1: John Johnson
p2: John Johnson, Mary Marison
p3: ["John Johnson","Mary Marison"]
---
questionUrl:: http://forum.obsidian.md/t//55779

```dataview
TABLE WITHOUT ID p1, typeof(p1), p2, typeof(p2), p3, typeof(p3)
WHERE file.name = this.file.name
```

This produces the following output:

See how the two first varianst, p1 and p2, are of type “string”, and they show everything as one line? And the last one, p3, shows a list of two entries, namely “John” and “Mary”, and is of type “array”.

Your equality comparison

When using something like participants = "John Johnson", you’re doing an equality match, and that matches only if both sides are identical. They’re not equal if one of them is just a part of the other, or vice versa.

Using contains() on non-lists fields

This could to some extent be countered by doing contains(participants, "John Johnson"), as we would then be matching against a part of the string. So this would check whether participants had “John Johnson” anywhere within it. This would however also match if your participants had been defined as participants: Robert John Johnson which most likely would be some other dude…

And furthermore, if you tried doing contains(file.aliases, participants) (with your definitions of them), it would require for the entire string of participants to be found within file.aliases. In other words, it would only work when participants is a single person and its aliases is fully defined in file.aliases.

A better approach

First of all, you’ll need to properly define lists of names (or aliases) in your files, so using your example files, you’d need to do something like:

John Johnson:

---
aliases: ["John J.", "John"]
---

2023-01-02 - Meeting

---
type: meeting_notes
participants: ["John J.", "Suzy S.", "Carl C."]
---
Two solo meetings with only John

2023-01-12 - Solo Meeting

---
type: meeting_notes
participants: John Johnson
---

Note how this is just one person, and no quotes or brackets

2023-01-22 - Solo Meeting 2

---
type: meeting_notes
participants: ["John Johnson"]
---

And this time, it’s both quotes and brackets, but still only one person

With this syntax, and the following query (note that I’ve removed the full name from the alias, in favor of re-adding it into a list combined with the aliases. You could remove that part, and only use the aliases, if you always define the full name into the aliases part. I kind of prefer not to do that in my files. Anyhow, here’s the query:

```dataview
TABLE participants

WHERE file.folder = this.file.folder
WHERE type = "meeting_notes"
  AND filter(list(this.file.name, this.file.aliases), 
             (f) => econtains(participants, f))
```

Which produces this output:

Notice that I’m using filter in a two-folded matter here, first of all it allows me to check each of names (from this.file.name and this.file.aliases) and to only keep those being fully contained in participants lists. So no partial matching, only full matches.

Secondly, I’m using the side effect to include the file (that we’re testing against), if and only if, the filter returns anything. So if neither of the names matches against any of the participants, the filter returns nothing, and the meeting is not listed.

Switching participants and aliases in query

Note that I also tried the query below, and it fails to report the first solo meeting with only “John Johnson”:

```dataview
TABLE participants

WHERE file.folder = this.file.folder
WHERE type = "meeting_notes"
  AND filter(participants, (p) => contains(list(this.file.name, this.file.aliases), p))
```

I’m not quite sure why it doesn’t report the first solo meeting, but I reckon it’s somehow related to the participants in the first solo meeting being a string and not an array.


So in order to get your queries to work, you need to ensure that you’re using lists of names in your participants lists, and in your aliases. Then it’s possible to use either full name or aliases to check for participation using a combinations of filter and econtains.

3 Likes

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