Fork me on GitHub
#datomic
<
2020-07-03
>
Adrian Smith08:07:32

Is there a learning website with a collection of SQL queries and their Datomic equivalents?

dvingo15:07:33

not sure about a comparison (of sql and datalog), but this tutorial is quite good http://www.learndatalogtoday.org/

Ertugrul Cetin16:07:51

hey guys, I'm considering to use Datomic Cloud, it seems that datomic.client.api does not have all functions that on-prem datomic.api does. Like datomic.api/entity, would it be a problem? Is there any alternative if I need to use this function?

kschltz19:07:18

Hi there @U0UL1KDLN we're using datomic cloud, and most of the times we use the pull api when we already have the entity id

Ertugrul Cetin19:07:04

@UNAPH1QMN thank you for the info

Linus Ericsson09:07:41

Datomic Cloud and datomic on prem works quite differently. The Entity API expects the application to be able to cache data locally (like a Datomic Peer does), otherwise it has to do a lot of roundtrips to get an entity API working, which would defeat the purpose with en entity view since it would be very slow and ALWAYS has the n+1 error - that you have to do more roundtrips to the server to get more data. The entity API is meant to be a very quick way to navigate around the database. You can get a similar (but not complete!) way of navigating parts of the databas using the pull expressions as Kaue describes above.

✔️ 3
kschltz19:07:08

I was wondering, if I were to shard my datomic cloud or to split my data in any way, would it make any sense to just create different dbs? something like

(d/create-database client {:db-name "smurfs-1"})
(d/create-database client {:db-name "smurfs-2"})

kschltz19:07:36

then query one or the other

kschltz19:07:30

I'd rather have to query 500M datoms over one db or the other

kschltz19:07:41

than to query 1B in a single db

kschltz19:07:00

does that make any sense from an architectural standpoint?

Jon Walch22:07:28

I'm using Datomic Cloud My data model is similar to

{:user/foo "foo"
 :user/other-one "hi"
 :user/bar [{:bar/bazed? true} {:bar/bazed? false}]}
In one query, I want to pull :user/foo :user/other-one and everything in :user/bar where :bar/bazed? is false. The issue that I'm running into is that I want :user/foo and :user/other-one no matter what, but if there are no :bar/bazed? that are false, the whole query returns an empty vector because of implicit joins. I'm currently doing what I need with two queries, but this path is extremely hot so I'd like to reduce it to one. I also don't want to pull all of :user/bar because it could be extremely large, where as the number of items in :user/bar with user/bazed? equal to false will be quite small.

favila15:07:38

I think you are asking for a list of maps of users where each user only contains the bar entities where bar/bazed? is false?

favila15:07:53

(does it specifically have to be false, or is unasserted the same?)

favila15:07:06

You can do it with a nested query and joining yourself

favila15:07:34

or issue two queries in parallel and join yourself

favila15:07:19

I recommend adding the false bars to the user map under a different name so the keyword has a globally-unique meaning.

favila15:07:19

I recommend adding the false bars to the user map under a different name so the keyword has a globally-unique meaning.

Jon Walch19:07:32

@U09R86PA4 I'm looking for a specific user. I have a unique attribute to look them up with. I want the user no matter what, but I also want everything in user/bar where bar/bazed? is false. If no bar/bazed? is false, I want user/bar to be returned as an empty vector

Jon Walch20:07:56

I think I may go the async query route instead of trying to do it all in one blocking query

Linus Ericsson09:07:34

I think you should consider changing the boolean to an additional reference between the user and the data map object instead. This way the structure of the database helps you retrieve the correct data. It makes the change of the boolean data a bit more complicated, but it sounds like it would be worth it in this case. So for instance: user -> :mail/inbox #{all mail in the inbox} user -> :mail/unread-in-inbox #{the unread mails from the inbox} obviously one has to update both the inbox and unread-in-inbox when removing an unread email but it can still be a simpler solution for you. you can also just have two different attributes :mail/inbox and :mail/unread and query for where both links exists. The :mail/unread is could then be sort of isomorphic with :bar/bazed? in your example above.

Jon Walch17:07:53

@UQY3M3F6D Thanks for weighing in! That's a good suggestion!

👍 3