Fork me on GitHub
#xtdb
<
2020-04-30
>
Akshay C. Gollapalli19:04:40

Is there a way to specify in a query that a document does not have a certain trait. ie: some docs might have a trait :dependencies, and some may not, is there a way to query for the ones that don't?" edit: didn't realize that {:where [[(not [e :my-trait])]]} worked. Obvious thing is obvious when made apparent. edit2: for any other noobs (like me) who see this, use the tests as a way to see queries that work (or don't work): https://github.com/juxt/crux/blob/master/crux-test/test/crux/query_test.clj

refset19:04:51

Hey - glad you found the answer so quickly πŸ™‚ but you're 100% right the tests are by far the best way to sanity check what's possible or not. And Datalog certainly has a learning curve...I spent most of last Saturday thinking about how to efficiently do the equivalent of a FULL OUTER JOIN in a single efficient Datalog without repeating a bunch of (or (not-join ... work. I've reluctantly had to give up thinking about it for now πŸ˜…

Akshay C. Gollapalli20:04:12

Thanks. For some reason, I’ll spend a bunch of time looking for something, decide I should just ask, then after asking, figure out a way to find the answer. I might need to order one of those rubber ducks after all... I might try my hand at some docs for the various Datalog operators with examples if you think it’d be helpful. edit: if only for learning purposes

refset20:04:59

Aha, we would never turn down an offer of writing docs! Another tutorial instalment to cover this area is also warranted.

refset19:04:39

Hey, do we have any Metabase fans around here? I'm a convert!

☝️ 8
Jorin07:05:28

Awesome to see Crux working already πŸŽ‰ We use it for all our BI needs in the company πŸ™‚

πŸ™‚ 4
dvingo20:04:38

never used it, seems cool - are you trying to get crux to work with it?

refset20:04:32

Yep πŸ™‚ the screenshot is showing Metabase talking to Crux via our work-in-progress SQL JDBC driver, powered by Apache Calcite. Metabase was able to figure everything out by itself and I was able to very simply create the join in the UI across the Datalog-backed "tables" that Calcite dynamically exposes - the generated SQL join then gets pushed down into a single Datalog query, so it's a pretty efficient abstraction.

πŸ™‚ 4
dvingo21:04:33

woah, that's really cool! i may have to play around with it πŸ™‚

jarohen21:04:15

neat, Metabase looks like it's come on a fair way since I last used it - which wasn't long ago, and it was good then πŸ™‚

nate22:04:49

huge fan of metabase, very cool that crux is working with it

πŸ™ 4
Akshay C. Gollapalli22:04:27

Is there a facility for subqueries? Or is it the sort of thing that's really unnecessary given the nature of it?

refset23:04:14

Or, not-join and various rules will already execute as subqueries under the hood. There's no explicit concept of subquery though. What situations are you thinking about?

πŸ‘ 4
refset23:04:29

Also there's really no penalty when running multiple queries from Clojure if everything is in-process and you use open-db

πŸ‘ 4
Akshay C. Gollapalli00:05:12

I was running into issues with querying entities with multiple values for a key: {:crux.db/id :entity :dependencies {:dep-1 :dep2}} Let's say you want entities that only depend on :dep-1. This doesn't work: {:find [e] :where [[(== #{:dep-1} d)] [e :dependencies d] [e :dependencies d2] [(!= #{:dep2} d2)]]} And neither did a few others, always either returning entity when they shouldn't (like the below). Or returning nothing (like the above). {:find [e] :where [[(== #{:dep-1} d)] [e :dependencies d] (not-join [e] [e :dependencies d2] [(!= #{:dep-1} d2)])]} Eventually this other one did work: {:find '[e] :where [(depends e) (not (doesn't-depend e))] :rules [[(depends e) [e :dependencies d1] [(== deps d1)]] [(doesn't-depend e) [e :dependencies d2] [(!= deps d2)]]] :args [{'deps #{:dep-1}]} I think it's because the rules in the last one create subsets of the entity, rather than creating subsets of tuples of the entity and a dependency, like the ones that didn't work. Hence the question about sub-queries. I'm guessing that each rule generates a subset on it's own, and then the final query is the intersection of the various tuples?

refset10:05:55

In that first snippet are you missing a # ? Is that value for :dependencies supposed to be a set?

refset10:05:51

...assuming so, I think you should be able to do this: {:find [e] :where [[e :dependencies :dep1] (not [e :dependencies :dep2])}

refset15:05:51

@US65YEL1M (just making sure you don't miss this response!)