Fork me on GitHub

First steps with datomic: WhenI enter or click anywhere in datomic console it just reloads the entire page. Any clues?

Ben Kamphaus19:04:24

@rauh: it does that with various browsers? with/without plugins disabled, etc.?


hey all, anyone have tips / methodologies / links to resources about debugging queries? I’m talking both about debugging queries that throw errors, and debugging queries that return data in an unexpected way


the only way i’ve found so far is just to play with where clauses


is there any way to see how datomic is processing a query?

Ben Kamphaus21:04:37

@ethangracer: is there a specific issue you’re trying to address? There’s no equivalent of e.g. a SQL query plan available in Datomic.


no specific issue at the moment, i’ve just had a very difficult time deciphering error messages and understanding how complex queries work (many :where clauses, :with and aggregates, using clojure functions in queries)


I end up just adding and removing random stuff to see what happens


which is fine from a learning perspective, but when I’m trying to achieve a certain result in production it takes a whole lot longer than I think it would with a debugger


so if tinkering is the best available option, that’s fine, just curious if there are others


or to see if anyone has thoughts on what is a more / less effective way of tinkering

Ben Kamphaus21:04:28

I personally haven’t run into issues adding/removing clauses in a controlled manner to get a query to work the way I’d like it to, or to build understanding while doing so. But I tend to build up queries incrementally and check intermediate results either with a small db or a set of tuples I use in place of a db along the way. And I tend to keep queries smaller and compose multiple queries, or e.g. a query versus pull many to split selection and projection.

Ben Kamphaus21:04:38

That’s just my personal take, though. I do understand the implied feature request for tools for explaining or tuning queries, and it’s one others have made and that we’re considering.


yeah some kind of tool for tuning queries would be great. I like the idea of creating a set of tuples to use in place of a db to troubleshoot queries, didn’t realize that was an option


so far I’ve just been using the repl hooked up to our full database, which makes it tricky to understand the behavior… lotsa data


how do you build your own tuples to test against?


How do you transact a new entity to a :db.cardinality/many? This will throw "Expected number or lookup ref for entity id, got {:new "entity"}":

(d/db-with db [[:db/add id :children {:new "entity"}]])
where the schema for :children is
{:db/cardinality :db.cardinality/many
 :db/valueType   :db.type/ref}

Ben Kamphaus21:04:19

@kenny: for the list form :db/add you need to generate one add transaction per set of things in the relation. If you were using a map form and [:new entity] was a stand in for a lookup ref, it needs to be nested in another collection, e.g. {:db/id ent-id :children [[:lookup “1”]]} (or a list of ids there). You can nest a new map without using an entity id only in the case that :children is a component, and still only in the map form.


@bkamphaus: Ah I see. Thanks!

Ben Kamphaus21:04:49

@ethangracer: by tuple examples I mean:

(def tuples [['sally :age 21] 
             ['fred :age 42] 
             ['ethel :age 42]
             ['fred :likes 'pizza] 
             ['sally :likes 'opera] 
             ['ethel :likes 'sushi]])

(d/q '[:find ?e :where [?e :age 42]] tuples)
; #{[ethel] [fred]}

Ben Kamphaus21:04:22

but I think with just a little bit of added complexity (especially considering pull specifications, etc.) I’d move pretty quickly to a small dataset in edn that I’d transact into a mem db. Or use the mbrainz subset if you can construct analogous queries with it.

Ben Kamphaus21:04:38

If you’re trying to get a feel for perf/clause ordering, then you definitely want something with a datomic db’s indexes.


@bkamphaus: thanks, that’s super helpful! for simpler queries I’d definitely prefer to use tuples, but I see the value in pulling down the mbrainz data and trying to build analogous queries too.