So I've been playing around with using datalevin to query arbitrary data sources.
(def db
[[0 :name "Bob"]
[0 :species "Parakeet"]
[0 :age 3]
[0 :owners 0 :age 2]
[0 :owners 0 :name "vigo"]
[0 :owners 0 :foods 0 :type "avocado"]
[0 :owners 1 :age 2]
[0 :owners 1 :name "Bob"]
[0 :owners 1 :foods 0 :type "apple"]
[0 :owners 1 :foods 1 :type "avocado"]
[1 :name "George"]
[1 :species "Goldfish"]
[1 :age 1]
[1 :owners 0 :age 2]
[1 :owners 0 :name "Bob"]])
(d/q
'[:find [?name ...]
:where
[?pet :owners _ :foods _ :type "avocado"]
[?pet :name ?name]]
db)
;; ["Bob"]
Is this behaviour intentional? Cause it's really cool/useful.Yes, these are by design, inherited from Datascript
So my next question is there any reason why this doesn't work with pull? As far as I can tell it's because pull checks for a db (same in Datascript).
I'm going to explore changing that check to see if it would just work with pull
Pull expects a triple representation, while queries work with relations, I.e. a collection of tuples. Triple is a special case of tuples
Pull is really about scanning triple indices. What you are seeing with datalog working on data collections is about hash join on relations
Bindings work not just with vectors, you can destruct map and nested data structures as well. See https://github.com/juji-io/datalevin/blob/a1bbfaa167755056b51dc39deb6405df7490f052/test/datalevin/test/query.clj#L248 for examples
test-nested-bindings have single level nested map, is it ergonomic to query deeply nested map?
Is it ergonomic? Depending on your personal taste? I guess. I donβt know.
Yeah, after I asked I realised even if pull did work. I probably wouldn't want it, as I'm mostly using this to transform external data into something that I can query in Datalog to extract the bits I care about and then convert to triples my database schema understands. This is all super useful!
Because if I can transform arbitrary edn data into a list of paths they can then be queried.
using datalog
Yup