Clojurians
#datomic
<
2016-03-18
>

This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

harold00:03:31

@wei - both :: definitely planning on open sourcing our stuff as well, when the time is right.

wei00:03:46

@harold have you found that datomic is sufficient for the volume of data you generate?

curtosis15:03:18

would there be any issues with creating enum entities dynamically (i.e. to reflect user additions)? I want to provide a hierarchical tagging system and think they'd be more useful than raw strings.

curtosis15:03:09

The one issue I can think of is that I'd have to manage them indirectly to e.g. handle "deletions"

bkamphaus15:03:11

@curtosis: so for the first pass I’ll throw out the basic rule of thumb — if it’s something you’d type into your application code, that’s the best fit for an ident.

bkamphaus15:03:27

for most other cases having a unique identifier and using lookup refs is the best approach.

curtosis15:03:53

hmm.. why is that?

bkamphaus15:03:45

the point of ident is for its keyword name to be interchangeable in many contexts with its entity id. If you have to do partial matching on the stringified ident, or generate things on the fly, you’ll give up performance advantages that come from having the ident in memory.

bkamphaus15:03:28

also ill suited for existence tests in query (error vs. no matches)

stuartsierra16:03:01

Also, if I recall correctly, all Idents are kept in memory, all of the time, on all Peers. If your users create millions of tags, that could lead to inefficient use of memory.

stuartsierra16:03:44

As far as convenience, Lookup Refs are almost as convenient as Idents.

curtosis16:03:52

(sorry, Internet decided to die on me. finally gave up and switched to iOS app.)

curtosis16:03:18

That makes sense. I don't think I expect anywhere near that many tags, but there doesn't seem to be much cost to just avoiding it in the first place. And there's indeed something to be said about not exposing program-internal language to the user.

curtosis16:03:48

as I understand it, I don't even really need to create a uuid attribute - the string name has to be unique anyway for lookup refs to work, right? So there'd be an entity with one attribute, which would be a name instead of a db.ident, right?

bkamphaus16:03:56

right, in this case by “unique identifier” I meant to point towards a string (or potentially keyword) attribute with :db/unique :db.unique/identity rather than suggest a uuid valued field.

bkamphaus16:03:27

for tags or something similar, unique string makes sense. Whether or not it makes sense to model it as an entity is a separate question, it looks like given the hierarchy of tags you expect, the entity with an attribute for a name and other attribute(s) for relations to other tags makes sense.

curtosis17:03:44

good, I'm following. :) And in fact I do have it modeled as an entity, precisely because I also want a :tag/parent ref attribute.

curtosis17:03:11

rereading the page on identity and uniqueness, it's all laid out pretty nicely - the key bit here is that my "enumerated tags" usage is not programmatic, so the semantics should be different (as are the tradeoffs). got it, thanks!

sdegutis17:03:47

When a peer upgrades its Datomic version, must the transactor that it connects to also be on the exact same version? If not, how do you know when to upgrade both the peer and transactor, as opposed to just the peer?

bkamphaus17:03:19

@sdegutis: don’t need to match versions except across compatibility breaking changes (all documented here: http://docs.datomic.com/release-notices.html ) — recommendations for upgrading an entire live system are here: http://docs.datomic.com/deployment.html#upgrading-live-system

sdegutis17:03:29

@bkamphaus: Excellent, thanks very much.

curtosis21:03:10

how would you use get-else where the non-default value is not the value that would be missing? This doesn't do it:

(d/q '[:find ?label ?parent 
       :in $ 
       :where 
       [?t :tag/label ?label]
       [?t :tag/parent ?r]
       [(get-else $ ?r :tag/label "N/A") ?parent]] (d/db conn))

curtosis22:03:39

hmm... maybe get-else isn't the right tool here. I got it to do what I expect using an or-join, but it looks a little ugly:

[:find ?label ?parent 
       :in $ 
       :where 
       [?t :tag/label ?llabel]
       (or-join [?label ?parent ?t] 
                (and [(missing? $ ?t :tag/parent)]
                     [(ground "N/A") ?parent])
                (and [?t :tag/parent ?r]
                     [?r :tag/label ?parent]))]

curtosis22:03:50

I suppose that's not actually terrible, but perhaps there's a simpler way.