Optimization Challenge! Pulling related tasks from everywhere into a master page for a tag (person/project/place) #1509
-
I have written a dataviewjs that pulls tasks from that page, as well as from tasks across my Obsidian vault that are tagged with “myTag” (that is, the current page’s first alias), or that come from pages tagged with “myTag", or tasks from specific pages listed with I feel contributing this to the community would be helpful to many. Can someone better at this than me help optimize this code?
|
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 11 replies
-
The script requires the main page to have an alias (first one) in the form of a tag. (Thanks to Tag Wrangler for the idea of creating Tag Pages— note: Tag Wrangler not needed for this script to work).
|
Beta Was this translation helpful? Give feedback.
-
Likely, |
Beta Was this translation helpful? Give feedback.
-
I think the main issue is you are not making use of the dataview index. For example, in this section: if (tasksFromIncludedPages && dv.current().includetasksfrom) {
taskList = taskList.concat(
dv.pages()
.where(p => dv.current().includetasksfrom.some(n => (p.file.name == n) || (String(p.file.link) == String(n))))
.file.tasks.where(t => !t.completed &&
dv.date(t.defer) <= dv.date('today')))} You are filtering over EVERY page to find the pages that are in your list. You should not do this - instead, iterate over the pages in the list directly: if (tasksFromIncludedPages && dv.current().includetasksfrom) {
for (let page of dv.current().includetasksfrom) {
taskList = taskList.concat(dv.page(page).file.tasks.where(t => !t.completed && dv.date(t.defer) <= dv.date('today')));
}
} This should be a decent performance boost. The "tasks from anywhere" query may also be slow, but this is more Dataview's fault - I need to set up additional task indices to make finding task files faster. |
Beta Was this translation helpful? Give feedback.
-
updated to version 0.9.2. const ver = "0.9.2"
// to include in pages (simplest):
// ```dataviewjs
// await dv.view("scripts/tasklist");
// ```
// to include in pages (with all options):
// ```dataviewjs
// await dv.view("scripts/tasklist", {thePage: "Optional page name", tasksFromThisPage:true, taggedTasksFromAnywhere:true, tasksFromTaggedPages:true, tasksFromIncludedPages:true});
// ```
// parameters are optional (defaults to current page, or true if not included)
// See https://github.com/blacksmithgu/obsidian-dataview/discussions/1509#discussioncomment-4900741
// 0.9.2 2023-02-17 - Minor cosmetic touches when being passed a file
// 0.9.1 2023-02-16 - Fix a bug when there are no aliases specified
// 0.9 2023-02-07 - Added the parameter to specify a page (thePage) to pull the tasks from
// 0.8.6 2023-01-08 - Added the feature to ignore pages with #ignoretasks tag (similar to ignoring pages with #multiproject) in the tasksFromTaggedPages section
// 0.8.5 2022-12-22 - Bug fix myAliases
// 0.8.4 2022-12-16 - Output "No tasks" if no tasks.
// 0.8.3 2022-12-03 - bug fixes: if not a tag in aliases, or no aliases (so that we can still use this in any page, not just projects or people)
// 0.8.2 2022-11-18 - bug fixes: tasksFromIncludedPages can now handle none, single, list
// 0.8.1 2022-11-17 - bug fixes: tasksFromIncludedPages, can now handle inline and frontmatter fields.
// syntax in frontmatter (note outer brackets and links in quotes)
// includeTasksFrom: ["[[link1]]","[[link2]]"]
// syntax inline (note double "::", and no outer brackets or quotes)
// includeTasksFrom:: [[link1]],[[link2]]
// 0.8 2022-10-31 - Updated tasksFromIncludedPages per https://github.com/blacksmithgu/obsidian-dataview/discussions/1509#discussioncomment-3985539
// 0.7.3 2022-10-26 - Changed defaults, and added optimization notes and changed behavior taggedTasksFromAnywhere to include current page in an optimization compromise.
// Currently, tasksFromIncludedPages only works from frontmatter, and is really slow. I thought I had gotten it to work with inline syntax, but no longer works.
// 0.7.2 2022-08-01 - Added capacity to look at [includeTasksFrom:: [[link]],[[link2]]] so that links update in page when destination file is renamed. Previously, was static string in the frontmatter.
// defaults
let debug = false
let thePage = dv.current()
let tasksFromThisPage = true
let taggedTasksFromAnywhere = true
let tasksFromTaggedPages = true
let tasksFromIncludedPages = true
// override any defaults from parameters passed
if (typeof input !== "undefined") {
if (typeof input.thePage !== "undefined") {
thePage = dv.page(input.thePage)
dv.span("*From* " + thePage.file.link + "*:* \n")
}
if (typeof input.debug !== "undefined") { debug = input.debug }
if (typeof input.tasksFromThisPage !== "undefined") { tasksFromThisPage = input.tasksFromThisPage }
if (typeof input.taggedTasksFromAnywhere !== "undefined") { taggedTasksFromAnywhere = input.taggedTasksFromAnywhere }
if (typeof input.tasksFromTaggedPages !== "undefined") { tasksFromTaggedPages = input.tasksFromTaggedPages }
if (typeof input.tasksFromIncludedPages !== "undefined") { tasksFromIncludedPages = input.tasksFromIncludedPages }
}
if (debug) { dv.span(">[!DEBUG]\n") }
let myAliases = ""
let myTag = ""
try{
myAliases = thePage.aliases
if (myAliases.length > 0) {
myTag = myAliases[0] // assume first alias is a tag the defines this person or project
if (myTag[0] != "#") {
myTag = ""
}
} else {
myAliases = ""
}
} catch(e) {
myAliases = ""
myTag = ""
}
if (debug) { dv.span("> myAliases:" + myAliases + " myTag:" + myTag + "\n") }
let taskList = dv.array([])
// Tasks from this page
// optimization: fast
if (tasksFromThisPage) {
try{
taskList = taskList.concat(
thePage.file.tasks.where(t => !t.completed &&
dv.date(t.defer) <= dv.date('today')))}
finally{}
}
// tasks from other pages listed in includeTasksFrom
// 2022-10-31 https://github.com/blacksmithgu/obsidian-dataview/discussions/1509 optimization
if (tasksFromIncludedPages && thePage.includeTasksFrom) {
for (let page of dv.array(thePage.includeTasksFrom)) {
taskList = taskList.concat(dv.page(String(page).replace(/[\[\]]/g,"").replace(/\|(.+)/g,""))
.file.tasks.where(t => !t.completed && dv.date(t.defer) <= dv.date('today')));
}
}
// tasks marked with this tag or alias from other pages
// optimization: tolerable
if (taggedTasksFromAnywhere && myAliases != "") {
taskList = taskList.concat(
dv.pages()
//.where(p => p.file.name != thePage.file.name) // speed optimization compromise: comment out to speed things up (we thus don't exclude current page)
.file.tasks.where(t => !t.completed &&
thePage.aliases.some(alias => t.text.includes(alias)) &&
dv.date(t.defer) <= dv.date('today')))}
// tasks from any page which contains this tag, except if tagged #multiproject or #ignoretasks
// optimization: fast
if (tasksFromTaggedPages && myTag != "") {
taskList = taskList.concat(
dv.pages(myTag + " and (-#multiproject and -#ignoretasks)")
.sort(p => p.file.mtime, "desc")
.file.tasks
.where(t => !t.completed &&
dv.date(t.defer) <= dv.date('today')))}
// print them out, make sure no dups, and sort by appearance in note
if (taskList.length > 0) {
dv.taskList(taskList.distinct(t => t.text).sort(t => t.line)) }
else {
dv.span("*No tasks*")
} |
Beta Was this translation helpful? Give feedback.
I think the main issue is you are not making use of the dataview index. For example, in this section:
You are filtering over EVERY page to find the pages that are in your list. You should not do this - instead, iterate over the pages in the list directly: