Fork me on GitHub
#datomic
<
2016-05-29
>
dryewo15:05:10

hi all, I’m new to datomic and I have a datalog question. This is my query:

'[:find (pull ?p [:]) (count ?v)
                   :where
                   [?p :]
                   [?v :td.vote/post ?p]]
and it returns no result if there are no votes for a post. I’d like datomic to put count 0 instead of omitting the post from results. Is there a nice way to achieve that?

Ben Kamphaus15:05:25

Not a nice way, no.

Ben Kamphaus16:05:10

At present to get any value for an aggregate you have to have some tuple that matches in the intermediate set. I think @marshall may have an example using or or not with ground and missing or something as a workaround hack for this or a similar problem.

Ben Kamphaus16:05:42

Pull does support default expressions so it may make more sense to get all values with a 0 as a default in the pull and do count or sum outside the query.

marshall16:05:30

Yes, you can sort of get that behavior with or and missing?, but it's not great. @bkamphaus suggestion of pull with default is probably cleaner

dryewo16:05:34

like this?

'[:find (pull ?p [: (default :td.vote/_post [])])
                   :where
                   [?p :]]

dryewo16:05:42

and then map the counting

dryewo16:05:07

The only thing that scares me is, what if I have too many votes so they don’t fit in memory (very unlikely, but I’m curious)? With aggregation functions this problem should be avoided, but not with manual counting.

Ben Kamphaus16:05:40

The intermediate rep has to fit in mem for the query to work in the first place (query runs on peer).

dryewo16:05:22

makes sense

dryewo16:05:30

then it should be ok