This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-03-17
Channels
- # bangalore-clj (1)
- # beginners (23)
- # boot (141)
- # cider (68)
- # cljs-dev (29)
- # cljsjs (1)
- # cljsrn (11)
- # clojure (150)
- # clojure-austin (3)
- # clojure-berlin (1)
- # clojure-france (2)
- # clojure-greece (13)
- # clojure-italy (5)
- # clojure-russia (49)
- # clojure-spec (15)
- # clojure-uk (45)
- # clojurescript (152)
- # code-art (1)
- # core-async (75)
- # cursive (12)
- # datascript (2)
- # datomic (90)
- # dirac (5)
- # emacs (10)
- # garden (1)
- # hoplon (52)
- # instaparse (4)
- # juxt (2)
- # lein-figwheel (2)
- # lumo (47)
- # mount (94)
- # off-topic (20)
- # om (21)
- # onyx (14)
- # parinfer (19)
- # pedestal (3)
- # protorepl (13)
- # re-frame (5)
- # reagent (20)
- # slack-help (10)
- # spacemacs (8)
- # specter (57)
- # unrepl (11)
- # untangled (3)
- # vim (1)
- # yada (1)
and I have found this bit of code that https://gist.github.com/jtmarmon/0a644fbca15a1742964c seems to solve it (Almost)
@thomas What are you trying to accomplish? If you want maps to start with, d/pull
may be an easier API to use, since it does return normal Clojure maps.
As a side note, (-> e class .toString (clojure.string/split #" ") second (= "datomic.query.EntityMap"))
is a complicated way to write instance?
.
then @dominicm pointed out that EntityMaps are not Clojure maps... there is a (into {} entity)
in the code, but from what I understand that won't work on nested maps
So what is the best way of turning EntityMaps into Clojure maps? With (into {} entity)
I can't do a postwalk and with the above mentioned function I am getting different results it seems and those result in failure higher up the stack.
(clojure.walk/postwalk (fn [x] (if (instance? datomic.query.EntityMap x) (into {} x) x)) input)
Does this work @thomas?Thank you @stuartsierra and @dominicm !!!
Guys for query [:find (max 5 ?e) (pull ?r [*]) :with ?player :where [?player :player/region ?r] [?player :player/attr.stats.wins ?e]]
I understand that in order to get all of the attributes for the entity layer:p I'll have to write your function aggregation?
@favila want to choose 5 entities which have a maximum value of an attribute :player/attr.stats.wins
query is works just me instead of one attribute (:player/attr.stats.wins) are interested in the whole essence of :player
so you want (d/pull db ?player [* {:player/region [*]}])
for the 5 players with the most wins?
@favila i'm sorry)) (d/q '[:find (max 5 ?e) (pull ?r [:region/key]) :with ?player :where [?player :player/attr.stats.wins ?e] [?player :player/region ?r] (d/db conn)
[:find (max 5 ?n-wins) ?r (pull [*] ?player)
:where [?player :player/attr.stats.wins ?n-wins]
[?player :player/region ?r]
since you are aggregating two different ways I'm not sure you can do it in a single query
@favila I don't quite understand the use case, it is not difficult to show the minimum sample?
@favila Thank you, but I still don't understand how two queries you can get at least :db/id for :player with the highest number of victories
you may get more than 5 results per region if multiple players have the same number of wins
(let [max-wins-per-region (d/q '[:find ?r (max 5 ?n-wins)
;; No point to :with ?player
:where
[?player :player/attr.stats.wins ?n-wins]
[?player :player/region ?r]] db)
max-wins-per-region-relations (into []
(mapcat (fn [[region-id n-wins]]
(map #(do [region-id %]) n-wins)))
max-wins-per-region)]
(d/q '[:find ?r-key (pull [*] ?player)
:in $ [[?r ?n-wins]]
:where
[?player :player/region ?r]
[?r :region/key ?r-key]
[?player :player/attr.stats.wins ?n-wins]]
db
max-wins-per-region-relations))
You can always do the aggregation yourself, too, if you can hold the intermediate result set
in that case the player cutoff will be arbitrary. If 6 players in a region all have 10 wins, which player is not listed?
if that doesn't fit in memory, you can use (d/datoms :aevt :player/region), and reduce over it, grabbing player data and aggregating at the same time
Remember, queries run on the peers. You can do everything with code instead of queries if you want. The client is going to download every intermediate value either way.
@favila when in the base of the 305 000 players request to get top players totally leaves 2.2 minutes
@a.espolov if you have an index on :player/attr.stats.wins, it may be faster to put that clause first
@favila you can add an index to the entity attribute if already exist in the database instances are selected?
e.g., if number-of-wins clusters around a few common values, it may touch fewer datoms to find the region then the number of wins. But if number of wins tends to vary widely the index is more selective, so getting by number of wins, then the region will touch fewer datoms
@favila la index i can disable attribute have no problems with existing records in the database?
@a.espolov I don't understand?
:db/index = true => :db/index = false such an operation for data in database is executed without problems?
These are the permitted schema alterations: http://docs.datomic.com/schema.html#altering-schema-attributes
But removing an index in your scenario will not help query performance. The reasons to remove an index are: less storage for the index, less indexing time.