Use cases

Knowledge graphs larger than RAM

A knowledge graph keeps growing: more entities, more links, more sources. GraphBuff's persistent mode keeps the graph on disk and reads it through a page cache, so its size is bounded by the disk, not by memory.

The problem

An in-memory graph database is fast until the graph is bigger than the machine. Then the choice is a larger machine or a different database, usually in the middle of a project.

With --persistent the same Cypher runs against fixed-size records on disk, with B+tree indexes and a redo log. Start in memory, switch the storage mode when the data needs it; nothing in the queries changes.

Try it with this dataset

Sixteen entities (people, organisations, places, topics), twenty links and an index on the name. Run this in your GraphBuff checkout (get one in a single command); it downloads knowledge.cypher, loads it and leaves you in the shell.

$ curl -O https://graphbuff.com/datasets/knowledge.cypher
$ cargo run --release -p graphbuff-cli -- --data ./kg --persistent -i knowledge.cypher
1 indexes added
16 nodes created, 20 relationships created, 21 properties set, 32 labels added

Who worked in France?

Query 1

A person works at an organisation, which is in a city, which is in a country: the country is reached through any number of LOCATED_IN hops.

MATCH (p:Person)-[:WORKED_AT]->(o)-[:LOCATED_IN*]->(:Place {name: 'France'})
RETURN p.name AS person, o.name AS organisation ORDER BY person;
+----------------+--------------+
| person         | organisation |
+----------------+--------------+
| "Marie Curie"  | "Sorbonne"   |
| "Pierre Curie" | "Sorbonne"   |
+----------------+--------------+
2 rows

How are Marie Curie and Otto Hahn connected?

Query 2

The shortest path over any relationship, in either direction.

MATCH p = shortestPath((a:Entity {name: 'Marie Curie'})-[*]-(b:Entity {name: 'Otto Hahn'}))
RETURN [n IN nodes(p) | n.name] AS connection, length(p) AS hops;
+----------------------------------------------------------------------------+------+
| connection                                                                 | hops |
+----------------------------------------------------------------------------+------+
| ["Marie Curie", "Radium", "Radioactivity", "Nuclear fission", "Otto Hahn"] | 4    |
+----------------------------------------------------------------------------+------+
1 row

Look up by prefix, then follow the links

Query 3

The name index answers the prefix search; the pattern collects who discovered each topic.

MATCH (e:Entity) WHERE e.name STARTS WITH 'Ra'
OPTIONAL MATCH (who:Person)-[:DISCOVERED]->(e)
RETURN e.name AS topic, collect(who.name) AS discoveredBy ORDER BY topic;
+-----------------+---------------------------------+
| topic           | discoveredBy                    |
+-----------------+---------------------------------+
| "Radioactivity" | []                              |
| "Radium"        | ["Marie Curie", "Pierre Curie"] |
+-----------------+---------------------------------+
2 rows

Not running GraphBuff yet?

$ docker run --rm -p 127.0.0.1:7475:7475 -p 127.0.0.1:7687:7687 ghcr.io/janvencl/graphbuff --demo movies

Needs Docker. Full walkthrough