Tags & Subtags - Filtering Dataview Results to Show/Not Show Results with Subtags

Things I have tried

I spent countless hours on this the last two days, trying a million things, reading the dataview user guides, and also a ton of forum and web posts, and I’ve finally thrown my hands up as I’m just not understanding the coding. (I’m not so technically-minded).

I posted a version of this as a reply to another very long thread and it might have gotten lost in the shuffle or it was just getting too convoluted. So I thought I’d break out this particular part of the question and simplify it in the hopes some fresh eyes can figure out what I’m doing wrong.

What I’m trying to do

I’m creating a workflow where I am aggregating snippets of text from various articles. In those articles I’m flagging/tagging quotes, talking-points, facts, etc. and then using dataview to return the results in a table. It’s working great and am very excited at how powerful this will be in my research.

The only problem that I’m running into is that I use a lot of subtags. There are times that I want to see results only with the exact tag and none of the subtags, and there are other times where I want to see the opposite—I want to see results of all tags and all the subtags.

Another case is when I’m trying to limit my results based on two tags in and “AND” situation. I want to see only results that have both tags, but when the tag has a subtag, it seems to treat it as an “OR” situation. When the tags are not direct, neighboring subtags, it works correctly.

I was able to solve the problem in some use-cases with “econtains(file.etags, “#pin/topic/test”)”, but in other cases, it doesn’t work.

The following are examples of my results. Thank you in advance for any advice on solving this.

  1. Here, I want to limit the results so that dataview doesn’t return subtags. The following code still returns #pin/topic/test/subcategory. I tried various placements of the “econtains” line as well. I also tried replacing “file” with “item” and other guesses.

This code works when I have the following type of use-case (it doesn’t return any subtags of #note/type/person), but I need it to work with more complex use-cases.

TABLE WITHOUT ID link(file.link, Title) AS "Title", Aliases, Occupation, Employment, Born, Death, Birthplace, Note
FROM #note/type/person AND -"Templates"
WHERE econtains(file.etags, "#note/type/person")
SORT file.link ASC

Here it doesn’t work—I don’t want to see the subcategory.

  1. Relatedly, when I’m wanting to return only the quotes that have BOTH tags, it only works if one of the quotes is not a direct subtag of the other (even though they are both still subtags of the previous level down). This case works because one of the tags was changed to “test2” (which I don’t want).

  2. But, if they are direct subtags of each other, then I get both quotes (which I don’t want). I will want to see subtags sometimes and sometimes not, and if so, is this the proper way?

I tried the above w/ a number of “econtains” variations as well, but that gave me no results at all. e.g. I get no results with this.

  item.Quote as Quote,
  item.Source as Source,
  item.Topic as Topic
FROM -"Templates" AND -"_Inbox"  
FLATTEN file.lists as item
WHERE item.Quote
  AND econtains(file.etags, "#pin/topic/test/science")
  AND econtains(file.etags, "#pin/topic/test")
Sort item.source ASC

Thanks again, I know this is a lot, but I’m determined to solve this so I can move on to the actual article markup! :slight_smile:


Still praying :pray: I’ll get some help w/ this, but in the meantime, had a little addendum.

I’m realizing that my tags do not always have the same tag/subtag heiarchy.

In the case of #cat1/subcat1/subcat2

As I mentioned above, sometimes I want to see

#cat1 and all of the subtags, i.e. subcat1 & subcat2
Sometimes I want to see only #cat1/subcat1 and not anything with #cat1/subcat1/subcat2

But I do have some tags in which the order or exact spelling is different, e.g.


Considering the original post question, can dataview return results for notes with any tag in which the word “pardon” appears w/o having to match the whole thing? That way I can get all notes with both those tags and any others I might have missed without having to list them all individually.

Thanks in advance!

The reason why both your examples don’t work the desired way is that dataview breaks down tag hierarchies in the following manner:

If you have a tag named #pin/topic/test/science, for dataview your note contains the following tags:

  • pin
  • pin/topic
  • pin/topic/test
  • pin/topic/test/science

If you only want to show results containing #pin/topic/test (but not #pin/topic/test/science): have you tried inserting a space in your query? Like contains(item.tags, "#pin/topic/test ")? Not sure if that works, but worth a try…

Really appreciate the feedback, I did try that, but when you make a space there, I get no results at all. It’s strange, it’s hard to actually figure out what it’s doing as the results (seem) to be inconsistent, but there’s probably a logic there that I’m not getting. I’ll keep at it!

I think all (or most) of your question will be answered, if you read and execute the stuff from my recently created post in Share and showcase:

Please don’t take the easy route, and just skim it. Create the notes, and copy the raw text into your vault, and go through the various examples of how the various contains and friends works.

When you understand that, you should be able to combine the correct versions of these utility functions into your WHERE clauses like you’ve done already with partial success. Hopefully, that post will raise your understanding enough to figure this stuff out, and get to the completeness of your queries you want.

Without actually spoon feeding you that’s the best I can do.

1 Like

Thanks so much for taking the time to make that post and followup here…
I started the process, made 4 files, added the tags and tried the first dataview snippet.
already, I guess I’m missing something as I’m getting no results.

Here’s a screenshot of two snippets in plaintext above the actual results.
I made the files I believe as you said, and even tried to put a hashtag in front of the second tag because I didn’t know what you meant by “with that last tag specified”

filename as I believe you instructed

Screenshot 2023-01-10 at 21.03.18

filename with extra hashtag in front of 2nd tag

Screenshot 2023-01-10 at 21.03.13

dataview snippets and results

I feel a bit stupid, but hopefully you’ll find some patience with my technical difficulties.



p.s. there is a part of your post so far that has what I think is a mistake, but just double checking.
Screenshot 2023-01-10 at 21.10.08

Loose the hashtag in front of #f51705… Corrected the post in both places.

Great, thanks, nice of you to make that post…been going through it, have some questions, but I’ll go through it a couple of times before posting anything…it’s a little confusing to keep track of all the variations, but it’s becoming more clear.

Dear @holroy, I’m about 3/4 of the way finished, and will definitely have to go over it a time or two before fully understanding and asking any followup questions (if any).

But in the meantime, I had two questions/concerns.

    1. A different post I read suggested that if the tags are in YAML vs. in the body that the solutions can be different, or non-existent if the tag is not in YAML. In any of your examples, will what I’m learning be different if the tag is in the body of the note?

In my main use-case, when I’m pulling quotes from an article, I tag the quote in the inline tag in the body and rarely do I go back to the YAML to repeat the tags there as that would increase time and friction. I only put tags in YAML for global tags/subjects.

    1. Is there a way in your examples to show an extra column that lists the actual tags matched as opposed to just the page title and “true”/“false”? You do a vesion of this in the very first example, but I couldn’t apply it to the others w/ out error.

I can just look at the page title for some of the easier examples you posted, but it would be much faster to scan, and allow me also to more complex scenarios quickly.

  • A more complex scenario might be, if I want dataview to display all the people pages that have a combination of let’s say, #pardons (+ any subtag of #pardons) with exactly the tag (no subtag) of #us-presidents/president1

It would be very helpful to see which subtag it actually found. when returning the pages E.g.

Person1, #pardon/recieved
Person2, #pardon/asked-for
Person3, #pardon/asked-for/denied

An more complex scenario, but not sure if possible, would be let’s say, #pardons (+ any subtag of #pardons) with any version of #us-presidents/president* (there are subtags of president1, but I dont want to see them). E.g. Dataview returns:

Person1, #pardon/recieved, #us-presidents/president1
Person2, #pardon/asked-for, #us-presidents/president1
Person4, #pardon/asked-for/recieved, #us-presidents/president2

For this last one it might be enough just to know it’s possible, but in any case, finding a way to display the actual matches would really help me learn what’s going on immediately.

Thanks as usual for sharing your knowledge!



In general my experience is that it doesn’t matter. If you see references to file.frontmatter.type you’ll get a hint that this is from the frontmatter/YAML, but in most case you’ll use file.type, and then it shouldn’t matter at all.

That would require a lot of extra expansion, which would really complicate the output. It’s better to just type out what file.tags actually is for each of the files, and see which one make sense. And for file.etags is just the one tag for that particular note (since each note has just one “meaningful” tag, aka the #aa/bb/cc thingy, and one for reference, the #f51705.)

Once you get to know the syntax to properly get any part of that scenario it’s just a matter of combining them with a proper combination of AND and/or OR. Know your building blocks, and you can build whatever.

Whenever you feel like building a complex scenario like that with pardon’s and presidents, you can start out with a table query, where you actually lists out either file.tags or file.etags or potentially a filtered version of the tag lists to narrow done the list to those related to the query at hand.

So that you could write something like: file.tags.filter((f) => startswith(f, "#pardon") to all tags starting with #pardon in current file.

But don’t go swimming at the deep end for starters. Learn the basics, and then extend as you get to know the variants.


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