This is a simple graph database in SQLite, inspired by “Denis Papathanasiou’s simple-graph project”, however this is written in R. This package is fully compatible with the python equivalant and interoperable. There are minor differences in the API, but it is largely identical.
Similar to the python library, the schema consists of just two structures:
id
valueid
values, specifying
the direction, with an optional json object as connection
propertiesdevtools::install_github("https://github.com/mikeasilva/simplegraphdb")
The R package provides convenience functions for atomic transactions to add, delete, connect, and search for nodes.
Any single node or path of nodes can also be depicted graphically by
using the visualize
function within the database script to
generate dot
files, which in turn can be converted to images with Graphviz.
Once loading the package in R, we can create, upsert, and connect
people from the early days of Apple Computer. The
resulting database will be saved to a SQLite file named
apple.sqlite
:
apple <- "apple.sqlite"
initialize(apple)
atomic(apple, add_node(list("name" = "Apple Computer Company", "type" = c("company", "start-up"), "founded" = "April 1, 1976"), 1))
atomic(apple, add_node(list("name" = "Steve Wozniak", "type" = c("person", "engineer", "founder")), 2))
atomic(apple, add_node(list("name" = "Steve Jobs", "type" = c("person", "designer", "founder")), 3))
atomic(apple, add_node(list("name" = "Ronald Wayne", "type" = c("person", "administrator", "founder")), 4))
atomic(apple, add_node(list("name" = "Mike Markkula", "type" = c("person", "investor")), 5))
atomic(apple, connect_nodes(2, 1, list("action" = "founded")))
atomic(apple, connect_nodes(3, 1, list("action" = "founded")))
atomic(apple, connect_nodes(4, 1, list("action" = "founded")))
atomic(apple, connect_nodes(5, 1, list("action" = "invested", "equity" = 80000, "debt" = 170000)))
atomic(apple, connect_nodes(1, 4, list("action" = "divested", "amount" = 800, "date" = "April 12, 1976")))
atomic(apple, connect_nodes(2, 3))
atomic(apple, upsert_node(2, list("nickname" = "Woz"), apple))
The nodes can be searched by their ids or any other combination of
attributes (either as strict equality, or using search_like
in combination with search_starts_with
or
search_contains
):
atomic(apple, find_node(1))
{'name': 'Apple Computer Company', 'type': ['company', 'start-up'], 'founded': 'April 1, 1976', 'id': 1}
atomic(apple, find_nodes({'name': 'Steve'}, "search_like", "search_starts_with"))
[{'name': 'Steve Wozniak', 'type': ['person', 'engineer', 'founder'], 'id': 2, 'nickname': 'Woz'}, {'name': 'Steve Jobs', 'type': ['person', 'designer', 'founder'], 'id': 3}]
Paths through the graph can be discovered with a starting node id,
and an optional ending id; the default neighbor expansion is nodes
connected nodes in either direction, but that can changed by specifying
either find_outbound_neighbors
or
find_inbound_neighbors
instead:
traverse(apple, 2, 3)
[2, 3]
traverse(apple, 4, 5)
[4, 1, 5]
traverse(apple, 5, neighbors_fn="find_inbound_neighbors")
[5]
traverse(apple, 5, neighbors_fn="find_outbound_neighbors")
[5, 1, 4]
traverse(apple, 5, neighbors_fn="find_neighbors")
[5, 1, 4, 3, 2]
Any path or list of nodes can rendered graphically by using the
visualize
function. This command produces dot files, which are
also rendered as images with Graphviz:
visualize(apple, 'apple.dot', c(4, 1, 5))
There are display options to help refine what is produced:
visualize(apple, 'apple.dot', c(4, 1, 5), exclude_node_keys=c('type'), hide_edge_key=TRUE)