Developer Guides Getting Started Getting Started What is a Graph Database? Intro to Graph DBs Video Series Concepts: RDBMS to Graph Concepts: NoSQL to Graph Getting Started Resources Neo4j Graph Platform Graph Platform Overview Neo4j Database Neo4j Desktop Intro Neo4j… Read more →
Getting Started with Neo4j and Ruby
This course provides an overview on everything that you need to build a Neo4j application with the Ruby programming language. Ruby on Rails and Sinatra examples are given but any web framework (or lack thereof) can be used.
You should have Ruby installed on your system. Some experience with Ruby and/or Rails is suggested.
Let’s say you would like to write a web application to track entities for yourself or your organization. Being a good DRY programmer you might decide that what you want is an asset portal: an application which gives you an GUI for browsing and editing entities while also making it easy to define new assets. This guide will show you how you might start creating such an application using Ruby on Rails and Neo4j.
Neo4j is the world’s most popular graph database. This offers a number of advantages:
- Neo4j provides a schemaless representation of both entities and relationships between entities.
- Relationships between entities are traversed rather than joined. Traversals explore the local subgraph meaning that query times stay the same as your database grows.
- Because of the traversal paradigm we think in terms of the complex relationships in our data without worrying as much how to model it
Rubyists generally prefer tools which are developer friendly and which don’t bother you with details until it’s neccessary. Neo4j makes it easy to create nodes and relationships in whatever way seems most natural, but you can also change the structure of your database with a query.
Connected information is everywhere in our world. Neo4j was built to efficiently store, handle, and query highly-connected elements in your data model. With a powerful and flexible data model, you can represent your real-world, variably-structured information without a loss of fidelity. The property graph model is easy to understand and handle, especially for object-oriented and relational developers.
The property graph model consists of:
Nodes, which have:
- properties: schemaless key/value pairs
- labels: describe and group nodes much like tables group rows, but nodes can have multiple labels
Relationships, which connect two nodes directionally and have:
- properties: schemaless key/value pairs
- A type: gives a description of how it connects the two nodes
While relationships are directional, querying relationships in either direction has no associated performance cost.
Cypher is Neo4j’s built-in query language. Cypher queries look like the following code block:
MATCH clause is the most common starting point for Cypher queries.
It defines a pattern for which to search and returns one result per match.
For example, we might get the following two matches:
RETURN clause, we would end up returning a table such as:
Here, you see we can return entire entities in our database rather than just properties.
This might be returned as a
Hash in Ruby, though by default in the Neo4j.rb gems these are wrapped in an object.
This is very handy, but it would also be nice to avoid the duplication of our
You can perform the same match but instead use the
collect function to aggregate the values:
While it’s possible to get started using the Neo4j.rb without learning Cypher, it is a very powerful way to query a Neo4j database and is worth learning. Also, since the Neo4j.rb project works by making Cypher queries to Neo4j it is good to understand Cypher as your queries get more complex. There is a Cypher tutorial if you would like to learn more.
For this guide, we will be using the Neo4j.rb project. The project consists of the following gems:
The Neo4j.rb project is made up of the following Ruby gems:
A Object-Graph-Mapper (OGM) for the Neo4j graph database. It tries to follow API conventions established by ActiveRecord but with a Neo4j flavor.
A low level driver for connecting to Neo4j. Used by the neo4j gem.
A set of rake tasks for installing and managing a Neo4j database within your project. Used by the neo4j-core gem.
- Andreas Ronge, one of our Swedish friends from Malmö, started writing his canonical Neo4j Ruby driver since before we hit 1.0.
- Brian Underwood and Chris Grigg joined the project and together released version 3.0 in September 2014.
- Starting in 2017, the team around Heinrich Klobuczek contributed to the project and from fall 2018 Heinrich took over the Neo4j.rb project as the primary maintainer.
Neo4j-core is a gem that provides low-level communication to a Neo4j server. In addition to basic database communicaton and node/relationship CRUD, Neo4j-core provides strong support for Neo4j’s schema indexes, constraints, labels, and a strong Cypher DSL.
How to get running:
The neo4j gem uses neo4j-core as an API to connect to the server and provides an ActiveRecord-like experience for use in frameworks. It adds modules allowing the creation of models that look and feel very similar to those found in vanilla Ruby on Rails. The gem builds on Neo4j-core’s foundation to streamline all aspects of node and relationship CRUD and provides an extremely advanced, intuitive, flexible DSL for generating Cypher.
How to get running:
Very often, your gem choice may come down to how you want to deploy:
Using Ruby with a separate Neo4j Server over the HTTP API
Connecting directly to the Neo4j database files from within your Ruby process (this requires JRuby)
A separate Neo4j server is go-to choice for most developers, especially if they are used to other relational or NoSQL databases in frameworks such as Ruby on Rails.
It allows you to have separate web and database servers and allows compatibility with popular PaaSes such as Heroku. If this sounds good to you, any of the popular gems are solid choices and you are free to consider whether you want a thin wrapper or the full framework experience.
Neo4j Embedded and JRuby is less common but offers blazing fast performance and access to our core Java API. The downside is that JRuby has its own configuration and compatibility demands and hosting a Java app can be difficult. Thankfully, modern app servers such as Torquebox and a strong community provide far more options and resources now than ever before. If this is right for you, the Neo4j-core and Neo4j gems will offer what you need.
There are many common gems that you’ll want to use with your Neo4j database. Many are supported for the Neo4j.rb project:
Admin User Interface
Integration With the Neo4j Spatial Plugin
Ruby Object Manager
- neo4j-even_easier_id (BSON UUIDs)
The Neo4j example project is a small, one page webapp for the movies database built into the Neo4j tutorial. The front-end page is the same for all drivers: movie search, movie details, and a graph visualization of actors and movies. Each backend implementation shows you how to connect to Neo4j from each of the different languages and drivers.
You can learn more about our small, consistent example project across many different language drivers here. You will find the implementations for all drivers as individual GitHub repositories, which you can clone and deploy directly.
Specifically in this guide, we will be using the
ActiveRel modules from the
neo4j gem to model nodes and relationships from our database.
The following example is in Ruby on Rails, but there is a Sinatra example below.
Here, we describe how to create a fresh Rails application with Neo4j as the database. If you have an existing Rails application, you can refer to the Neo4j.rb documentation.
Here is how you would setup your asset portal Rails app:
What do these commands do?
The first creates a new Rails app skipping
-O flag) and setting up Neo4j.rb in your project (the
Then, we change into our directory and install the latest version of the community edition of Neo4j into our app directory (into
Last, we start up our copy of Neo4j.
Next, you should open up your
config/application.rb file and find the
Here, you have a choice between *embedded* and server modes:
- Server mode allows you to connect to Neo4j via it’s HTTP JSON APIs.
- Embedded mode requires JRuby and allows you to run Neo4j as part of your JRuby process. This gives you access to the Neo4j Java APIs directly.
By default, you will be configured to Neo4j in server mode on the default port (7474). If you would like something other than the default console, take a look at the documentation.
To see an example of setting up Neo4j in Rails, check out this short screencast.
In this guide, we will be setting up different
ActiveNode models, which will serve as assets.
This is a textbook example of where we can use class inheritance in Neo4j.rb.
First, we create some basic models:
This will generate scaffolds just like any Rails application, with the exception that the models will be
ActiveNode models rather than
ActiveRecord models and will look like this:
Since Neo4j is schemaless, we need to define our properties in our model.
To learn more about properties, check out this short screencast.
Once we’ve set up those models, we can define our asset models like so:
That should generate a model that looks like this:
You should change that to look like the following (note the
Asset superclass definition):
By inheriting from
Book model will create nodes with two labels (
Likewise, when you query for nodes via the
Book model, it will only find nodes which have both labels.
Lastly, we just need to make a couple of small fixes. Change these lines to get the names of book authors and categories:
And change these lines to be able to choose the author when creating or editing books:
So that you can set your associations, change the
book_params method in the
BooksController to remove the
Now that we have created our scaffolding, let’s run the migrations to create constraints for our models and start up our Rails server:
From there, you can create, update, browse, and delete books via the scaffolding.
You can visit
/categories to get entry points into the various sections.
If you just wanted to do simple CRUD operations, there are plenty of other databases to choose from. How can we do something a bit more fun using the power of Neo4j?
First, let’s look at a performance improvement, which is not available from
When you go to your list of books, you should see something like this in your log:
If you find that a bit hard to read, then you can add the following line to your application’s configuration:
Once you complete that, your log will look more like this:
First, the books are loaded, and then separate queries are made to get all of the authors and categories for those books.
ActiveRecord, you would need to specify an
includes in order to make this happen rather than having each entity loaded individually.
ActiveNode, on the other hand, makes the assumption that if you refer to an association from a list of items, you are almost certainly going to want that association for all of the objects.
But we can do better!
Now, modify the
index action of the
BooksController like so:
with_associations method is similar to
includes, except that our associations are loaded in the same query using the
collect() function demonstrated earlier.
What we get is a list of
Book objects that are pre-populated with authors and categories.
You may have heard that Neo4j makes building recommendations from your data easy.
Let’s take a look at how we might make some recommendations.
For this, we are going to introduce
Since entities are connected via relationships in Neo4j, the database doesn’t draw any distinction for when we want to have a single relationship or many to/from a node.
In our Ruby apps, however, it is often convenient to be able to draw this distinction.
To learn more about associations, check out this short screencast.
First, change the
category association for the
Don’t forget to change the
:category argument in the
with_associations call in the controller to
:categories like below.
Then add a
books association to the
Since we have changed the
has_many for the book categories, we should update our scaffold UI to match:
Now, with the ability for a book to have many categories and for a category to have many books, you can have a much better picture about recommending books.
It is simple to get a start on querying potential recommendations. Try running this in your Rails console:
It should show you the query which was made and it should look something like:
This query is finding all of the books that share categories with all other books.
This is not particularly useful until we start introducing some variables.
neo4j gem, this is called association chaining.
For more information about association chaining, check out this short screencast:
What if you wanted to list every book and find out, for every other book with which it shares a category, how many categories it shares?
Notice how we are starting to assign variables. These eventually become the variables in the cypher query made to Neo4j.
Taking it a step further, let’s create a query which finds, all the books that share at least two categories. We can also display these recommendations in our app like so:
Of course, we don’t want to put too much logic in the controller, so we can extract this to a model class method:
all method starts it off, we can actually add this to an existing chain rather than just calling it on the
For example, if we had a
recent scope which only gave us books from the past ten years:
Are you getting into the idea of using Neo4j? Great! If you still have a lot of questions, there are a number of resources to help you along with your journey.
For the fastest help or answers to questions, take a look at or reach out to us on our Neo4j Online Community!
For the example view, see the one from the result of the Rails example above.
You can find the result of this guide in its GitHub repository.
If you would like to play with a more developed application, check out our asset_portal app.
The project introduces a single
AssetController to avoid the duplication from this guide and also uses other tools like Semantic UI for a cleaner interface.
In addition to the screencasts embedded in this guide, there are two others to help you learn more about the