asami

Asami, the graph database https://github.com/threatgrid/asami
2021-06-28T15:01:46.189600Z

I don’t know. For my implementation it’ll be dependent on the underlying database as it’s done in a single SPARQL query with a property path, and the graphs I’m working with are small enough to live in memory anyway. I would expect the query to be memory bound though it’ll depend on the implementation. For my data cycles are a very rare edge case, and one of the main reasons for testing it is to invalidate certain graphs and avoid running algorithms that may not terminate in the presence of cycles over the data.

2021-06-28T20:28:53.191600Z

I’m interested in trying Asami and would be interested in knowing some typical setups. Haven’t worked with in-memory only databases much, so… do you import from disk/DB (or wherever) on start and go from there, or what is a typical usecase? 🙂

quoll 2021-06-28T20:30:07.192Z

At work we load from a whole lot of JSON or EDN

quoll 2021-06-28T20:31:17.193Z

For in-memory stores, when I’m saving a lot of data, I’ll do an export-data to a file, and import-data when I restart

2021-06-28T20:32:00.193700Z

Thanks, great 🙂 So, haven’t looked but is there built-in import/export functionality?

2021-06-28T20:33:23.195200Z

Btw, read most of you background articles. Fascinating and a great read. Thanks for sharing so much, really interesting! 😄

quoll 2021-06-28T20:35:31.196300Z

thank you

2021-06-28T20:39:00.198500Z

For loading from JSON, XML or other messy files, that would be regular parsing and a lot of transacts, right?

quoll 2021-06-28T20:51:19.199Z

I haven’t tried from XML, but so long as you have a seq of objects it’s fine

quoll 2021-06-28T20:52:47.200500Z

You can insert statements (triples) easily enough, but we tend to not do that. Instead we go with objects. These are deconstructed into triples, and they all go in together in a transaction

quoll 2021-06-28T20:53:31.200800Z

Here’s a copy paste from a session I was using on Friday…

quoll 2021-06-28T20:54:07.201400Z

(require '[asami.core :as d]) 
(require '[cheshire.core :as json]) 
(require '[<http://clojure.java.io|clojure.java.io> :as io]) 
(def bundle-dir (io/file "/data/bundle")) 
(def bundles (map (comp json/parse-stream io/reader) (.listFiles bundle-dir))) 
(def tx2 @(d/transact conn {:tx-data bundles})) 

quoll 2021-06-28T20:54:42.201800Z

That was Clojure (not ClojureScript) of course

quoll 2021-06-28T20:55:22.202400Z

each file in the bundle directory held a single map object, and it was several MB of data

refset 2021-06-28T20:58:01.202500Z

> the graphs I’m working with are small enough to live in memory anyway ah okay, that definitely tips it in favour of just doings things outside of whatever durable store you use 🙂

quoll 2021-06-28T21:07:51.207800Z

To load triples, I tend to just write them as edn, and load them that way. e.g. triples.edn

[[#a/n[123] :type :person]
 [#a/n[123] :first-name "Betty"]
 [#a/n[123] :last-name "Rubble"]
 [#a/n[123] :spouse #a/n[124]]
 [#a/n[123] :child #a/n[125]]
 [#a/n[124] :type :person]
 [#a/n[124] :first-name "Barney"]
 [#a/n[124] :last-name "Rubble"]
 [#a/n[124] :spouse #a/n[123]]
 [#a/n[124] :child #a/n[125]]
 [#a/n[125] :type :person]
 [#a/n[125] :first-name "Bam-Bam"]
 [#a/n[125] :last-name "Rubble"]]
(require '[clojure.edn :as edn])
(def data (edn/read-string (slurp "triples.edn")))
(def tx @(d/transact conn {:tx-triples data})) 

2021-06-28T21:11:49.209200Z

Fantastic, thank you so much. This helps me get going without (as much) stumbling around first… 👍😊

quoll 2021-06-28T21:12:08.209500Z

Maybe I should write a wiki page with the above

2021-06-28T21:15:08.212600Z

Please do. 🙂