Check-out our new look and give us some feedback!
Reading Time: 8 minutes
neo4j

Introduction

In this tutorial, we will examine what Neo4j is, what it is used for, and how it is implemented. We will also install and configure the installation on an Ubuntu 20.04 server. Neo4j is a graphical database used to create data relationships. Other examples of graphical databases include:

  • ArangoDB
  • Grakn Core
  • Microsoft SQL Server 2017
  • OrientDB
  • RedisGraph

What is Neo4j

Neo4j connects data as it is stored, allowing us to run queries that we never knew or thought about before. To put it simply, Neo4j records the relationship between data nodes, whereas conventional relational databases use columns and rows to store structured data. Since each node stores references to all the other nodes to which it is connected, Neo4j can encode and query complex relationships with minimal overhead.

Neo4j can encode and query complex relationships with minimal overhead

By Originally uploaded by Ahzf (Transferred by Obersachse) - Originally uploaded on en.wikipedia, CC0, https://commons.wikimedia.org/w/index.php?curid=19279472

Neo Technology is the creator and developer of the open-source software Neo4j. The company has been developing it since 2003. It is written in Java and Scala, and the source code is freely available on GitHub. As of 2015, it is considered the most utilized graphical database management system in use today. Neo4j employs its own query language called Cypher, but queries can also be written in other styles, for example, through the Java API.

Prerequisites

For this installation, the software requires the following baseline settings.

  • 8 GB RAM and a four-core server. At a minimum, the recommended use is 1 GB RAM and a single-core server.
  • Ubuntu 20.04 OS
  • All commands are run as root. If you are a regular user, commands must be prefaced by the sudo command.

Neo4j installation

Add Repository

Ubuntu does not officially contain Neo4j in the standard package repository. We will add the package source pointing to the location of the Neo4j repository, then add the GPG key from Neo4j for verification, then install Neo4j itself.

We start by updating the list of packages and the packages themselves.

root@host:~# apt update && apt -y upgrade

Add Additional Software

In this step, we will install an additional package that is needed for HTTPS connections. This application may be already installed by default on the system, but they still need to be updated.

root@host:~# apt install apt-transport-https ca-certificates curl software-properties-common -y

The apt-transport-https package enables the usage of https via the package manager using the libapt-pkg library. This keeps the installation secure.

Verify Security Key

Now we add the official security key for the Neo4j package repository. This key check and verifies what you are installing is from the official repository.

 root@host:~# curl -fsSL https://debian.neo4j.com/neotechnology.gpg.key | apt-key add -
 OK
 root@host:~#  

Add Repository

Add the official Neo4j repository to the package manager list.

root@host:~# add-apt-repository "deb https://debian.neo4j.com stable 4.1"

Install Neo4j

When installing Neo4j and all its dependencies, it is essential to note that the installation will prompt us to install Java packages to work with Neo4j. During installation, press Y. to accept this software install. If you have Java installed, the installer will understand and skip this step.

 root@host:~# apt install neo4j -y
 Reading package lists... Done
 Building dependency tree       
 Reading state information... Done
 The following package was automatically installed and is no longer required:
   libfprint-2-tod1
 Use 'sudo apt autoremove' to remove it.
 The following additional packages will be installed:
   cypher-shell
 The following NEW packages will be installed:
   cypher-shell neo4j
 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
 Need to get 116 MB of archives.
 After this operation, 131 MB of additional disk space will be used.
 Get:1 https://debian.neo4j.com stable/4.1 amd64 cypher-shell all 4.1.3 [27,1 MB]
 Get:2 https://debian.neo4j.com stable/4.1 amd64 neo4j all 1:4.1.5 [88,4 MB]
 Fetched 116 MB in 10s (11,1 MB/s)                                              
 Preconfiguring packages ...
 Selecting previously unselected package cypher-shell.
 (Reading database ... 163626 files and directories currently installed.)
 Preparing to unpack .../cypher-shell_4.1.3_all.deb ...
 Unpacking cypher-shell (4.1.3) ...
 Selecting previously unselected package neo4j.
 Preparing to unpack .../neo4j_1%3a4.1.5_all.deb ...
 Unpacking neo4j (1:4.1.5) ...
 Setting up cypher-shell (4.1.3) ...
 Setting up neo4j (1:4.1.5) ...
 Processing triggers for man-db (2.9.1-1) ...
 Processing triggers for systemd (245.4-4ubuntu3.3) ...
 root@host:~#  

Start the Neo4j Service

Once we have it installed, we need to enable it as a neo4j.service service.

 root@host:~# systemctl enable neo4j.service
 Synchronizing state of neo4j.service with SysV service script with /lib/systemd/systemd-sysv-install.
 Executing: /lib/systemd/systemd-sysv-install enable neo4j
 Created symlink /etc/systemd/system/multi-user.target.wants/neo4j.service → /lib/systemd/system/neo4j.service.
 root@host:~#  

Check Neo4j Status

Next, we verify that everything is working as expected.

 root@host:~# systemctl status neo4j.service
  neo4j.service - Neo4j Graph Database
      Loaded: loaded (/lib/systemd/system/neo4j.service; enabled; vendor preset:>
      Active: active (running) since Wed 2020-12-23 20:04:44 +03; 2min 4s ago
    Main PID: 4827 (java)
       Tasks: 52 (limit: 9489)
      Memory: 447.9M
      CGroup: /system.slice/neo4j.service
              └─4827 /usr/bin/java -cp /var/lib/neo4j/plugins:/etc/neo4j:/usr/sh>
 сне 23 20:04:46 host neo4j[4827]: 2020-12-23 17:04:46.101+0000 INFO  ======== N>
 сне 23 20:04:47 host neo4j[4827]: 2020-12-23 17:04:47.073+0000 INFO  Initializi>
 сне 23 20:04:47 host neo4j[4827]: 2020-12-23 17:04:47.077+0000 INFO  Setting up>
 сне 23 20:04:47 host neo4j[4827]: 2020-12-23 17:04:47.077+0000 INFO  Creating n>
 сне 23 20:04:47 host neo4j[4827]: 2020-12-23 17:04:47.083+0000 INFO  Setting ve>
 сне 23 20:04:47 host neo4j[4827]: 2020-12-23 17:04:47.085+0000 INFO  After init>
 сне 23 20:04:47 host neo4j[4827]: 2020-12-23 17:04:47.088+0000 INFO  Performing>
 сне 23 20:04:47 host neo4j[4827]: 2020-12-23 17:04:47.197+0000 INFO  Bolt enabl>
 сне 23 20:04:47 host neo4j[4827]: 2020-12-23 17:04:47.843+0000 INFO  Remote int>
 сне 23 20:04:47 host neo4j[4827]: 2020-12-23 17:04:47.844+0000 INFO  Started.
 lines 1-19/19 (END)
 To exit this screen, press Ctrl + C.
 It is important to have the following parameters:
 Loaded: loaded (/lib/systemd/system/neo4j.service; enabled; vendor preset:>
  Active: active (running) since Wed 2020-12-23 20:04:44 +03; 2min 4s ago 

Test DB Connection

Since we installed Neo4j and started it as a service, we will now test the database connection and configure the admin user.

Note:
We are using the free, Community Edition Neo4j version. It supports simultaneous work with the same database, but does not include assigning roles and permissions to users.

Working With Neo4j

To interact with the database, we will launch the internal utility called cypher-shell to working with Neo4j. When we first run it, we will be asked to enter a user and password. By default, the username is neo4j, and the password is neo4j. After the first login, you will be prompted to change the password to one of your choosing.

 oot@host:~# cypher-shell
 username: neo4j
 password: *****
 Password change required
 new password: ********
 Connected to Neo4j 4.1.0 at neo4j://localhost:7687 as user neo4j.
 Type :help for a list of available commands or :exit to exit the shell.
 Note that Cypher queries must end with a semicolon.
 neo4j@neo4j>  

To exit, use the exit command.

 neo4j@neo4j> exit
 Bye!
 root@host:~#  

Add Nodes 

Let's set up some sample nodes and define relationships between them. Connect using Cypher

 root@host:~# cypher-shell
 username: neo4j
 password: ********
 Connected to Neo4j 4.1.0 at neo4j://localhost:7687 as user neo4j.
 Type :help for a list of available commands or :exit to exit the shell.
 Note that Cypher queries must end with a semicolon.
 neo4j@neo4j>  

Next, let's add a node called Liquidweb and the names of colleagues who work for this company under the name Margaret. We can do this using the CREATE command, and the syntax will be as follows.

 neo4j@neo4j> CREATE (:Liquidweb {name: 'Margaret'});
 0 rows available after 36 ms, consumed after another 0 ms
 Added 1 nodes, Set 1 properties, Added 1 labels
 neo4j@neo4j>  

Add Users

Let's add a few more colleagues and link them to the company they work for, Liquidweb. We will connect using the FRIEND command.

 neo4j@neo4j> CREATE (:Liquidweb {name: 'John'})-[:FRIEND]->
              (:Liquidweb {name: 'Peter'})-[:FRIEND]->
              (:Liquidweb {name: 'Chris'});
 0 rows available after 38 ms, consumed after another 0 ms
 Added 3 nodes, Created 2 relationships, Set 3 properties, Added 3 labels
 neo4j@neo4j>  

Create Relationships

Since Peter and Chris work in the same department and have the same properties as nodes, we will create a relationship with the name column.

 neo4j@neo4j> MATCH (a:Liquidweb),(b:Liquidweb)
              WHERE a.name = 'Peter' AND b.name = 'Chris'
              CREATE (a)-[r:DEPARTMENT { name: 'Developers' }]->(b)
              RETURN type(r), r.name;
 +------------------------+
 | type(r) | r.name       |
 +------------------------+
 | "DEPARTMENT" | "Developers" |
 +------------------------+
 1 row available after 105 ms, consumed after another 10 ms
 Created 1 relationships, Set 1 properties
 neo4j@neo4j> 
  • MATCH - This indicates the correspondence of the nodes. In this case, within one company Liquidweb
  • WHERE - between values
  • CREATE - create and add
  • RETURN - Return to the base.

Now create a connection between John and Chris, although they are in different departments, but they are working on the same project.neo4j@neo4j> MATCH (a:Liquidweb),(b:Liquidweb)

              WHERE a.name = 'John' AND b.name = 'Chris'
              CREATE (a)-[r:PROJECT { name: 'Cool Project' }]->(b)
              RETURN type(r), r.name;
 +----------------------------+
 | type(r)   | r.name         |
 +----------------------------+
 | "PROJECT" | "Cool Project" |
 +----------------------------+
 1 row available after 48 ms, consumed after another 5 ms
 Created 1 relationships, Set 1 properties
 neo4j@neo4j>  

Display Info

Now we will display all this data and their relationships using the following query.

 neo4j@neo4j> Match (n)-[r]->(m)
              Return n,r,m;
 +--------------------------------------------------------------------------------------------------+
 | n                            | r                                  | m                            |
 +--------------------------------------------------------------------------------------------------+
 | (:Liquidweb {name: "John"})  | [:FRIEND]                          | (:Liquidweb {name: "Peter"}) |
 | (:Liquidweb {name: "John"})  | [:PROJECT {name: "Cool Project"}]  | (:Liquidweb {name: "Chris"})  |
 | (:Liquidweb {name: "Peter"}) | [:DEPARTMENT {name: "Developers"}] | (:Liquidweb {name: "Chris"})  |
 | (:Liquidweb {name: "Peter"}) | [:FRIEND]                          | (:Liquidweb {name: "Chris"})  |
 +--------------------------------------------------------------------------------------------------+
 4 rows available after 17 ms, consumed after another 2 ms
 neo4j@neo4j>  

We received the output data with the following FRIEND relationships, which show the relationship and the following data relationships between DEPARTMENT and PROJECT.

To exit the cypher shell, run the exit command.

 neo4j@neo4j> :exit
 Bye!
 root@host:~#  

Set up a Secure Remote Connection to Neo4j

We will not always be able to connect to the database from the server itself. If we want to configure the application to use Neo4j, we will need to configure it to securely connect to other servers. Also, we should configure the firewall in order to restrict which servers can attach to Neo4j.

By default, Neo4j connects via localhost (127.0.0.1 - localhost - intended for testing applications without working with other servers). Also, the work of Neo4j from localhost will not be open for public access to the Internet. Only users with access to the local network will be able to connect to Neo4j.

Configure Neo4j

For Neo4j to connect to other servers, we need to change the settings of the configuration file /etc/neo4j/neo4j.conf. We will use the nano editor for this task. Remember, if you are not root, use the sudo command.

 root@host:~# nano /etc/neo4j/neo4j.conf
 root@host:~#  

Find the line in the Network connector section

#dbms.default_listen_address=0.0.0.0

Uncomment this line by removing the # symbol and then press Ctrl + S and Ctrl + X to save and exit the editor.

The 0.0.0.0 value will bind Neo4j to all available IPv4 network interfaces. You can put a specific IP address or network that your servers use as a data path. You can also configure it to use IPv6 interfaces, but there are many nuances to that setting. We recommend that you read the documentation on the official website.

Configure Firewall for Remote Connections

To configure the Neo4j software for remote connections, we must configure the firewall. We restrict access so that only trusted systems can connect to it. In this case, we will use the default Ubuntu firewall, UFW. 

Next, we must check to see if the firewall is activated. If it is not active, we have to enable it.

 root@host:~# ufw enable
 Firewall is active and enabled on system startup
 root@host:~#  

Neo4j creates two network sockets when installing the software. One on port 7474 for the HTTP interface and the one for the primary protocol on port 7687. Neo4j recommends using port 7687. The command to open a port will be similar to the following command used for allowing an IPv4 address.

 ufw allow from YOUR_IP to any port 7687 proto tcp
 YOUR_IP - Use an IP here to provide access permission. If you want to allow access to the entire local network, use the following rule:
 ufw allow from 192.168.50.0/16 to any port 7687 proto tcp 

Enter your specific network range to open the port. For an IPv6 address, the command will look like this.

ufw allow from fe80::1006:f7a3:b9cc:b0cb to any port 7687 proto tcp

The above IPs are used as an example. Substitute your values and add a rule.

 root@host:~# ufw allow from 192.168.50.189 to any port 7687 proto tcp
 Rule added
 root@host:~#  

Restart Firewall

Be sure to restart your firewall.

 root@host:~# ufw reload
 Firewall reloaded
 root@host:~#  

Verify Connection

Now let’s check to see if it is working correctly.

 root@host:~# ufw status
 Status: active
 To                         Action      From
 --                         ------      ----
 7687/tcp                   ALLOW       192.168.50.189            
 root@host:~#  

And with that, we have a working Neo4j server that's ready to go and configured to allow access on port 7687.

Conclusion

We met with the Neo4j graphical database, learned how it works and why it is needed. Set up a package manager and then installed Neo4j. Next, we checked the functionality, went into it, and changed the password. We tried basic commands on how to create a table, make relationships, and set up nodes. In the end, we configured the connection to the IPs we needed and configured a firewall for security.

Avatar for Margaret Fitzgerald

About the Author: Margaret Fitzgerald

Latest Articles

How to Edit Your DNS Hosts File

Read Article

How to Edit Your DNS Hosts File

Read Article

Microsoft Exchange Server Security Update

Read Article

How to Monitor Your Server in WHM

Read Article

How to Monitor Your Server in WHM

Read Article