[DataviewJS] Getting data from a table

Obsidian is not a database … Obsidian is not a database … OBSIDIAN IS NOT A DATABASE!!!

I keep telling this to myself, but yes - I was aware that this could have happened, so I dive a little into those dangerous waters. And I got a question from a colleague, and I found a similar question from 2023 on this forum. So, here it is. It’s not beautiful, but it’s mine :wink:

At the top is the MD table, and at the bottom are DataviewJS queries, which extract data from a table. The worst problem is that tables are not treated as DB tables, so you need to build arrays.

As per Adding Metadata - Dataview you can add values with keys inline. So, I (ChatGPT did it, and it’s useful as I just copy/paste the table, and it updated with “[ :: ]”) create a table to look like this:

image

As this post is talking about “usefulness” and not “beauty”, we’ll all ignore how ugly this is :smile: But, on the other hand, in the Reading mode, it looks a little better:

image

… and - there is always CSS :wink:

As long as we have the two most important pieces of information, key and value - Key:: Value, we can now start playing with data.

  • This one lists all unique locations from a table:
let uniqueLocations = [...new Set(dv.pages().flatMap(p => p.loc))];
dv.list(uniqueLocations);
  • This one counts how many participants are from Vienna:
let people = dv.pages().flatMap(p => p.loc).filter(loc => loc == "Vienna");
dv.paragraph(`Number of participants from Vienna: ${people.length}`);
  • This one, create a table with participants older than 40:
let names = dv.pages().flatMap(p => p.name).values;
let ages = dv.pages().flatMap(p => p.age).values;
let locations = dv.pages().flatMap(p => p.loc).values;

let people = names.map((name, index) => ({
    name: name,
    age: ages[index],
    loc: locations[index]
})).filter(p => p.age > 40);

dv.table(["Name", "Age", "Location"], people.map(p => [p.name, p.age, p.loc]));
  • This one gets me and the average age of participants from Vienna:
let ages = dv.pages().flatMap(p => p.age).values;
let locations = dv.pages().flatMap(p => p.loc).values;

let viennaAges = ages.filter((age, index) => locations[index] == "Vienna");

if (viennaAges.length > 0) {
    let avgAge = viennaAges.reduce((a, b) => a + b, 0) / viennaAges.length;
    dv.paragraph(`Average age of participants from Vienna: ${avgAge.toFixed(1)}`);
} else {
    dv.paragraph("No participants from Vienna found.");
}
  • And this one gets me: how old is the participant, and where is he coming from:
let names = dv.pages().flatMap(p => p.name).values;
let ages = dv.pages().flatMap(p => p.age).values;
let locations = dv.pages().flatMap(p => p.loc).values;

let index = names.indexOf("James Brown");

if (index !== -1) {
    dv.paragraph(`James Brown is ${ages[index]} years old and is from ${locations[index]}.`);
} else {
    dv.paragraph("James Brown was not found.");
}

Q: Is this useful?
A: No!

Q: Was this fun?
A: YES!

Q: Will you ever use it?
A: Probably never…

Q: Why did you do it?
A: If someone is asking if it is possible to show that it is, but … not worth it.


I hope that somebody finds it helpful… cheers, Marko :nerd_face:

2 Likes

Why not though? If you’re only designing for one, I don’t see why you shouldn’t use something like Notion or Obsidian to manage data and create your own ad hoc apps in the Obsidian environment.

3 Likes