Fork me on GitHub
#datomic
<
2016-04-22
>
firstclassfunc15:04:25

When loading data into datomic does one need to populate the entities associated with a reference before adding that reference to a new entity. for example. Do I have to populate :room/name before I reference it by another entity? {:my/name "myname", :my/room {:room/name "roomname"}}

Ben Kamphaus15:04:19

@firstclassfunc: you can use tempids to transact both sides of the ref at the same time. You can nest map forms in the tx if the ref is a component.

firstclassfunc15:04:15

@bkamphaus: ok great tks.. I am using Tupelo so that generates the negative IDs for me..

ethangracer18:04:36

hey all, i’m playing around with aggregates and built this query:

'{:find  [(count? ?b) (count ?a)]
      :in    [$ ?id1 ?id2]
      :where [[?b :attr/three ?id2]
              [?b :attr/two :attr.two/enum]
              [?b :attr/one ?id1]

              [?a :attr/two :attr.two/enum]
              [?a :attr/one ?id1]]}
essentially I want to get two counts, the first is a count of all entities with the specified id and enum, and the second is a count of a proper subset of the first set of entities however, right now these counts seem to be multiplied together. I.e. if (count? a) is 5 and (count ?b) is 10, then [(count? a) (count? b)] returns [[50] [50]]. anyone have some insight?

Ben Kamphaus18:04:04

@ethangracer: you're counting the result of the Cartesian product of ?a and ?b twice essentially. The short version is you'll need to split this into two queries.

ethangracer18:04:01

I was hoping that wouldn’t be the answer. Why are they being combined? I don’t understand

Ben Kamphaus18:04:14

One query will aggregate over one set of tuples/relations with grouping implied by find.

Ben Kamphaus18:04:09

All a to each b, then count. All b to each a then count.

ethangracer18:04:32

huh, interesting

ethangracer18:04:54

so the find specification binds the two counts together similar to a non-aggregate query

ethangracer18:04:00

that makes sense

sdegutis20:04:05

Is it possible for a :db.cardinality/many to be ordered?

Ben Kamphaus20:04:11

not naively at rest. At present, defining ordering of values in Datomic implies building a linked list in your schema (node/value, node/next) or refs of (coll/first, coll/second), or having a second attr for the representation that’s a concatenated string (same strategy used for composite keys in some cases), etc.

Ben Kamphaus20:04:29

and yes, we’re aware of and considering the features that resorting to such workarounds suggests simple_smile

sdegutis20:04:33

@bkamphaus: I'm surprised you didn't mention something like :sortable/position, as I imagine that would be a common way to do this.

Ben Kamphaus20:04:23

yep, a position attr that points to an enum is also an option.

Ben Kamphaus20:04:37

or has a numeric value, this all of course assumes you’re writing ordering by logic outside of query/pull as you can’t indicate the equivalent of e.g. SQL “order by” (but that work is done in the peer anyways w/Datomic so it’s not implying a different perf cost per se)

sdegutis20:04:18

@bkamphaus: hmm, I don't understand those last two suggestions, the enum that might or might not have a numeric value, used for ordering

Ben Kamphaus20:04:27

you can just use e.g. an int for position if you provide a position attribute: 1,2,3, etc. I was overthinking it in mentioning an enum there.

sdegutis20:04:04

I figure the easiest is to have any sortable entity just have :sortable/position which is a :db.type/long

sdegutis20:04:14

But maybe I'm thinking of this too Java-ish.

Ben Kamphaus20:04:21

I think as I was imagining cases before (with the first suggestion) that might have to point to things that aren’t reified as entities, but maybe you don’t like the implicit sort order. I.e. a bunch of strings but you don’t want them sorted in lexicographical order.

sdegutis20:04:34

Then you'd do (->> entities (sort-by :sortable/position))

sdegutis20:04:49

@bkamphaus: ah yeah, I see now what you mean.

Ben Kamphaus20:04:36

it does imply having to offset a bunch of values on update to insert in first/mid position though, or some other logical ordering for determining spacing and insert logic on noncontiguous integers, etc. Other solutions have the same problem though.

sdegutis20:04:40

@bkamphaus: unfortunately, we do have an "ordered list of strings" on a given attribute, which we had to split out into their own entities referenced by :product/things, which each have :thing/value (string) and thing/sort-position (int).

sdegutis20:04:35

rather than :product/things being a :db.cardinality/many of :db.type/string which I'd have preferred.