Fork me on GitHub
#datomic
<
2016-08-08
>
mrmcc304:08:59

@pesterhazy, @robert-stuttaford, @podviaznikov: https://github.com/mrmcc3/tf_aws_datomic i’m sure there are many things that could be improved but I can at least confirm that this gives you a running transactor (with dynamo) and properly configured peers

pesterhazy07:08:04

wow, awesome 🎁 @mrmcc3

yonatanel12:08:08

Why is the semi sequential squuid better for indexing than a random uuid?

robert-stuttaford12:08:22

indexing sorts datoms

robert-stuttaford12:08:34

sequential uuids sort faster

robert-stuttaford12:08:23

because most of the uniqueness is towards the end of the uuid value, which means that on average, it takes less bits of the uuid to determine a sort decision

robert-stuttaford12:08:41

that's my layperson understanding, anyway 🙂

yonatanel13:08:01

I see. So there's no concept of a hash index that doesn't care about ranges, as in mongo?

danielstockton14:08:45

datomic's indexes are like b-trees, if things are sequential it means the tree needs much less re-balancing

stuarthalloway14:08:57

@yonatanel: semisequential guids are a good idea in general, you never know what kinds of indexes your data might want to live in

stuarthalloway14:08:15

@yonatanel: adapting indexing (http://blog.datomic.com/2014/03/datomic-adaptive-indexing.html) means that Datomic will index efficiently even if store purely random values

stuarthalloway14:08:21

it is a principle of Datomic that you should get good indexes by default, without having to make indexing choices up front (that inevitably serve some jobs well and other jobs poorly)

stuarthalloway14:08:59

this is exactly the opposite of the “Model Around Your Queries” idea encouraged in e.g. Cassandra http://www.datastax.com/dev/blog/basic-rules-of-cassandra-data-modeling

alexati15:08:31

Hi! I have a super-newbie question: After leiningen downloads the datomic peer library dependency correctly, when I (require ‘datomic.api) on my project, I get ClassNotFoundException clojure.lang.Tuple java.net.URLClassLoader.findClass (URLClassLoader.java:381). What’s happening? I’m stuck… thanks in advance!

marshall15:08:14

@alexati: I’m guessing you’re using an incompatible version of Clojure

marshall15:08:34

the latest release of Datomic requires Clojure 1.8

marshall15:08:41

@alexati: Alternatively it may be some other incompatible dep. You can run lein deps :tree to find what may be conflicting

Alex Miller (Clojure team)15:08:51

that has to be the Clojure dep

alexati15:08:54

@marshall Thanks a lot, I completely overlooked that - I was using clojure 1.7

marshall15:08:15

Sure. I may have found that one myself…. once or twice 🙂

alexati15:08:58

error messages are the best part of clojure 🙂

yonatanel16:08:26

@stuarthalloway: Can I just use the squuid function when I need to generate an ID, even without datomic? e.g when I know I will need to store it later

stuarthalloway16:08:59

yes, and the source code is like ~10 lines if you don’t want a dep

yonatanel16:08:24

btw, when there's partitioning involved, isn't it recommended to have the most significant part of the id all over the place, as is recommended with amazon s3 keys? (and of course ranges are not needed)

stuarthalloway17:08:52

@yonatanel: depends on the partitioning scheme, but yes that can be a concern

severed-infinity17:08:24

hey guys just getting into using datomic, right now I am working on just a simple registered user system. testing the add and retract feature but I’ve notice I had to re-evaluate the db after each add/retract to see the effect take place. Am I missing something?

jaret18:08:03

@severed-infinity: I imagine you are querying against the same database value. In Datomic the database is a value and database values are immutable. So whatever item you are adding and retracting has another value (new) that you need to use. Each transaction in Datomic adds a new database value and all of the old values are still present, but if you want the most recent value you will need to retrieve it first.

severed-infinity18:08:04

so I assume then what I’d want is some function (say add function) that gets the db in let binding?

jaret18:08:43

@severed-infinity: sure, that is one way of doing it.

rwtnorton19:08:00

@severed-infinity: There is also :db-after you could use (without having to make another roundtrip): http://docs.datomic.com/clojure/index.html#datomic.api/transact

severed-infinity20:08:45

ah never thought of that, using that approach then would it be best to create the db as an atom?

val_waeselynck21:08:49

@severed-infinity an atom holding the db value wouldn't give you persistence, so it's only useful for speculative work. Semantically a Connection is already a kind of reference holding db values

severed-infinity22:08:21

@val_waeselynck: ah okay, currently I am using the approach I mention earlier of using it in a

let
context but are there any good code examples or best practices code examples in regards to handling the db change over time?

val_waeselynck22:08:54

transacting and obtaining :db-after is the way to go, but you usually don't need to do it more than once

val_waeselynck22:08:41

if you're adding several things, just make a batch transaction that adds them all at once

sdegutis22:08:58

Is there a way to see the tx-data of a given transaction in the database history?

sdegutis22:08:57

Sorry, I meant tx-data. Fixed the typo.

marshall22:08:27

@sdegutis: yes, you can use the log api.

sdegutis22:08:38

Ah right, thanks.

sdegutis22:08:26

Ahh, that's gonna suck. Having to parse through datoms.

marshall22:08:12

You can use it in query. Use the tx-data function to bind e, a, v, and op

sdegutis22:08:30

Thanks again.

severed-infinity22:08:07

(def db (d/db conn))
…some transaction…
(set! db (:db-after transaction))
would this be the suggested approach?

sdegutis22:08:27

@severed-infinity: that's usually not necessary since Datomic stores the most recent transaction's :db-after along with its connection, so all subsequent calls to (d/db conn) will return it.

marshall22:08:39

(d/q '[:find ?e ?a ?v ?tx ?op
       :in ?log ?tx
       :where [(tx-data ?log ?tx)[[?e ?a ?v _ ?op]]]]
     (d/log conn) <your-tx-id>)

sdegutis22:08:52

@severed-infinity: The only time you ever need to access :db-after directly is when you need to make sure you have a consistent view of the database, e.g. to avoid race conditions.

marshall22:08:11

Hrm. Not sure how to code block on mobile. Anyway that query will get all the datoms for a given tx

sdegutis22:08:27

@marshall: It looks formatted like a code block to me (on desktop).

sdegutis22:08:46

Thanks btw.

marshall22:08:41

Sure. And of course you can add clauses as normal to do whatever else you want. Remember to pass a db in addition to the log if you want to do any 'normal' querying additionally

marshall22:08:20

@severed-infinity: you might want to look at Component (https://github.com/stuartsierra/component) for managing your db state throughout an application

marshall22:08:53

In very general terms, functions that only query should take a db as an argument and functions that transact should take a connection

severed-infinity22:08:29

@sdegutis: ah okay, its just that after adding a new user to the db and looking them up using the following query with id in this case representing an id in my system and db being the same as I declared above just simply returns an empty set unless I re-evaluate db before the call.

(d/q '[:find ?e :where [?e :user/id id]] db)
In actuality I use this function specially
(defn lookup-user [id]
  (let [db (d/db conn)
        result    (d/q '[:find ?e
                         :in $ ?id
                         :where [?e :user/id ?id]] db id)]
    result))

severed-infinity22:08:58

but that db bound in the let form still returns an empty upon querying

sdegutis22:08:55

@severed-infinity: Right, like I said, if you want to see the value of your DB after your transaction, either use :db-after or (d/db conn).

sdegutis23:08:18

How would you go about "reversing" a transaction?

marshall23:08:58

Query for the datoms in the txn (as above), reverse the op position of all datoms in the txn (other than the txInstant one) and re-transact

marshall23:08:06

Tim Ewald gave a really nice talk on Reified Transactions last year at conj: http://www.datomic.com/videos.html