continuous-integration/drone/push Build is passing
Details
|
||
---|---|---|
.. | ||
resources/public | ||
src | ||
deps.edn | ||
dev.cljs.edn | ||
figwheel-main.edn | ||
readme.org |
readme.org
Minimal clojurescript project demoing datalog queries
Getting started
To work with the code interactively jack into the project in your IDE of choice select "figwheel-main" as the build tool and dev as the build.
Alternatively start a repl from the command line with
clojure -m figwheel.main --build dev --repl
Intro to datalog
See the extensive comments in the src code for a working example, also watch / read these for a good intro.
https://www.youtube.com/watch?v=oo-7mN9WXTw http://www.learndatalogtoday.org/ https://udayv.com/clojurescript/clojure/2016/04/28/datascript101/
Blog of the dev who makes datascript https://tonsky.me/blog/the-web-after-tomorrow/
Creating a DATABASE
Datalog databases can be schema less but a lot of the power comes from creating a schema specifying uniqueness and relations.
Schema less Database
In it's simplest for we create a database connection like below.
(def demo-conn (d/create-conn {}))
Using the connection we can just start inserting data, using standard hash maps and lists structures, we always specify the attribute and the value when transacting.
(d/transact! demo-conn [{:user/name "Oly" :user/img "me.jpg"} {:user/name "Sam" :user/img "you.jpg"}])
Using a Schema
In this example we are saying name is unique and rooms has a many to one relationship, when we transact data will be inserted even if its not in the schema but rules stop things like duplicates from happening.
(def schema {:user/name {:db/unique :db.unique/identity}
:user/rooms {:db/cardinality :db.cardinality/many
:db/valueType :db.type/ref}})
(def demo-conn (d/create-conn schema))
Transacting this data would mean Oly would be inserted once but the image will be updated to you.jpg
(d/transact! demo-conn [{:user/name "Oly" :user/img "me.jpg"} {:user/name "Oly" :user/img "you.jpg"}])
Querying the databases
There are three types of queries in datalog entity lookup's pulling a tree of data or querying with d/q
.
Looking up an entity
d/entity
is used to find the entity id, using any unique piece of data for example the user Oly
exists once so the entity db/id will be returned which can be used for further queries.
(d/entity @conn [:user/name "Oly"])
Pull a tree of data
Pull is used with entity id's once you know the entity you can specify what data you want to view '[*]
being the most common looking up all keys, you can also specify the attributes your interested in looking up including there relations to make a more specific view.
(d/pull @demo-conn '[*] 1)
(d/pull @demo-conn '[:user/name :user/rooms] 1)
Querying your dataset
Querying in datalog is all about binding variables to your entities attributes and values which you can use in you conditions or to return in the result set.
In this example we return the user-id and user/name in the find clause which we looked up in the where clause by finding all attributes :user/name
the binding the entity id and username to variables on each match to display in the find clause.
(d/q '[:find ?user-entity ?user-name :where
[?user-entity :user/name ?user-name]] @demo-conn)
Write some more as needed better examples in the src code.