This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-09-15
Channels
- # announcements (15)
- # babashka (8)
- # beginners (23)
- # biff (20)
- # calva (6)
- # cider (9)
- # clerk (31)
- # clj-kondo (3)
- # clj-otel (2)
- # clojure (116)
- # clojure-argentina (1)
- # clojure-austin (5)
- # clojure-europe (64)
- # clojure-nl (3)
- # clojure-norway (23)
- # clojure-sweden (40)
- # clojure-uk (1)
- # cursive (16)
- # data-science (2)
- # datahike (8)
- # emacs (3)
- # events (1)
- # hyperfiddle (24)
- # malli (5)
- # off-topic (24)
- # re-frame (9)
- # releases (1)
- # solo-full-stack (25)
- # sql (18)
- # tree-sitter (19)
- # xtdb (10)
I'm trying to read documentation on subqueries because I want to write an aggregate subquery with a default value: https://docs.xtdb.com/language-reference/datalog-queries/#where-subqueries But these subqueries are very basic. I tried "just writing" the query but then I don't know how to deal with a list of tuples properly because then I still don't know how to do the default value for an aggregation. Do you think it's better if I'd do several separate queries instead? I want to calculate one value for each record row.
I already implemented it in the basic query way. The subquery is too much for me.
Hey @U028ART884X you should be able to achieve just about anything within a single Datalog query, but there are definitely some complexity/verbosity hoops (and potentially performance hoops) when attempting to do so. If you can share some sort of ~minimal example of what you're trying to achieve I would be happy to help offer solutions
I was trying to fetch a list of documents and sum its likes in one query. So the outer query is a normal one but the inner query can have no registered likes and I want that case to default to zero. This is my summation query:
{:find (sum vote-value)
:where [[vote :vote/value vote-value]
[vote :vote/target-id target-id]]
:in [target-id]}
Then after this query I do this: (or vote-result 0)
And the outer query just queries the list of these target-id
docs.
So currently I run these small queries separately because it's less complicated and I don't know how to handle missing vote values.I think you can do something like replace the current :where
vector with:
[(or-join [vote-value]
(and [vote :vote/value vote-value]
[vote :vote/target-id target-id])
[(identity 0) vote-value])]
I tried this. And I think there is a problem.
My vote/value
is a number -1, 0 or 1.
If there are more than two votes then or-join
returns a set of results which means that I can't sum them up and produce a vote count.
It's because my intermediate result with or-join becomes this #{-1 0 1}
but not this: [-1 -1 -1 0 1]
Currently my additional query works well.
This also seems to work:
(sum ?vote-value)
...
'(or (and [?vote :vote/target-id ?target]
[?vote :vote/value ?vote-value])
(and [(identity nil) ?vote]
[(identity 0) ?vote-value]))
But if I omit sum
then it doesn't return a set of values and instead returns distinct ?vote-value
list.I refactored my queries to use the or
but I think they're a little less performant now. I'll see what happens.
I think you should be able to force it to not deduplicate by returning the vote entity also (and then just don't use it)