This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-03-17
Channels
Circling back to https://clojurians.slack.com/archives/C03RZMDSH/p1710072771580899 discussion about custom aggregates... Here's the best implementation I could conjure up for a query that pulls the entities having the N earliest expiring st.oauth.token/expires-at
timestamps:
(d/q {:query '{:find [(pull ?t selector) ?expiry]
:in [$ selector]
:where [[(q '{:find [(min 5 ?expiry)]
:where [[_ :st.oauth.token/expires-at ?expiry]]} $) [[?mexpiry]]]
[(untuple ?mexpiry) [?expiry ...]]
[?t :st.oauth.token/expires-at ?expiry]]}
:args [db selector]})
It seems quite verbose. In particular, the need to untuple
the (min 5 ?expiry)
seems like it shouldn't be required. Then I remembered an offhand comment by @favila about possibly using identity
instead of vec
to aggregate cardinality many attributes... the built-in aggregates seem to return tuples, but would it be possible to have a custom aggregate that returns a collection thus allowing a binding form like [[[?mexpiry ...]]]
? Maybe even something as simple as list
? It's worth noting that using untuple
or even just identity
works to perform that missing binding. I'll give it a try this week.You need two levels of destructure because the query returns relations, not because of the aggregate. min
is returning the same level of nesting it received
I don't think the dot (`.`) syntax works with cloud... it's not documented and throws when I try it. That means that the return from the subquery has one more level of nesting than you might otherwise hope. And I've not been able to get at the innermost collection of five ?expiry
with just destructuring.