Fork me on GitHub
#datomic
<
2020-03-23
>
vnctaing02:03:39

Hi, I’ve encountered some issue while I was playing around with datomic, I’ve described my problem on stackoverflow https://stackoverflow.com/questions/60807032/fixing-a-datomic-anomalie

potetm02:03:54

@vnctaing you want all of your key-value pairs in the same map

potetm02:03:20

you have them in 3 maps

potetm02:03:25

e.g.

[{:db/ident :trip/name
  :db/valueType :db.type/string
  :db/cardinality :db.cardinality/one}]

vnctaing02:03:47

Ah right :man-facepalming::skin-tone-2: ! good catch !

Braden Shepherdson16:03:08

a general datomic question: does (datoms ...) return only the existing, unretracted values? or does it return the full history?

favila16:03:03

what datoms returns depends on the database

favila16:03:04

databases all have a basis-t, and can also have any/none of: • as-of • since • history • filter

favila16:03:24

when all of those a nil, you get only assertions valid at basis-t

favila16:03:44

as-of removes any datom not valid at that time

favila16:03:52

since removes any datom after that time

favila16:03:15

history adds in retractions and datoms no longer valid in the as-of to since range

favila16:03:25

(or the entire history if both are unset)

favila16:03:11

filter is an arbitrary predicate that runs after all of the above and can suppress datoms from showing up.

Vishal Gautam16:03:53

If you want full history then you have to pass historical database i.e

(def hist-db (d/history (d/db conn))
;; 
(d/datoms hist-db ...)

Vishal Gautam16:03:18

If you pass the the current value of database, then it will returns all the datoms that are valid at the current time.

robert-stuttaford17:03:42

1. composite unique tuple on two other attrs. one attr is the partnership, the other is a unique identifier for that partnership. [partner partner-id] 2. haven't re-transacted those attrs to cause tuple attrs to appear yet 3. want to retract a bunch of redundant values on one of the target values, to avoid having to re-assert for the tuple. 4. transaction at 3 fails because now it's trying to set the same value [partner nil] for the tuple, which fails the uniqueness check. Can I retract tuple attrs directly? I know I can't retract them now because they don't exist yet, so it seems that I have to first re-assert these values so that tuple datoms are made, and then retract both the identifier and the tuple datoms to clear away the old values. Happy to rewrite any of this if it doesn't make sense 🙂

robert-stuttaford17:03:28

My other option is to do a cleanup before asserting the tuple schema, which is still something I can do -- just looking to learn how to deal with this when that is no longer an option 🙂

marshall17:03:59

@robert-stuttaford I think the cleanup beforehand is your best option right now

marshall17:03:45

We are aware of the complications with automatic composite tuples; don’t have a specific workaround once the unique composite is declared

robert-stuttaford17:03:18

for interest's sake, let's say that door was closed. am i hosed, or is there a way, even if longwinded?

marshall17:03:34

you’d have to rename and ‘move’ the attribute

robert-stuttaford17:03:17

ok. is there a way to directly assert updates to tuple attrs? or is it only ever via altering their targets?

marshall17:03:58

no, Datomic does the assertions, you trigger it by ‘touching’ the entity

robert-stuttaford17:03:02

thanks for answering so quickly! it was rad to hang out in Berlin, which feels like it was months and months ago now, haha

marshall17:03:07

yes, it was awesome

marshall17:03:09

actually, you could “turn off” uniqueness

marshall17:03:21

then fix the problems

marshall17:03:27

then re-enable uniqueness

robert-stuttaford18:03:00

that makes sense, thanks!

Jon Walch19:03:36

What I want from this query is "Give me the :db/id of the datom that has the largest :foo/end-time"? Is this the correct way to do it? I call ffirst on the output and get what I'm looking for, I'm just not sure of max's behavior with :db/id.

(d/q {:query '[:find (max ?target) (max ?end-time)
               :where [?target :foo/bar? false]
               [?target :foo/end-time ?end-time]]
      :args  [db]})

favila19:03:40

You can’t use aggregation for this. You want to fetch the full result, find the highest end-time, and select the target

favila19:03:07

:find ?target ?end-time

favila19:03:07

then

(max-key (fn [[_target ^Date end-time]] (.getTime end-time))
         results-of-query)

Jon Walch19:03:37

So if I wanted to bound the total amount of records that this query could return, I'd need to do that some other way?

ghadi19:03:51

if the db you're passing is not a history db but a regular db, ordinary queries return the latest assertion for something

Jon Walch19:03:16

It is a regular db

ghadi19:03:11

so only history dbs contain all of the past datoms, regular db is "now" (at a particular 't')

ghadi19:03:44

it would be helpful to understand your goals before talking through mechanisms

Jon Walch19:03:43

I have n (and growing) foo s in this example. Right now the query would return all of the records where ?target :foo/bar? false] which is "most" of them

Jon Walch19:03:14

I'd like to avoid returning nearly all foo s from the db in this query

ghadi20:03:10

[?target :foo/end-time ?end-time]
[(> ?end-time threshold)]
and pass in e.g. yesterday as the threshold?

Jon Walch20:03:46

Cool, was wondering if there was a better way, but this will do fine. Thanks!

marshall20:03:52

you could use a subquery

marshall20:03:04

depending on how ‘unique’ your max value is

marshall20:03:54

find the max (or min) value in the inner query, use it find the db/id (or whatever else) in the outer query

Jon Walch21:03:26

Oh nice! I'll give this a shot too.