Fork me on GitHub
#xtdb
<
2023-05-23
>
jmerrifield19:05:28

In Datalog queries, is there a way to specify that all/some/none of a related set of entities meet a criteria? e.g. given orders with multiple shipments, can I write a query that finds orders where all the associated shipments have a status of :shipped?

sergey.shvets19:05:32

Try something like this:

'{:find [[order-id (count shipped-id) (count any-shippped-id)]
  :where [[order-id :order/id]
          [shipped-id :shipment/order-id order-id]
          [shipped-id :shipment/status :shipped]
          [any-shipped-id :shipment/order-id order-id]]}
Then you can filter resulting tuples where count doesn't match. You can even use cond/if as a forth argument within find.

jmerrifield22:05:36

OK that makes sense! Presumably if I wanted to add a pull query to the orders, it might make sense to run this query first, filter to get matching IDs, then xt/pull-many those IDs? Otherwise I'd be fetching a lot of data which would then be discarded?

sergey.shvets22:05:15

Yeah, getting ids and then pulling data by them will be the best way to go. Since you're querying against the "immutable value" of db there is no need to make overly complicated query to make sure you get all the data in one pass.