This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-01-17
Channels
- # announcements (1)
- # babashka (26)
- # beginners (28)
- # biff (8)
- # calva (45)
- # cider (62)
- # clara (3)
- # clj-kondo (34)
- # cljfx (1)
- # clojure (72)
- # clojure-belgium (1)
- # clojure-canada (13)
- # clojure-conj (2)
- # clojure-dev (3)
- # clojure-europe (19)
- # clojure-nl (1)
- # clojure-norway (1)
- # clojure-uk (8)
- # clojurescript (10)
- # clr (36)
- # core-logic (13)
- # cursive (2)
- # datalevin (2)
- # datomic (23)
- # fulcro (13)
- # graphql (23)
- # instaparse (1)
- # introduce-yourself (4)
- # jobs (1)
- # jobs-discuss (13)
- # lsp (30)
- # luminus (7)
- # malli (2)
- # off-topic (57)
- # polylith (13)
- # portal (5)
- # reagent (32)
- # reitit (6)
- # remote-jobs (1)
- # shadow-cljs (25)
- # xtdb (12)
Hi guys, I was testing Datomic on prem with postgres backend, and I have a few million datoms inserted, although I would like to count them. I have come up with the following query: [:find (count ?e) :where [?e :tweet/id]] Is there a reason for this query to take so long that it either runs out of memory, or never returns a result?
The reason is that d/q is eager and must hold the entire result in memory before aggregation. It is not useful for large results like this. Use d/datoms instead
I was using the console, to do that query, do you know how I would go about using d/datoms in datomic console?
ok, thanks for your help
also if you would like the total count of datoms in the history database you can use https://docs.datomic.com/on-prem/clojure/index.html#datomic.api/db-stats
thanks for that 🙂
It also didn’t help that my id attribute wasn’t set as unique…
@U09R86PA4 question, I have used datoms like so
(d/datoms (d/db (d/connect client {:db-name "twitter"})) {:index :aevt :components [:tweet/id]})
But how can I know how many elements are there from that structure? If I try to iterate and increment a counter, it always returns 1000, which I think might be a default chunk size
(count (seq (d/datoms (d/db (d/connect client {:db-name "twitter"})) {:index :aevt :components [:tweet/id] :limit -1})))
ok, that was what I was missing, thanks!
Hiya, I'm looking to use create a heterogeneous tuple and am confused about how to properly read tuples from entities afterwards for example, I have
{:db/ident :my/tuple
:db/valueType :db.type/tuple
:db/tupleTypes [:db.type/long :db.type/ref]
:db/cardinality :db.cardinality/one
and if I transact
(datomic.api/transact datomic-connection [{:my/id 123 :my/tuple [12 [:my/user "foofoo"]]}])
I get a set, not an ordered sequence, for :my/tuple
(datomic.api/entity (datomic.api/db datomic-connection) [:my/id 123])
; =>
{:my/id 123 :my/tuple #{17592186045528 12}}
How do I then get the first or second tuple values from the entity?
Also curious why it is a set in the first place.
I know you can do this with a custom datomic query + the untuple
query function thing, but I'm not sure if that plays well with a query returning a collection that also includes the entities. Plus I'm curious about the possibility to do this at the entity level
thanks!I found a work around by not going through the entity api: for instance I wanted to do
;; users with name "foofoo" aged 12-13
(->> (datomic.api/q
'[:find ?my-entity
:in $
:where
[?my-entity :my/tuple ?tup]
[?user :my/user "foofoo"]
(or [(tuple 12 ?user) ?tup]
[(tuple 13 ?user) ?tup])]
(datomic.api/db datomic-connection))
(map (partial datomic.api/entity (datomic.api/db datomic-connection)))
(map (fn [entity] {:age (get-in entity [:my/tuple 0])
:my/id (:my/id entity)})))
but the fact that :my/tuple results in a set means (get-in entity [:my/tuple 0])
is non-deterministic in regards to which element of the tuple it evaluates to
after re-reading the different options available to :find
, https://docs.datomic.com/on-prem/query/query.html#find-specifications, I realized that I could do:
(->> (datomic.api/q
'[:find ?my-id ?age
:in $
:where
[(untuple ?tup) [?age _]]
[?my-entity :my/id ?my-id]
[?my-entity :my/tuple ?tup]
[?user :my/user "foofoo"]
(or [(tuple 12 ?user) ?tup]
[(tuple 13 ?user) ?tup])]
(datomic.api/db datomic-connection))
(map (fn [[id age]] {:age age
:my/id id})))
hmm, I tried for a minimal reproduction and actually am not able to get it to return a set instead of a vector. So I guess it is some issue on my side with intermediate wrapper logic
(ns tuple-fun
(:require [datomic.api :as d]))
(def schema
[{:db/ident :oblique/text
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one}
{:db/ident :oblique/strategy
:db/valueType :db.type/tuple
:db/tupleTypes [:db.type/long :db.type/ref]
:db/cardinality :db.cardinality/one}])
(defn setup-connection! []
(let [uri "datomic:"
_ (d/create-database uri)
conn (d/connect uri)
]
@(d/transact conn schema)
conn))
(def conn (setup-connection!))
@(d/transact conn [{:db/id "os1" :oblique/text "Only a part, not the whole"}
{:oblique/strategy [1 "os1"]}])
(def oblique-entity
(d/entity (d/db conn)
(d/q '[:find ?oblique-strategy .
:where [?oblique-strategy :oblique/strategy _]]
(d/db conn))))
(:oblique/strategy oblique-entity)
;; results in a vector as expected
https://tonsky.me/blog/datascript-internals/ is a great write-up. I was wondering if anyone was aware of other resources (articles, papers, clearly written code) which may provide additional insight into what's going on under the covers when unifying queries and esp. accessing/representing history in any Datalog implementation.
It's a video, and coming at things from the opposite end vs that datascript writeup (more emphasis on how to fit it into their distributed architecture), but I always liked this talk about #xtdb (formerly crux): https://www.youtube.com/watch?v=YjAVsvYGbuU