Fork me on GitHub
#xtdb
<
2020-05-05
>
ouvasam11:05:32

Hi, may be a stupid question but what is the best way to count with crux ? I had a look at the crux.decorators but not sure what should be done ? thanks

refset12:05:26

Hey - it's a good question! Are you looking to count result tuples in general? Or, more specifically, count entities with certain attributes? Or are you looking for counts to be returned within tuples? I think there may be a few different options.

ouvasam12:05:11

Hi Jeremy, more count entities with certain attributes even if i don't see the difference between the first and the second proposition ?

refset13:05:22

Okay, it's good to know the context. I think crux.decorators could definitely help you, but as you only want to do counts (for now) it would be simplest to just reduce over the results in your own code to create a count.

refset13:05:46

If you share a query I can attempt to write an example

ouvasam13:05:05

Here is what i've done for now

(defn count-translations-by-status
  []
  (let [all (crux/q
             (crux/db node)
             {:find '[?id ?s]
              :where '[[?e :crux.db/id ?id]
                       [?e :app/type :app/Translation]
                       [?e :translation/status ?s]]})
        gp (group-by last all)
        gp (zipmap (keys gp)  (map #(count (second %)) gp))]
    gp))

ouvasam13:05:42

this produce something like

{:DRAFT 2
 :WAITING-FOR-APPROVAL 0
 :PUBLISHED 10}

refset14:05:18

So that looks like a reasonable solution to me. There are probably some small efficiency tweaks that can be made but I nothing springs to mind. If you have a very large result set then you could use open-q to do some of that processing more lazily. I wouldn't recommend trying to adopt crux.decorators.aggregation.alpha right now, as it's not under active maintenance, although it would certainly be a more pleasant solution if you have aggregation logic to maintain in many different places. We are hoping to review and bring it up-to-date again soon though.

jarohen14:05:36

given you've not got many documents here this'll be fine - if memory was a concern you could use clojure.core/frequencies - (->> all (map last) (frequencies))

👌 4
jarohen14:05:29

(->> [[:id1 :DRAFT]
      [:id2 :PUBLISHED]
      [:id3 :DRAFT]
      [:id4 :WAITING-FOR-APPROVAL]]
     (map last)
     (frequencies))

;; => {:DRAFT 2, :PUBLISHED 1, :WAITING-FOR-APPROVAL 1}

ouvasam14:05:01

Excellent ! Many thanks to another of you !

🙏 4
dvingo16:05:48

got pull to work with crux by making some minor edits to the datascript pull implementation: https://gist.github.com/dvingo/ca637c159ff58c54d320054c98368e0e everything works (defaults, limits, recursion - limited and unlimited, prop renaming, prop wildcard) except reverse attribute lookup

👍 4
👏 4
💯 4
jarohen16:05:44

hey @U051V5LLP, looking good - thanks! 🙂

jarohen16:05:48

was hacking on something similar myself on Friday afternoon, using the EQL library - seems like it really brings the implementation size/complexity down

dvingo17:05:04

for sure! 🙂 i was playing around with using eql as well, luckily i somehow had the thought to see how datascript did it, ha.

refset18:05:47

This is a nice find - where would the world be without datascript! Reverse lookups for Crux will certainly be a bit different in the sense that everything gets returned as if it was cardinality-many. Will you need to solve it for your data model anyway, or is your gist enough for you?

dvingo19:05:20

I don't need the reverse lookups at this point, will probably play with adding it at some point though

👍 4
teodorlu09:05:23

I would love to see native pull support in Crux!