datomic

Ask questions on the official Q&A site at https://ask.datomic.com!
João Fernandes 2020-09-20T09:32:26.024900Z

Hi, I've been trying do find a way to do a left join for last three days and I finally decided to ask for help 😅 How can I get all owners and their pets even if they don't currently have a pet?

[:find ?owner-name ?pet-name
 :where [?owner :owner/name ?owner-name]
        [?owner :owner/pets ?pet]
        [?pet :pet/name ?pet-name]]

Giovani Altelino 2020-09-21T14:22:12.034200Z

You could to use an or-join

Giovani Altelino 2020-09-21T14:29:59.039Z

[:find ?owner-name ?pet-name
 :with ?data-point
 :where [?owner :owner/name ?owner-name]
        [?owner :owner/pets ?pet]
        [?pet :pet/name ?pet-name]
 (or-join [?owner-name ?pet-name ?data-point]
   (and [(identity? ?owner-name) ?data-point)
   (and [(identity? ?pet-name) ?data-point)]

Giovani Altelino 2020-09-21T14:30:37.039200Z

I guess something like this should work, although I don't have datomic installed right now to confirm

2020-09-20T09:38:28.026100Z

find all owners and pull the results?

João Fernandes 2020-09-20T09:39:11.026200Z

Is there a way to do it in "one trip" or am I making a conceptual mistake here?

schmee 2020-09-20T09:44:25.026600Z

@joaovitorfernandes2 I think you can use get-else for this: https://docs.datomic.com/cloud/query/query-data-reference.html#get-else

João Fernandes 2020-09-20T09:58:20.026700Z

The union happens on [?owner :owner/pets ?pet] and get-else doesn't support cardinality-many attributes 😣

pithyless 2020-09-20T09:58:25.026900Z

@joaovitorfernandes2 as a rule of thumb, I suggest using where clauses for filtering and pull for pulling data (that may or may not exist)

[:find (pull ?owner [:owner/name {:owner/pets [:pet/name]}])
 :where [?owner :owner/name _]]
So, you could use get-else in the where clause to optionally find pets, but that only makes sense if you then want to filter with additional rules (e.g. if the owner has a pet, one of the pets names need to be "Rex")

pithyless 2020-09-20T09:59:37.027100Z

When you want conditional matching, you need to add a datalog rule (or one of the sugar syntaxes - e.g. or)

João Fernandes 2020-09-20T10:11:57.027400Z

Thank you so much! Yesterday I tried to use pull but I didn't knew I could nest maps in there! Again, thank you!

pithyless 2020-09-20T13:38:20.027900Z

@joaovitorfernandes2 Technically, that is not a nested map, but the notation for doing a join. I recommend checking out the pull docs for the kinds of built-in features you can take advantage of: https://docs.datomic.com/on-prem/pull.html The syntax has been re-used in other libraries (e.g. it is the basis for https://github.com/edn-query-language/eql and used by libraries such as Fulcro and Pathom, among others)

2020-09-20T20:37:39.029200Z

I'm seeing some memcached/item-too-large logs when integrating memcached (same with valcache), could I be missing some required config?

cmdrdats 2020-09-21T11:01:15.033300Z

You could excise the values? That should get rid of them

2020-09-21T14:19:32.033700Z

I'm going to try excising, though I remember reading that it's not made to reduce the size of stored data necessarily

favila 2020-09-21T14:26:45.038Z

It’s not, but if you have a too-large value that’s the only way to ensure it’s not written to segments again

👍 1
favila 2020-09-21T14:27:31.038400Z

It’s actually OK to have item-too-large occasionally. All this means is that the item will be fetched from storage instead of memcache/valcache

favila 2020-09-21T14:27:38.038600Z

it will still be kept in object cache

favila 2020-09-21T14:27:56.038800Z

that said, there’s a reason they say to keep strings under 4k

2020-09-21T15:17:16.042400Z

thanks. In this case the data size was by accident

favila 2020-09-20T21:57:14.030700Z

You have segments which are too large to cache. This is not configurable. Probably you have some large string or binary values