Fork me on GitHub
João Fernandes09:09:26

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 Altelino14:09:12

You could to use an or-join

Giovani Altelino14:09:59

[: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 Altelino14:09:37

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

David Pham09:09:28

find all owners and pull the results?

João Fernandes09:09:11

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


@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")


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

João Fernandes10:09:57

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


@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: The syntax has been re-used in other libraries (e.g. it is the basis for and used by libraries such as Fulcro and Pathom, among others)

João Fernandes09:09:20

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


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


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


thanks, that could make sense


I believe I have a few run away string values


does retraction affect the storage of large strings in the segments or do those stay for good?


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


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


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

👍 3

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


it will still be kept in object cache


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


thanks. In this case the data size was by accident