datomic

Ask questions on the official Q&A site at https://ask.datomic.com!
joshkh 2020-10-11T11:03:33.437400Z

i'm curious if anyone here makes use of recursion in their queries? i tend to find myself thinking "ah, recursion can solve this problem!" but then later i find myself implementing some tricky manipulations outside of the query to get back the results i want. for example, if i want to find the top level post of a nested post, then i have to walk the resulting tree to its maximum depth, which of course is pretty quick, but does not feel elegant.

; the "Third Level" post
(d/q '{:find  [(pull ?post [:post/id :post/text {:post/_posts ...}])]
       :in    [$]
       :where [[?post :post/id #uuid"40b8151d-d5f4-45a6-b78c-67655cdf1583"]]}
     db) 
=>
; and the top post being the most nested
[[{:post/id     #uuid"40b8151d-d5f4-45a6-b78c-67655cdf1583",
   :post/text   "Third Level",
   :post/_posts {:post/id     #uuid"9209c1c6-d553-4632-848a-d9929fd7652a",
                 :post/text   "Second Level",
                 :post/_posts {:post/id   #uuid"0b15be5d-84f2-45d1-8b44-b9928d67f388",
                               :post/text "Top Level"}}}]]

steveb8n 2020-10-12T09:46:24.444300Z

I have a tree read at the core of my app. It's was tricky to make it perform well and it's still not super fast. I'm using recursive rules. My summary: it's possible but non-trivial

schmee 2020-10-11T11:42:58.438900Z

you can also implement recursion with rules: https://docs.datomic.com/cloud/query/query-data-reference.html#rules

schmee 2020-10-11T11:43:37.439100Z

it might be easier to write a rule to get the id of the nested post, and then do a pull on that id

schmee 2020-10-11T11:43:44.439300Z

instead of pulling the whole thing

joshkh 2020-10-11T12:11:22.439500Z

hmm. i'm not sure how i would write a recursive rule though, e.g. one that unifies on a top level post in the example above

joshkh 2020-10-11T12:12:13.439700Z

then again i haven't given it much thought. i'll play around and see what i can come up with. thanks for the advice 🙂

teodorlu 2020-10-11T12:13:56.439900Z

If you use recursion without a recursion limit, you open yourself to an infinite loop. Perhaps it makes sense to have a hard-coded recursion limit regardless.

joshkh 2020-10-11T12:14:40.440100Z

oh yes, i've been down that road before