Overview Why Neo4j? Introduction to Neo4j Cypher Neo4j in Ruby Setup The Fun Stuff Eager Loading Recommendations Doing More An example Sinatra application The asset_portal application Getting Help More Screencasts Integrations with other gems Goals This course provides an overview… Read more →
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.
Introduction to Neo4j
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.
Neo4j in Ruby
For this guide, we will be using the Neo4j.rb project. The project consists of the following gems:
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.
The Fun Stuff
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!
An example Sinatra application
For the example view, see the one from the result of the Rails example above.
The asset_portal application
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