Today I embark upon a quest to attempt to replace XTDB in my RDF project with Asami. I am excited and a bit intimidated. Once I learned that I have to use sets for multi-cardinality attributes it clicked. 😅
What made you switch?
I use it to search RDF vocabulary which is schemaless, but not document oriented like XTDB, asami is triple oriented so it works a lot more seamlessly with RDF.
I don’t know if it was just introduced later, or what, I have a feeling that early Datomic didn’t use vectors for entities with multicardinality properties. But maybe I’m wrong and it was always like that. I forget. It turns out that I didn’t have a lot of use for multicardinality properties in Datomic. Most of the time when I needed multiple values, the order mattered.
So maybe I just didn’t remember properly 🙂
Sets make sense for idiomatic “RDF/EDN” serialization and will be accepted by Datomic in tx-data too. There are always going to be some trade offs in how to represent the RDF with Clojure data and I am already using EDN tagged literals which require binding the appropriate data readers for things like language tagged strings, so I think you made the right design choice thinking about RDF
I basically rewrote Mulgara for Clojure, with various design updates.
i.e. the underlying architecture was based on presumptions of RDF
Hello! Related to RDF lists... I'm loading triples directly into Asami using https://github.com/quoll/asami/wiki/3.-Loading-Data#triples, but I noticed if you add entities with arrays, convenient https://github.com/quoll/asami/wiki/5.-Entity-Structure#containership triples are added to make querying easier. Has anyone been able to get those :a/contains predicates added when loading triples directly from RDF? I'm parsing the RDF with https://github.com/quoll/raphael (which I wouldn't expect to add them) 🙂
Oh I got this property path querying working too, might be all I need
(a/q '[:find [?s ...]
:where
[:n0 :fhir/name ?name]
[?name :rdf/rest* ?list]
[?list :rdf/first ?s]]
(a/db asami-conn))Hopefully that IS all you need!!!
The :a/contains link is specifically an entity convenience
it doesn’t happen when triples come in otherwise
(Also, I’m very sorry that you’re running Raphael separately. I’m working on it, I promise!)
Yes I think this is the way to go, except now I have to go deeper into nested lists ... In FHIR, someone can have multiple full names, and a full name can have multiple given names, etc. Here's the example I'm querying into https://hl7.org/fhir/R5/patient-example.ttl.html
I think I almost have it for two layers using optional but it seems like I should try to go arbitrarily deep... This kind of thing is tricky for me to grasp in SPARQL
Oh I didn't search well enough! https://clojurians.slack.com/archives/C018H97E02D/p1675503703424879 I'll try using CURIEs that look like :rdf:rest
Maybe, :rdf/rest?
Oh I thought I could do a recursive property path query if I changed
:rdf/rest*/:rdf/first
to
:rdf:rest*/:rdf:first
But I see that you suggested another way to achieve this for arbitrary depth... I have something working now but it's not a very general or pretty solution, because I'm collecting values that are either RDF lists or not... but it works well enough for what I need