Fork me on GitHub
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):


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


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


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

☝️ 2

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

πŸ™‚ 1

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


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.

πŸ™‚ 1

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


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 πŸ™‚


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

πŸ™ 1
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?


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?

πŸ‘ 1

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

πŸ‘ 1
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?


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


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


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