Fork me on GitHub
#datomic
<
2024-06-01
>
Tobias Sjögren09:06:49

How would you represent this fact in a Datom ?: John Doe is the sound engineer at Concert X.

cjohansen09:06:33

{:db/id 1234
 :concert/id "x"
 :concert/sound-engineer {:db/id 5678
                          :person/id "johndoe"}}
So, specific datom would be
[1234 :concert/sound-engineer 5678 900000 true]
And the attribute:
{:db/ident :concert/sound-engineer
 :db/valueType :db.type/ref
 :db/cardinality :db.cardinality/one}

👍 1
Tobias Sjögren09:06:53

So "sound engineer" should/could be the attribute ?

cjohansen09:06:34

Makes sense to me. You could model it the other way around as well, but that feels less natural to me.

Tobias Sjögren09:06:53

What would be "the other way around" ?

cjohansen09:06:50

Something like :sound-engineer/responsible-engineer or some such. On the person

cjohansen09:06:19

:person/sound-engineering-concerts

cjohansen09:06:27

heh, like I said - more awkward

cjohansen10:06:43

With my first suggestion, you could find all the concerts John Doe has been the sound engineer at with:

(def john-doe (d/entity (d/db conn) [:person/id "johndoe"]))
(:concert/_sound-engineer john-doe)

Tobias Sjögren10:06:53

So specific roles played by persons should/could be represented as the attribute - some might say that roles could/should be the value where the attribute is :role, but then you would need more than single datom to represent the fact I guess..

Tobias Sjögren10:06:27

(Datomic data modeler newbie..)

cjohansen10:06:43

Yes. This is just one suggestion, a very straight-forward one. If you want more detail then you’d need to represent the role as an entity as well

👍 1
Tobias Sjögren10:06:53

Do you agree to what is being said here @U09R86PA4?

cjohansen10:06:31

There are many ways to model this, my suggestion is simplistic. I don’t know at what depth you want/need to model your concerts 🙂

cjohansen10:06:54

For instance, it is not uncommon for a concert to have more than one sound engineer.

Tobias Sjögren10:06:55

I have plenty of roles associated with the concerts..

cjohansen10:06:00

You could model “sound engineering” as an entity also:

{:concert/sound-engineer
 {:sound-engineer/person {:person/id "johndoe"}
  :sound-engineer/payment 500}}
Or an even more general role:
{:concert/workers
 [{:concert.worker/person {:person/id "johndoe"}
   :concert.worker/role :concert.role/sound-engineer
   :concert.worker/payment 500}]}

cjohansen10:06:06

I generally prefer to keep things explicit and not overly generic. So I’d want at least a :concert/sound-engineer (or :concert/sound-engineers ) attribute, even if it points to an entity with role-like information.

👍 1
cjohansen10:06:42

Keep in mind that you can also be both specific on some things and at the same time generic on others - and you can mix and match attribute namespaces. For instance, you probably don’t want to model a bunch of :X/payment attributes that are essentially the same, so this is fine:

{:concert/sound-engineer
 {:sound-engineer/get-in "..."
  :concert.worker/person {:person/id "johndoe"}
  :concert.worker/payment 500
  }}
Not the best example, but my imagination is failing me at the moment 😅

Tobias Sjögren10:06:26

Sorry, I don't use Datomic so I'm a bit unsure what in your code represents what in a Datom..

cjohansen10:06:53

These are entity maps. You can pass them directly to d/transact and let Datomic break them down into datoms for you. Here’s how it goes:

;; This is the same as
[{:db/id 1234
  :concert/sound-engineer
  {:db/id 5678
   :sound-engineer/get-in "..."
   :concert.worker/person {:db/id 9876
                           :person/id "johndoe"}
   :concert.worker/payment 500
   }}]

;; ...this
[[1234 :concert/sound-engineer 5678]
 [5678 :sound-engineer/get-in "..."]
 [5678 :concert.worker/person 9876]
 [5678 :concert.worker/payment 500]
 [9876 :person/id "johndoe"]]

cjohansen10:06:34

I would advise you to become intimately familiar with how these shapes relate, it’s essential to understanding Datomic and making good use of it.

Tobias Sjögren10:06:05

Thanks. At the moment I'm working on a triple-based model in FileMaker and taking inspiration from Datomic. What I'm envisioning is a master attribute set that would work across multiple domains and for every system built one would take a subset of that attribute set to model the domain at hand..

favila11:06:54

> Do you agree to what is being said here @U09R86PA4? yes

👍 1
🧑‍⚖️ 1
Tobias Sjögren09:06:51

The aspect that I'm struggling with is combing 1) declarative roles like "John Doe is a sound engineer", with 2) contextual roles like "John Doe is the sound engineer at Concert X". It appears that "sound engineer" needs to be represented both as an entity and as an attribute, which is confusing to me...

cjohansen09:06:34

What does it mean to be a sound engineer in "John Doe is a sound engineer"? That he has that skillset? That he has a sound engineering job? Find out what you mean by that and model that. If all you really need to know is that he's a sound engineer at the specific concert, then the above discussion gives plenty answers. You may want to model more sound engineering aspects though.

👍 1
cjohansen09:06:23

If you only model that John sound engineers specific concerts, you can use Datomic to answer the question "Is John a sound engineer?" by looking at whether he's every held a sound engineering position.

cjohansen09:06:52

Not saying that's the only correct way to do it, just throwing it out there as something to consider.

Tobias Sjögren09:06:41

One use of storing the fact "John Doe is a sound engineer" (based on skillset, education or whatever) could be that only persons that have this skillset/education are allowed to use this role at some event like a concert.

cjohansen09:06:04

Sure. Several options for this as well. {:person/skills #{:skill.music/sound-engineering ,,,}} is a loose tag-like approach, {:person/skills #{{:skill/kind :skill.music/sound-engineering, :skill/blabla ",,,"}}} reifies skills as an entity, etc. Depends on how much detail you need in your system.

Tobias Sjögren09:06:40

Would it make sense to model "sound engineer" both as an attribute and an entity to you ? (I need to better understand the construct of ":skill.music/sound-engineering"..)

cjohansen09:06:31

:skill.music/sound-engineering is a namespaced keyword. In this context it acts like a "tag" for skills.

cjohansen09:06:14

"Sound engineering at a concert" and "having a sound engineering skillset" are two distinct pieces of data, so it makes complete sense to model both.

👍 1
Tobias Sjögren09:06:09

Thanks ALOT for your answers!..

Tobias Sjögren09:06:01

(btw, I've been to concerts where it was evident that they certainly are two distinct pieces of data:wink:..)