Fork me on GitHub

I'm having difficulty getting my use-case to work with datomic and could use some guidance. I'm implementing datomic as an audit log for our system. I've been successful in implementing most of the desired functionality but I am stuck at trying to query to find all transactions that touched an entity of a certain type. The following query should convey the gist of what I want:

[:find ?txn ?timestamp ?user ?description
 :in $
 [?txn :db/txInstant ?timestamp]
 [?txn :data/user ?user]
 [?txn :data/description ?description]
 [?e _ _ ?txn]
 [?e :model/type :workOrder]


One thing I would certainly try putting the most selective clause first ( That would speed up the query. You can also combine the last two clauses into [?e :model/type :workOrder ?txn]


Actually, you don’t need the ?e variable. So [_ :model/type :workOrder ?txn] would do.


Would this only give me transactions that asserted that the model/type of some entity was :workOrder? I'm looking for all records of that type that had any property changed by a transaction.


I think you want the history database?


if by “touched” you included “retracted”


if $ is a history database, and :data/user and :data/description are always present and cardinality-one, your query should work but may be slow because of clause ordering


This query is a bit more defensive because it tolerates nils:

(d/q '[:find (pull $db ?tx [:db/id :db/txInstant :data/user :data/description])
       :in $ $db
       [?e :model/type :workOrder]
       [?e _ _ ?tx]
     (d/history db) db)


but it should be roughly the same as yours


This particular query doesn't work because it has "insufficient bindings" but I've gone through many iterations of this overall idea and I either get the bindings error or I get memory/timeout issues because the query is too taxing. the Log API looks like it would help but it doesn't look like I can use that very effectively with the client API, is this really the case?


Your OOMs are because you are selecting all TX datoms in memory. Put the most selective clause first


I'm using Datmoic Cloud and I just pushed an ion and it's made a lambda that I can see and test in AWS Lambda console. However, when I go to API Gateway to connect an API to that lambda, I go to this page and my lambda doesn't come up in the search bar. This sounds like an AWS issue, however when I create a new Lambda from scratch without using Datomic, API Gateway can see that one just fine. Is there something I need to configure in the Datomic Cloud Lambda that will make it show up in API Gateway?

Joe Lane18:09:28 Go look up the full name of the lambda in the lambda console and copy paste it into that field. That drop down sometimes doesn't auto populate the lambda but it's there nonetheless. I believe the lambda name is prefixed with the system name, like my-system-demo.


Pfffffffffffft wow I didn't try that you're right the auto complete was broken

Joe Lane19:09:39

It's been broken for over a year, I think it was actually documented broken in the datomic ion tutorial. Glad you got it figured out!

Msr Tim21:09:55

Hi i am trying to insert some test seed data

                 :employee/id 1
                 :employee/first-name "Level1"
                 :employee/last-name "Approver"
                 :employee/email ""

                 :employee/id 2
                 :employee/first-name "Level2"
                 :employee/last-name "Approver"
                 :employee/email ""
                 :employee/approver [:employee/id 1]

Msr Tim21:09:15

it rightly complains about

Msr Tim21:09:20

Unable to resolve entity: [:employee/id 1] in datom [-9223301668109597978
   :employee/approver [:employee/id 1]]

Msr Tim21:09:49

is there a way to insert that in on tx . Instead of two.


you need to use an explicit :db/id for any entities you want to reference from “elsewher” in the same transaction


one sec i’ll get you the docs

Msr Tim21:09:42

thank you. I've been looking everywhere but didn't quite figure out the approprite google keywords.


^ in datomic cloud docs. if you are using on-prem it’s the same and i can find you that link if you prefer


basically you want:

                :db/id "1"
                 :employee/id 1
                 :employee/first-name "Level1"
                 :employee/last-name "Approver"
                 :employee/email ""

                 :employee/id 2
                 :employee/first-name "Level2"
                 :employee/last-name "Approver"
                 :employee/email ""
                 :employee/approver "1"

Msr Tim21:09:09

i am using cloud


where the db/id is an arbitrary string - as long as it’s the same string in both places

Msr Tim21:09:29

oh perfect so I have to use entity id

Msr Tim21:09:33

thank you!

Msr Tim21:09:23

that worked. Thank you so much for quick response.


there are some ways to define a composed unique attr? For example, I want the combination of :my/name and :my/surname to compose an unique constrain


Are name surname “foo” “bar baz” and “foo bar” “baz” different?


If not, you must string concat and compute the attr yourself. Otherwise you can use tuples


they are different


I think tuples would be a better option too. thanks @U09R86PA4