Fork me on GitHub
#datomic
<
2019-04-12
>
joelsanchez19:04:50

how would you query the ids of all the entities that reference a given entity, including transitively? i.e. I have entity A, which has a :db.type/ref attribute whose value points to B, and B also has a ref attr whose value points to C, and I want to go from C to A this is trivial to do if you know how many steps there are, but implementing it for the general case seems difficult to me without resorting to complicated graph traversal algos

joelsanchez19:04:08

so is there a simpler way or do I need to do it the hard way? (i.e. graph traversal custom fn)

joelsanchez19:04:08

just to make my case clearer, this is to detect when I need to reindex an entity in elasticsearch. if a subentity (a component, usually, but not always) is changed I'll need to reindex the parent entity, but the link isn't always direct

benoit19:04:09

It seems like Datomic rules would work great for this. The question is whether you can have a list of attributes that you can lookup in these rules or whether you should consider any attribute of type ref.

benoit19:04:22

Absolutely not tested but I would try something in this spirit:

[(parent ?p ?e)
 [?p ?attr ?e]
 [?attr :db/type :db.type/ref]]
[(ancestor ?a ?e)
 (parent ?a ?e)]
[(ancestor ?a ?e)
 (parent ?p ?e)
 (ancestor ?a ?p)]

Daniel Hines02:04:21

I spent a good chunk of time on this channel bothering you guys before arriving at an identical rule. Do the Datomic docs show this example, and I just missed it? Vaguely googling for phrases like "transitive query Datomic" leads to the mbrainz example which only goes to some depth specified upfront or this forum post which never arrives at this rule https://forum.datomic.com/t/how-to-do-graph-traversal-with-rules/132 If the Datomic docs don't have this example, it may be expedient to add it, or perhaps an authoritative blog post. This one rule is so impressively powerful, I think it deserves whatever hype it can get. "Traverse your graphs instantly with this one weird trick..."

😀 4
joelsanchez07:04:05

completely agree, and I had the same experience with the googling

joelsanchez07:04:35

thankfully, rules saved my day

benoit19:04:58

You might not even need the clause on the type of the attribute.

joelsanchez20:04:45

I'm absolutely blown away, I never used rules before, but this works and I'm very grateful for your help

benoit20:04:59

No problem. Usually if you have a recursive problem, rules help.

ghadi21:04:16

@joelsanchez as noted it will be much faster if you specify the exact attribute you need

ghadi21:04:48

[?p ?attr ?e] <- not binding the attribute causes a much larger scan

benoit21:04:03

?e should be bound to the child entity so the scan should not be much bigger, unless there are a lot of attributes on each entity they don't care about.

benoit21:04:05

You should of course call parent and ancestor with a bound ?e to find ?p. Not try to retrieve the whole database 🙂

joelsanchez21:04:08

nah, they are small entities, and they don't have that many ref attributes. since the child entities are usually components, they aren't referenced by more than one entity, and the depth is always lower than 3

Daniel Hines02:04:21

I spent a good chunk of time on this channel bothering you guys before arriving at an identical rule. Do the Datomic docs show this example, and I just missed it? Vaguely googling for phrases like "transitive query Datomic" leads to the mbrainz example which only goes to some depth specified upfront or this forum post which never arrives at this rule https://forum.datomic.com/t/how-to-do-graph-traversal-with-rules/132 If the Datomic docs don't have this example, it may be expedient to add it, or perhaps an authoritative blog post. This one rule is so impressively powerful, I think it deserves whatever hype it can get. "Traverse your graphs instantly with this one weird trick..."

😀 4