Fork me on GitHub
#datomic
<
2024-03-17
>
cch104:03:45

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.

favila12:03:30

I think you just want {find [(min 5 ?expiry) .] :where …`}` ?

favila13:03:26

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

favila13:03:59

This query could be an index-pull btw if expires-at is indexed

cch117:03:55

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.

cch117:03:24

Definitely expires-at is indexed (this is Cloud) but the outer query shown above is representational and I'm still not sure of the final form and if it will work nicely with index-pull -but I'm going to explore that too.

favila17:03:56

Ah yeah, cloud doesn’t have find-destructuring

cch117:03:11

Couple that with an inability to destructure down three levels (not sure why) and I end up stuck with the extra "external" destructuring. At least it works...