Fork me on GitHub

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"}}


@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.


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


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?


@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.


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


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


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


huh, interesting


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


that makes sense


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


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.


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


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


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


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)


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


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.


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


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


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.


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


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


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.


@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).


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