"A human being should be able to change a diaper, plan an invasion, butcher a hog, conn a ship, design a building, write a sonnet, balance accounts, build a wall, set a bone, comfort the dying, take orders, give orders, cooperate, act alone, solve equations, analyze a new problem, pitch manure, program a computer, cook a tasty meal, fight efficiently, die gallantly. Specialization is for insects." (Robert A. Heinlein)

Saturday, 24 May 2014

Now something completely different: Neo4j


I've been interested in the variegated world of “NOSQL” databases since a while but I was mostly undecided which one start experimenting with. Most of NOSQL databases give their best in high data volumes, high availability, high scalability, “high everything” use cases. Going to test such databases in a realistic way is not an easy task. Testing them on a EEEPC while traveling by train is definitively impossible. I so concentrated my interest on “Graph Databases”: a kind of NOSQL databases designed to represent data tied by complex and deep relationships, hard to be described by the classic table form.

Neo4j

Among the many, Java based, graph databases the one that got my attention has been Neo4j. Two things made me decide for testing Neo4J: first Neo4J is embeddable in your Java project, the second is the huge amount of documentation and examples available at Neo4j site.

Installation

Installing Neo4j has been quite simple just matter of extracting the downloaded archive into a folder in my home directory (I have a “Projects” folder for this)
tar xv neo4j-community-2.0.3-unix.tar.gz
this is more than enough for a test installation or if you are going to use it only embedded in anoter Java project. Installing a Neo4j server would be a little more more tricky.
Neo4j service can be started by shell using the “neo4j” script provided in the bin directory:
cd Projects/neo4j-community-2.0.3/bin/
./neo4j start
at start it gives a warning about not running it in a Oracle Java JVM but during my tests it worked fine even with OpenJDK JVM. Of course fro a more intense use it'd better follow the suggestion and use the right JVM.
The same script can be used to stop Neo4j service:
./neo4j stop
User interface

Neo4j offers a web based user interface on the “http://localhost:7474” address. The web interface provide an easy way to send commands to Neo4j with the help of a good variety of saved scripts and examples available with one mouse click.
a more complex administration interface is available at the “http://localhost:7474/webadmin/” address.

The Cypher language

Cypher is the language used by Neo4j to describe graphs and navigate trough them. In the Neo4j site there is a huge content about Cypher documentation and examples. As first Cypher experiment I decided to represent my home computer network defining nodes to represent devices and links for the network connection.
create (eee:pc {name:"EEEPC900",ram:"2G",mhz:"900",wifi:"yes"}),
(des:pc {name:"VeritonS661",ram:"3G",mhz:"1800",cores:2}),
(pho:phone {name:"LGL3E400",wifi:"yes"}),
(swi:switch {name:"5Ports"}),
(vod:router {name:"Vodafone",wifi:"yes"}),
(eee)-[:ethernet]->(swi),
(des)-[:ethernet]->(swi),
(swi)-[:ethernet]->(vod),
(eee)-[:wifi]->(vod),
(pho)-[:wifi]->(vod);
computers connect to the wired network trough a LAN switch while WIFI enabled devices connect directly to the WIFI router. Representing a computer network with nodes and link comes natural but nodes could also represent operating systems:
create (u:os {name:"Ubuntu", version:"14.04"}),
(w:os {name:"Windows", version:"XP"}),
(a:os {name:"Android", version:"2.3"});
then use e “boot with” link to describe which device boots with which operating system:
match (x:pc), (y:phone), (u:os {name:"Ubuntu"}), (w:os {name:"Windows"}), (a:os {name:"Android"})
create (x)-[:boot_with]->(u),
(x)-[:boot_with]->(w),
(y)-[:boot_with]->(a);
here is the resulting graph as shown by Neo4j web interface:

Wat's next?

Experimenting with Neo4j has been a very interesting experience, I'm only starting to thing how many projects could get a benefit from representing their data with a graph. Next step will certainly trying to embed Neo4j in a Java project.