… 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
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:
As this post is talking about “usefulness” and not “beauty”, we’ll all ignore how ugly this is But, on the other hand, in the Reading mode, it looks a little better:
… and - there is always CSS
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