Fork me on GitHub
#datomic
<
2020-07-16
>
dregre03:07:35

Relative newcomer to Datomic and I’ve been banging my head against a wall… wonder if anyone has any hints. If the entity “person” has a cardinality-many attribute “friends,” I want to fetch a person where all of that person’s friends have a certain predicate. Plain and simple unification seems to return a person when any of its friends have the predicate.  So I need to reach for something else, but I don’t know what that is.

Jacob O'Bryant04:07:06

You can use not/not-join to check that a person doesn't have any friends that don't satisfy the predicate.

dregre05:07:20

That’s logical! Is it idiomatic?

dregre15:07:29

Let me take it one step further. If my “friends” entities all have a cardinality-many attribute “pets,” how could I grab a person who only has friends that have at least one dog? I don’t necessarily want to exclude people who have friends who have cats, so long as each friend also has at least one dog.

dregre15:07:16

Using not/not-join starts to get hairy in this situation, I would think.

favila15:07:55

If you are on on-prem, I recommend just using predicates

favila15:07:14

if you are on cloud, you can try to fit it into subqueries using q

dregre15:07:58

This is incredibly helpful, thank you!

Jacob O'Bryant19:07:54

I believe this should work also (haven't tested it fyi):

; "Doesn't have a friend who doesn't have a dog"
(not-join [?person]
  [?person :person/friends ?friend]
  (not-join [?friend]
    [?friend :person/pets ?pet]
    [?pet :pet/type :dog]))

Jacob O'Bryant20:07:28

Doesn't seem too hairy IMO

dregre04:07:38

You’re right, not bad at all! I’ll pinch this, thanks muchly!

bamarco14:07:08

Well I figured out the "no protocol" error message. It just wanted me to add "https::/" to the url. I hadn't thought about protocols with the web since I last used ftp. Anyways I figured out which aws api I should be using, so I switched to aws-api from clj-http. So my questions now are not really datomic related (not really a problem using ions anymore, but aws-api). I'll head over to #aws I guess, but on my way out does anyone know why the following does not actually send a response to wscat? I have tries all kinds of things for :Data which is supposed to be a blob including (a json string, a json smile, a .getBytes of json string, a plain test string, and the object shown below)

(aws/invoke (aws/client {:api :apigatewaymanagementapi})
      {:op :PostToConnection
       :request {:Data {"action" "pong"}, :ConnectionId id}})

dregre15:07:29

Let me take it one step further. If my “friends” entities all have a cardinality-many attribute “pets,” how could I grab a person who only has friends that have at least one dog? I don’t necessarily want to exclude people who have friends who have cats, so long as each friend also has at least one dog.

daniel.spaniel17:07:20

does datomic allow for doing queries with limit and offset and maybe sorting? ( trying to do pagination )

favila17:07:59

No: datomic query results are sets or bags and so inherently unordered, so limit and offset doesn’t make sense. You are expected to either find a natural paging boundary and use that as input to the query to limit results (e.g. results a day at a time), or sort and page yourself afterwards.

favila17:07:31

That said, the client api has limit and offset parameters, but I wouldn’t rely on them for user-facing paging for the reasons stated

daniel.spaniel18:07:20

got it, oh well .. i guess i just suck it up ( thanks @U09R86PA4

kenny18:07:01

Is there any guarantee that the order of a carnality many attribute remain the same given no new transactions? e.g., something like this would be true.

(->> (range 1000)
     (map (fn [_] (d/pull db [::card-many] eid)))
     (partition-all 2 1)
     (every? #(= %1 %2)))

ghadi18:07:50

carnality many is such a great misspelling for 2020

kenny19:07:43

Wow, didn't even notice!

ghadi19:07:23

I don't think there is a guarantee of order

ghadi19:07:34

unless you're iterating via d/datoms, which are sorted

kenny19:07:35

Hmm, okay. It makes testing certain things a bit more of a pain. Since pull returns vecs I have to convert everything to sets to test equality.

ghadi19:07:16

try xform ?

kenny19:07:33

Converting tests to dev-local unearthed this.

kenny19:07:35

Good idea!

ghadi19:07:42

never mind, doesn't do set

kenny19:07:43

Hmm. Seems like any fully qualified fn will work.

kenny19:07:36

Oh but I'd need to allow it...

kenny19:07:24

Seems like dev-local should support passing in a custom ion-config map.

kenny19:07:01

Am I missing something here?

(slurp (io/resource "datomic/ion-config.edn"))
=> "{:xform [clojure.core/set]}"

(d/pull db '[{[::card-many :xform clojure.core/set] [*]}] eid)
Execution error (ExceptionInfo) at datomic.ion.resolver/anomaly! (resolver.clj:41).
'clojure.core/set' is not allowed by datomic/ion-config.edn

ghadi19:07:29

dev-local isn't an ion

kenny19:07:03

Not sure what you mean. I thought it supports all Datomic features, one of which is :xform. You config :xform via datomic/ion-config.edn, no?

ghadi19:07:28

dunno -- will defer to @marshall

kenny19:07:05

More complete example...

marshall19:07:36

Can i see your client config map

kenny19:07:21

{:server-type :dev-local
 :system      "kenny-test10"}

marshall19:07:51

Ill have to investigate. Looks like a bug

kenny19:07:40

Ok. Should I open a support ticket?

ghadi19:07:41

btw the original question was "does pulling cardinality many attrs guarantee a particular order?"

marshall19:07:23

@U083D6HK9 sure if you could drop that example in a ticket we can track it there

kenny19:07:16

Will do. Thanks.

kenny19:07:07

Wait, my question was more specific @U050ECB92. Is there any guarantee that the order of a carnality many attribute remain the same given no new transactions?

kenny19:07:35

Okay, interesting. Thanks.

kenny19:07:43

The problem this is solving is that I'd like to use certain Datomic features while running particular tests. An example would be allowing a custom :xform used only during tests.