DataviewJS: Query with DQL

Things I have tried

I’m able to write a manual dataviewjs query that uses yaml attributes like so:

```dataviewjs
dv.pages()
  .where(p => p.type == "project" && p.status == "active")
```

What I’m trying to do

But instead I want to use a DQL query as the source. Here is the dataview query that I would like to use as the source in my dataviewjs code:

```dataview
List
WHERE type = "project" AND status = "active"
```

I would like this because:

  • I find the DQL syntax more convienent and readable
  • I have a suspicion that the DQL query is more performant than the dataviewjs query because it would be easier to use an index (although I’m not sure if dataview currently uses indexing)
  • I already have a bunch of DQL queries and I don’t want to have to rewrite them in order to start using dataviewjs

Does anyone know if this is possible. From the dataview dv.pages docs it seems like it may not be supported. Does that mean that this would be a feature request?

Another reason I like DQL is because I don’t know how to add an ORDER to a dataviewjs query (without manually writing my own javascript sort by looping through all the returned pages).

It’s easily done by using either of the dv.query() variants, see Codeblock Reference - Dataview, where each of them has their pros and cons.

I often find my self doing something like the following:

```dataviewjs
const result = await dv.query(`
LIST
WHERE type = "project" AND status = "active"
`)

if ( result.successful ) {
  // console.log(result)
  dv.list(result.value.values)
}
else
  dv.paragraph("~~~~\n" + result.error + "\n~~~~")
```

What’s returned in result varies a little depending on what query you run, but you’ll get the hang of it rather quickly, especially when you know how to navigate and use the Console pane in Developer Tools.

You add a .sort(p => p.type) statement (or .sort(p => p.type, "desc") for the reverse variant), or similar. And if you want to manipulate stuff you can take it all out and execute normal javascript by introducing a code block, { ... }, like in:

   dv.pages()
     .sort(p => {
       console.log(p);
       // do whatever with p
       return p.something
    })

On the topic of what is and isn’t possible, I also suggest looking at Data Arrays - Dataview On the last part it shows all the different function calls available related to dv’s data-array implementation.

And there is nothing stopping you from running a dv.query() like above, and then do something like result.value.values.filter(f => f.something == "something"). So the flexibility is all over the place…

2 Likes

Thank you!!! That was amazingly helpful!

For future reference here’s my final query:

```dataviewjs
const result = await dv.query(`
LIST WITHOUT ID file.path
WHERE type = "project" AND status = "active"
SORT priority asc
`)

if (result.successful) {
	if (result.value.values.length > 0) {
	    const query = `
	        not done
	        (path includes ${result.value.values.join(') OR (path includes ')})

	        # you can add any number of extra Tasks instructions, for example:
	        group by path
	    `;

	    dv.paragraph('```tasks\n' + query + '\n```');
	} else {
	    const message = `No files found`
	    dv.paragraph(message)
	}
} else {
	dv.paragraph("~~~~\n" + result.error + "\n~~~~")
}
```

It’s an adaptation of an Obsidian Tasks example for my own needs

Quick followup question, why do you prefer dv.query over dv.tryQuery? It seems like it can be shorter to use dv.tryQuery and I’d guess the error reporting would be relatively simpler.

I’m a programmer, so I like having the control and possibility to do stuff even when it fails. Using tryQuery removes some of that control and some debug options.

But feel free to use it, if you want to. Most of the time everything is good anyways.

1 Like

Ah, k. That makes sense. Thanks!

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