blacksmithgu / obsidian-dataview

A data index and query language over Markdown files, for https://obsidian.md/.
https://blacksmithgu.github.io/obsidian-dataview/
MIT License
6.9k stars 407 forks source link

Block/heading queries #30

Closed rapatel0 closed 1 year ago

rapatel0 commented 3 years ago

It would be great to be able to filter based on block or sections link in the standard search.

blacksmithgu commented 3 years ago

I'm currently working on fancy new query syntax for block/section-level queries (as well as link-based queries). Do you have any examples in mind, so I can make sure it's supported?

robhawkes commented 3 years ago

Not sure if this fits into blocks/section-level but a use-case I have is that I define events across random files as list items:

File 1:
- Some event in File 1 #event #2021-03-01
- Another event in File 1 #event #2021-03-02

Another file:
- Some event in File 2 #event #2021-03-01
- Another event in File 2 #event #2021-03-02

Those files may contain all sorts of other content surrounding the list items, and the list items could be spread out across each file.

From there I'd like to pull those line-items into a consolidated list somewhere else. This is how I currently do it with the official query syntax (removed backtick to show as code):

``query
line:(#event)
``

Or if I wanted to only show line-items relating to this month:

``query
line:(#2021-03)
``

The problem with the built-in queries is that the output is noisy and cumbersome and cannot be configured, unlike Dataview.

rapatel0 commented 3 years ago

Here's an example - I have a morning checklist in my Daily notes

    - [x] #Health/Vitamins Vitamin D
    - [x] #Health/Vitamins B12 Vitamin
    - [x] #Health/Vitamins Iodine
    - [x] #Health/Vitamins Calcium 
    - [ ] #Health/Vitamins Omega3s
    - [x] #Health/Water Fill Water Jug

With Dataview i could do some analytics on how often I'm actually doing stuff if that makes sense. Could sub stratify on vitamins or health in general, for example

FekketCantenel commented 3 years ago

I am stubbornly attempting to replicate how, in Roam Research, you dump notes into your Daily Note like so:

Then on a Quotes page, I would use a dataview to pull all the lines tagged #quote and display them, ideally grouped by secondary tags.

On my Productivity MOC, I'd have:

The latter three are technically possible with the vanilla query codeblock but only shows a portion of the retrieved text. @robhawkes is exactly right re "the output is noisy and cumbersome and cannot be configured, unlike Dataview."

(The Obsidian expectation seems to be that I create a new page for every single quote, which is cumbersome and would clutter my precious Graph View.)

evfro commented 2 years ago

I am also very interested in this feature. My typical use-case is as follows.

For example, in my daily note 2021-10-07 I may have the following (mind indents):

[[Project A]]
  - [ ] task of project a

[[Project B]]
  - [ ] task of project b

I also have a separate note with project-related task queries, where I want to gather tasks not only from project pages directly, but also from all other pages including daily notes.

There, I'd like to have the possibility to list tasks of only specific projects. Currently, the following query

``dataview
task 
from [[Project A]]
where real and !completed
``

would return tasks for both projects:

2021-10-07
  - [ ] task of project a
  - [ ] task of project b

as it only checks for link existence, but does not limit the query to a block scope.

Not sure about the syntax to specify block scope in such query, though. As was already mentioned above, from the standard Obsidian query perspective, the task can be accomplished by e.g.

``query
line:"Project A" task-todo:""
``

that would display

2021-10-07
  [[Project A]]
    - [ ] task of project a

But standard Obsidian queries are not very convenient for what I'm trying to achieve. They lack interactivity and one has to manually expand query results, if there are many tasks under the project.

It seems that having block scope specification for dataview queries would be a perfect solution for the described scenario. It would facilitate two potentially independent regimes:

  1. brainstorming, when new ideas and tasks are generated without switching contexts (daily notes <--> project pages), so that creative process is not interrupted;
  2. planning / analyzing, when a more consolidated and organized view is required.
blacksmithgu commented 2 years ago

Block/heading queries are high on my TODO list. Support will probably come through DataviewJS first (since it is easier to expose data there), and then in queries via the improved query syntax later.

rlopeznegrete commented 2 years ago

Will follow as I'm keenly interested in this functionality. Hopefully soon...

Thanks a lot for this great plugin!

iris2jane commented 2 years ago

Wow~I really want to associate the blocks in the outline with CSV or markdown files and present them in outline order👇

截图_20215820125839

kurtharriger commented 2 years ago

I am also experimenting with using block ids as a method to store metadata for tasks in yaml instead of inline text. I find putting metadata on same line begins to feel noisy.

I found that if the task has a block id I could grab the blockid from the link and store the metadata in yaml.

And now I am thinking it would be great if I could add yaml metadata to any block id, but there doesn't seem to be an easy way to query a list of block ids yet.

blacksmithgu commented 2 years ago

@kurtharriger I can see same-line metadata being quite noisy - there is incoming support for adding metadata via sublist elements, though that is also a little noisy. Being able to externally store metadata by { file, section, block } ID is an interesting idea - there is incoming support for easily loading YAML data (via dv.io.yaml()), which should make homebrewing this via scripts a little easier. Block IDs are being added as available metadata to tasks; I'm experimenting with also indexing any markdown block that has an explicit block ID (which is paragraphs, headers, and list items currently).

charleshan commented 2 years ago

indexing any markdown block that has an explicit block ID (which is paragraphs, headers, and list items currently)

This would be a big improvement but if you were to do this, wouldn't it be better to index every line? It looks like Obsidian is already doing this.

``query
line:keyword
``

Obsidian has different search operators for content, line, blocks, section, etc.

https://help.obsidian.md/Plugins/Search#Search+operators

person-al commented 2 years ago

I'm also glad to see this on the roadmap! I'd also like to be able to access Dataview fields on a "per section" basis. My use case is files that contain different sections of the same types of data in them, for example:

# Books I've Read This Year

## Tale of Two Cities
Start Date:: 2021-01-01
End Date:: 2021-01-05
Rating:: 5
Genre:: Classic
Would Recommend:: true

## War and Peace
Start Date:: 2021-02-01
End Date:: 2021-02-20
Rating:: 3
Genre:: Classic
Would Recommend:: false

The goal being to be able to treat "sections" of a file the same way we currently treat files. So in addition to having dv.page("books/Books I've Read This Year.md"), which produces a page object with all the fields available as properties, one could also do: dv.page("books/Books I've Read This Year.md").sections(), which would return an array of section objects that also contain all the fields in that section available as properties.

The DQL, perhaps, could have something like...TABLE section.name, file.day FROM <source> the same way we currently have TABLE file.name, file.day FROM <source> available?

Not trying to be prescriptive here, just trying to share some thoughts/ideas, since it is such a complicated request as you've noted. I think the biggest complication in my mind is how to deal with the different levels of sections. Some people may want H1, some may want H2... you may actually need to add some kind of dataview field or tag to the header to denote to dataview how the page should be divided into "sections". Or perhaps it only supports it's lowest level section.

Thanks so much for your work on this plugin, you've enabled so many of us to supercharge Obsidian. You've done an incredible job!

auralluring commented 2 years ago

I'd really like to be able to treat sections as a sort of alternative to objects in YAML. Different levels of headers could denote nesting, for example:

# top level:
 ## middle level:
  ### bottom level
 ## middle level 2

If there was no middle level, it would go straight to the next one down (the bottom level). This way I could loop over the sections and selectively extract which metadata I want.

Zygar commented 2 years ago

Stoked to see this is in the roadmap. Similar use-case to @evfro here:

March 7, 2022.md

- Some random notes from a day
- [ ] A random task from a day
- [[A project name]]
  - Some meeting notes 
  - Some more meeting notes
  - [ ] Action from that meeting
      - Some extra context 
      - Some more context, maybe even some #tags or other metadata. 
  - [ ] Another action from that meeting 
  - [[T52-A really big task]]
T52-A really big task.md
---
for: [[A project name]]
---
- [ ] The task in question
   - A bunch of extra context

I'd love to be able to query [[A project name]] and receive something like:

Ideally with the ability to filter based on whether the task's child (or parent, or parent file) contains certain metadata (e.g. #deep-work); a link to its original page, and foldable/unfoldable context (children of block)

This would be a gamechanger to my variant of GTD and finally get me off Roam Research!

autolyticus commented 2 years ago

I don't really use tasks that much, but this feature request seems to include the capability that I've been looking for which is transcluding sections from a larger file.

For eg. I have different log files for different projects/areas of my life (à la PARA):

Research Log.md
# 2022.06.18.1132
- Read paper X

I would love to be able to transclude or embed just the relevant sections into my daily/weekly notes so that I can see a dashboard of what I worked on. This would enable the periodic notes to just be a view reflecting the reality that goes on in the specific area, which also has the added benefit of letting me add notes in their correct context. The correct context is what I'm doing and what I've done in the past on the same project/area, not what I've done on that particular day/week!

If I'm understanding this feature right, this would enable just that! So just wanted to mention this potential use-case as well.

Currently I am using the native Obsidian query syntax for this:

```query
(section:("2022.06.18") -file:("2022-W24"))


But I'd much prefer it if I could make use of the dataview rendering and transclusion goodness rather than the native Obsidian search results that appear.
AB1908 commented 2 years ago

@Zygar, your use case seems possible now though it may take a bit of work to set up correctly.

AB1908 commented 2 years ago

@reisub0 does your section content include non metadata stuff like paragraphs of text?

autolyticus commented 2 years ago

Yep, I essentially would like that whole section transcluded.

ryanwwest commented 2 years ago

Does the fact that this issue was closed as completed mean that you can now query by both block and heading? I must have missed info on that release?

AB1908 commented 2 years ago

@ryanwwest, yeah section level filtering was added recently. Can you go through the release notes for the recent 0.5.x releases?

AB1908 commented 2 years ago

@reisub0, I'm afraid we're going to need some JS for that since non-metadata content isn't indexed by Dataview.

autolyticus commented 2 years ago

@AB1908 I understand, I am not averse to JS myself, but I couldn't really follow how to do it with the current dataviewJS APIs. I also tried to find clues by going through the recent release notes for 0.5.x as mentioned above, I couldn't see anything mentioning this feature.

AB1908 commented 2 years ago

No worries, I'll try and get something around the weekend. Meanwhile, you can look up some snippets from the discussions.

EtienneSafa commented 2 years ago

For me it would be : Compile Zettelkasten notes and/or sections and/or paragraphs into a linear document, for example using a tag like #compile_My_New_Article :

something like

LINES from Notes
WHERE tag = "compile_My_New_Article"

⇒ would output the tagged lines, sections and files I wanna include in my new article :)

Then I'd copy-paste them into VS Code in order to rearrange them with alt + ↑ and alt + ↓

The-O-King commented 1 year ago

Hello! Is there any update on this feature? someone mentioned that there's section level filtering currently however I can't seem to find any documentation on it (although perhaps I'm misunderstanding what's being referred to there?)

Thanks :)

AB1908 commented 1 year ago

@reisub0 sorry for not following up on this earlier. @The-O-King, this feature is available. See an example here. Please note that the example vault assumes some metadata setup that is best browsed by downloading the vault itself.

bobbruno commented 1 year ago

I have a use case: I have, at the end of each of my meeting notes documents, 3 summary sections I fill when reviewing the notes, called "Decisions", "Open Issues" and "Next Steps", which I'd like to capture on a single document for all meetings over a time period for reporting purposes. It'd be great if I could just write 3 dataviews and collect all that in the same place.

AB1908 commented 1 year ago

@bobbruno this should already be doable so long as you write them as lists. Please open a separate discussion if you need help.

tonyxiao commented 1 year ago

@AB1908 are there workarounds in cases where lists aren't used? They can be a bit limiting because non-list styles such as headings / block quotes etc. cannot be easily used in lists in markdown format.

AB1908 commented 1 year ago

I actually don't know since I've forgotten how indexing works. Will have to check.

MikeMoolenaar commented 1 year ago

Seems to work now, I made a dataview from the to-do items in my kanban board:

TASK 
From "Notes/TODO kanban"
WHERE meta(section).subpath = "Today"

"Today" is the header and it has some task underneath, works great! Based on an example query from here.

GJRobert commented 1 year ago

@MikeMoolenaar this issue does not deal with TASK query. What's in need is listing contents of sections/blocks according to some criteria like query, but needs to be done with the Dataview way.

MikeMoolenaar commented 1 year ago

@MikeMoolenaar this issue does not deal with TASK query. What's in need is listing contents of sections/blocks according to some criteria like query, but needs to be done with the Dataview way.

Ah okay, sorry I misunderstood the issue

Perverance commented 7 months ago

Block/heading queries are high on my TODO list. Support will probably come through DataviewJS first (since it is easier to expose data there), and then in queries via the improved query syntax later.

Pardon my ignorance, I arrived here looking if there was a way to query lines by some criteria (not just task lists, but every line), something I couldn't figured out yet. By what I understod it means that in the future we could write something like this to list all the lines containing a particular tag?

LIST
FROM LINES:#important

Thanks!

cakechaser commented 7 months ago

@Giulidan, perhaps you'll find it useful, you can already do that with bullet lists. The following query will look for all bullet points containing "#important"

table
L.text
from "Notes"
flatten file.lists as L
where contains(L.text, "#important")

It's not very fast though.

Another option you have is to use the standard Obsidian "query" codeblock. This will search all the lines, not just the bullet lists.

Together with the "Better Search Views" plugin you can achieve a similar result with the following block:

```query
#important
Perverance commented 7 months ago

@Giulidan, perhaps you'll find it useful, you can already do that with bullet lists. The following query will look for all bullet points containing "#important"

table
L.text
from "Notes"
flatten file.lists as L
where contains(L.text, "#important")

It's not very fast though.

Another option you have is to use the standard Obsidian "query" codeblock. This will search all the lines, not just the bullet lists.

Together with the "Better Search Views" plugin you can achieve a similar result with the following block:

```query
#important

Thank you, I knew that, but I want to query not just lists, but the line that contains a particular tag. I'll check that plugin! Thank you for your help!