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"}}}]]
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
you can also implement recursion with rules: https://docs.datomic.com/cloud/query/query-data-reference.html#rules
it might be easier to write a rule to get the id of the nested post, and then do a pull
on that id
instead of pulling the whole thing
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
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 🙂
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.
oh yes, i've been down that road before