Fork me on GitHub
#datomic
<
2016-07-08
>
casperc07:07:34

So I have a cardinality many value (ref actually, but never mind that), and I want to perform a query taking a list as input giving me of all entities that have at least those values in its cardinality many attribute. My problem is that when binding the input values to a list, Datomic does an ‘or’ on the values meaning that if I provide [:a :b] as input it will also give me entities having only 😛. So can I have the query treat the input with ‘and’ semantics somehow?

casperc08:07:33

Just to make it a bit more specific, I have a template entity which can contain some fields. I want to query for templates having a number of fields (though they can have more). The following query threats the inputs as ‘or’ where I would like ‘and’:

(d/q '[:find [?e ...]
            :in $ [?ids ...]
            :where 
            [?e :template/field ?fields]
            [?fields :template.field/id ?ids]
            ]
      db [101 102])

danielstockton10:07:30

if i transact 'bob likes cheese' and that fact already exists, is any transaction created that reaffirms this fact?

danielstockton10:07:22

for example, if at tx1 bob tells me that he likes cheese, and then at tx2 alice tells me that bob likes cheese

danielstockton10:07:44

i want some auditing capabilities that can not only tell me that bob told me he likes cheese at tx1 but also that alice reaffirmed that bob likes cheese at tx2

pesterhazy10:07:41

How do I find all the datoms transacted in a tx?

(d/q '[:find ?e ?a ?v ?tx ?added :in $ ?tx :where [?e ?a ?v ?tx ?added]] (rdb) 13194153065948)

datomic.impl.Exceptions$IllegalArgumentExceptionInfo: :db.error/insufficient-binding Insufficient binding of db clause: [?e ?a ?v ?tx ?added] would cause full scan

pesterhazy10:07:47

that obviously doesn't seem to work 🙂

pesterhazy11:07:35

I guess (first (-> conn d/log (d/tx-range 13194153065948 nil))) works

casperc11:07:13

@pesterhazy: Yep, that’s how.

pesterhazy11:07:57

repl-based helpers for inspecting an entity's history ^^ @casperc

marshall13:07:30

@danielstockton: If the datom being transacted is identical in the second transaction, it will result in an empty transaction generated. You could use transaction metadata to indicate that the transaction was issued by a different user (i.e. ‘alice said’ in transaction #2), however the transaction itself won’t be associated with the ‘bob likes cheese’ fact. If you need to track that information as well, you’ll want to model that directly (possibly also as transaction metadata). The reified transactions talk here: http://www.datomic.com/videos.html provides some more detail on using transaction metadata for provenance tracking.

marshall13:07:54

@casperc: This is essentially the same question as was asked by @bhagany yesterday. Binding using the collection form (…) will run the query on each element of the collection and return the union of those results. To ask “and” questions your list of ids need to be provided in the same tuple, using the tuple binding form (http://docs.datomic.com/query.html#tuple-binding) Each id will have its own individual datalog clause and the default behavior of multiple clauses in a query is “And”.

danielstockton14:07:46

thanks @marshall, pretty much what i had thought

lvh15:07:35

Is there any particular recommended docs for taking existing nested data and turning it into datoms? I’m currently doing it semi-manually — it’s fine, but it feels like there should be an easier way

lvh15:07:50

in particular, I’m trying to put swagger API specs in datomic to query them

stuartsierra16:07:25

@lvh You can transact nested data as maps if it matches your schema. You have to create entity IDs for any map that isn't a component nested under another map.

lvh16:07:25

Oh, cool! That'll definitely save me a bunch of time, I'll just go in and add appropriate namespaced keywords

stuartsierra16:07:26

@lvh reference docs at http://docs.datomic.com/transactions.html#nested-maps-in-transactions describe what forms of nesting are allowed

lvh16:07:28

Looks like I will still have to mangle the data somewhat since e.g. paths/status codes aren’t very useful keys: https://github.com/OAI/OpenAPI-Specification/blob/master/examples/v2.0/json/petstore-minimal.json#L26-L46

stuartsierra16:07:29

Yes. For cases like that, my usual pattern is: - every function returns a vector of valid transaction data - (vec (concat ...)) things together to build the full transaction

stuartsierra16:07:32

- create tempids in the "parent" and pass them to a "child constructor"

lvh16:07:39

Also, some parameters/definitions are inline, some of them are defined at the top level (so e.g. you don’t have to repeat how your limit query parameter works each time)

lvh16:07:37

Ah; I saw something earlier like {:widget/manufacturer [:manufacturer/e-mail “"]} ; are idents on insertion a Datascript-only feature, or would those work too?

lvh16:07:51

I’m wading through a whole bunch of links and tutorials and they don’t always specify

lvh16:07:31

I’m glad that I’m going in the right direction because I did in fact have:

(->> (concat (operations swagger))
                         (map (fn [m] (assoc m :swagger/api (:info swagger))))
                         vec)
in my code already 😄

Alex Miller (Clojure team)20:07:31

@stuartsierra: how about (into [] cat […]) instead of (vec (concat …))

stuartsierra20:07:14

@alexmiller: I have that defined as concatv 🙂

Alex Miller (Clojure team)20:07:38

:) I just enjoy putting things into my cat

lvh21:07:14

Is there a recommended way for describing, uh, … overlays? I have a high-level default, which specific components lower in the hierarchy can override it seems the two options are: 1. propagate the default to the leaves 2. walk the graph until you find the default In particular, is there a standard way of writing e.g. fns that produce clauses that go in where, or do you need to concat in that case?

lvh21:07:21

I don’t know if my description makes any sense

lvh21:07:53

in my specific case, apis have operations, apis produce and consume mime types (e.g. application/json); individual operations can claim to produce e.g. application/xml in addition to json

lvh22:07:34

also, are attributes generally spelled in the singular if they have cardinality many?