Goals This guide explains the example application we use to introduce the different Neo4j drivers in detail. Prerequisites You should be familiar with graph database concepts and the property graph model. You should have installed Neo4j and made yourself familiar… Learn More →

Goals
This guide explains the example application we use to introduce the different Neo4j drivers in detail.
Prerequisites
You should be familiar with graph database concepts and the property graph model. You should have installed Neo4j and made yourself familiar with our Cypher Query language.
Beginner


Example Project Description

To demonstrate connection to and usage of Neo4j in different programming languages we’ve created an example application. It is a simple, one-page webapp, that uses Neo4j’s movie demo database (movie, actor, director) as data set. The same front-end web page in all applications consumes 3 REST endpoints provided by backend implemented in the different programming languages and drivers.

  • movie search by title
  • single movie listing
  • graph visualization of the domain

movie application

Domain Model

(:Person {name})-[:ACTED_IN {roles}]->(:Movie {title,released})

GitHub

The source code for all the different language examples is available on GitHub as individual repositories that can be cloned and directly used as starting points.

Webpage

The webpage is a single Bootstrap page that uses jQuery AJAX calls to access the backend and adds the returned JSON result data to HTML DOM elements in the page.

For the search, that is the /search?q=query endpoint whose results are added as table rows in a listing.

If you click on any of the movie titles, the right-side view is populated with the movie details.

For the movie details it uses the /movie/A%20Movie%20Title endpoint and the results are rendered as panel title, image source, and unordered list for the crew.

Graph Visualization

For the Graph Visualization we use d3.js. Our /graph endpoint already returns the data in the format of “nodes” and “links”-list that d3 can use directly. We then apply the force-layout algorithm to render nodes as circles and relationships as lines, and add some minimal styling to the visualization to provide the movie title/person name as title attribute to the node circles which is shown as a tooltip.

Data Setup

  • Start your local Neo4j Server (Download & Install)
  • Open the Neo4j Browser.
  • Log in, remember the password
  • Install the Movies dataset with :play movies
  • Click the large CREATE statement and hit the triangular “Run” button to insert the data.

You can also choose to use our Neo4j Sandbox or a cloud-hosted Neo4j database. If you go this route, then you have to provide the URL to your Neo4j server in an environment variable NEO4J_URL.

Alternatively you can run this Cypher LOAD CSV statement:

LOAD CSV WITH HEADERS FROM "https://dl.dropboxusercontent.com/u/14493611/movies_setup.csv" AS row
MERGE (m:Movie {title:row.title}) ON CREATE SET m.released = toInt(row.released), m.tagline = row.tagline
MERGE (p:Person  {name:row.name}) ON CREATE SET p.born     = toInt(row.born)
WITH   m,p,row WHERE row.type = "ACTED_IN"
MERGE (p)-[r:ACTED_IN]->(m) ON CREATE SET r.roles = split(row.roles,";")[0..-1]

Endpoints

Get Movie

// JSON object for single movie with cast
curl http://localhost:8080/movie/The%20Matrix

{"title": "The Matrix",
 "cast": [{"job": "acted", "role": ["Emil"], "name": "Emil Eifrem"}, {"job": "acted", "role": ["Agent Smith"], "name": "Hugo Weaving"}, ...
          {"job": "directed", "role": null, "name": "Andy Wachowski"}, {"job": "produced", "role": null, "name": "Joel Silver"}]}

The Cypher query is used, with the parameters {title:"The Matrix"}

It matches the movie by title, then optionally finds all people working on that movie and returns the movie title and a crew-list consisting of a map with person-name, job identifier derived from the relationship-type and optionally a role for actors.

LOAD CSV WITH HEADERS FROM "https://dl.dropboxusercontent.com/u/14493611/movies_setup.csv" AS row
MERGE (m:Movie {title:row.title}) ON CREATE SET m.tagline = row.tagline,m.released=row.released
MERGE (p:Person {name:row.name}) ON CREATE SET p.born = row.born
FOREACH (_ in CASE row.type WHEN "ACTED_IN" then [1] else [] end |
   MERGE (p)-[r:ACTED_IN]->(m) ON CREATE SET r.roles = split(row.roles,";")[0..-1]
)
FOREACH (_ in CASE row.type WHEN "DIRECTED" then [1] else [] end | MERGE (p)-[:DIRECTED]->(m))
FOREACH (_ in CASE row.type WHEN "PRODUCED" then [1] else [] end | MERGE (p)-[:PRODUCED]->(m))
FOREACH (_ in CASE row.type WHEN "WROTE"    then [1] else [] end | MERGE (p)-[:WROTE   ]->(m))
FOREACH (_ in CASE row.type WHEN "REVIEWED" then [1] else [] end | MERGE (p)-[:REVIEWED]->(m))

Search Movies

// list of JSON objects for movie search results
curl http://localhost:8080/search?q=matrix

[{"movie": {"released": 1999, "tagline": "Welcome to the Real World", "title": "The Matrix"}},
 {"movie": {"released": 2003, "tagline": "Free your mind", "title": "The Matrix Reloaded"}},
 {"movie": {"released": 2003, "tagline": "Everything that has a beginning has an end", "title": "The Matrix Revolutions"}}]

The Cypher query used, with the parameters {query:"matrix"}.

The search movies query matches the movies by title with CONTAINS and then returns the movie nodes as a list of maps with the title, released and tagline entries.

MATCH (movie:Movie)
 WHERE lower(movie.title) CONTAINS {query}
 RETURN movie

Graph Visualization

// JSON object for whole graph viz (nodes, links - arrays)
curl http://localhost:8080/graph[?limit=50]

{"nodes":
  [{"title":"Apollo 13","label":"movie"},{"title":"Kevin Bacon","label":"actor"},
   {"title":"Tom Hanks","label":"actor"},{"title":"Gary Sinise","label":"actor"},
   {"title":"Ed Harris","label":"actor"},{"title":"Bill Paxton","label":"actor"}],
 "links":
  [{"source":1,"target":0},{"source":2,"target":0},{"source":3,"target":0},
   {"source":4,"target":0},{"source":5,"target":0}]}

The Cypher query used finds all pairs of movies and actors and returns the movie title and a collection of all actor names as cast. A separate function then takes this result and converts it into the node- and link-list that d3 expects.

The parameter {limit:50} is used to prevent the visualization from becoming a hairball.

MATCH (m:Movie)<-[:ACTED_IN]-(a:Person)
 RETURN m.title as movie, collect(a.name) as cast
 LIMIT {limit}

Run Locally

Then setup and start the language/stack specific implementation of the backend and open the web-application on http://localhost:8080.

You can search for movies by title or click on any result entry to see the details.

Deploy to Heroku

Many of the mentioned GitHub example repositories feature a “Deploy to Heroku” button. You can either use that or follow the manual process outlined below.

We want to install our application to the cloud, for instance the Heroku PaaS. We will also use either the GrapheneDB or GraphStory Neo4j Database Hosting Add-On or the free Neo4j Sandbox

Install the Heroku Toolbelt and git.

Then run these commands:

# initialize git repository and add files
git init
git add .
git commit -m"my neo4j movies app"

# create heroku application, please change the app-name
export app=my-neo4j-movies-app
heroku apps:create $app

# add free hosting database
heroku addons:add graphenedb:chalk --app $app
# or
heroku addons:add graphstory --app $app

# configure your app to use the add-on
heroku config:set NEO4J_REST_URL=GRAPHENEDB_URL --app $app
# or
heroku config:set NEO4J_REST_URL=GRAPHSTORY_URL --app $app

# deploy to heroku
git push heroku master

# open application
heroku open --app $app

# open addon admin page
heroku addons:open graphenedb
# or
heroku addons:open graphstory

In the Graphenedb-UI use “Launch Neo4j Admin UI”. In the Neo4j-Browser import the :play movies dataset as of the install instructions above.

Make sure that username and password are provied as part of the URL, e.g. bolt://user:password@host:port or http://user:password@host:port.

Then your app is ready to roll.

Existing Language / Driver Examples

For our example application we’ve provided a implementation for the languages and drivers listed below. You can find them in the Neo4j Examples GitHub repository. Most of them have thankfully been made available by the driver authors.