Neo4j in your own software: Very basic Perl hacking

In this final article in a three-part series, learn to write some Perl code to query your graph database.
515 readers like this.
An introduction to GNU Screen

Opensource.com

In the prior articles in this series, we've looked at the fundamentals of graph databases and installed and started using Neo4j, a popular open source graph database. In this final article, we'll write some Perl code to do the same things as we did in the second article and point you to some other libraries for working with Neo4j in your own programming.

If you still have your database up from the prior article, be sure and erase all the data in there with this Cypher query:

MATCH (n)
OPTIONAL MATCH (n)-[r]-()
DELETE n,r

Now that you have an empty graph, you're ready to play with Perl a bit. I've written a script that will re-create the graph. Given what you've already learned about Neo4j in the prior articles, this should be pretty straightforward. I'm using Perl 5.24 on my Debian stretch box, with Mark Jensen's fabulous CPAN module REST::Neo4p. Neo4j is installed on the same box, so it's a local connection.

#!/usr/bin/perl

use strict;
use warnings;
use REST::Neo4p;

# Connect to the database. Anonymous connections are not allowed, so give a username and password.

REST::Neo4p->connect( 'http://127.0.0.1:7474', 'neo4j', 'T0aster' );

# Create the nodes and set labels on them. I'll use the same variables as
# before, but they won't go out of scope so quickly!

my $a = REST::Neo4p::Node->new(
    {
        name           => 'Jane Doe',
        favorite_color => 'purple'
    }
)->set_labels('Person');
my $b = REST::Neo4p::Node->new( { name => 'John Doe' } )->set_labels('Person');
my $c = REST::Neo4p::Node->new(
    {
        name           => 'Mary Smith',
        favorite_color => 'red',
        dob            => '1992-11-09'
    }
)->set_labels('Person');
my $d =
  REST::Neo4p::Node->new( { name => 'Robert Roe' } )->set_labels('Person');
my $e =
  REST::Neo4p::Node->new( { name => 'Rhonda Roe' } )->set_labels('Person');
my $f = REST::Neo4p::Node->new( { name => 'Ryan Roe' } )->set_labels('Person');
my $t =
  REST::Neo4p::Node->new( { name => 'Petaluma, CA' } )->set_labels('City');
my $u = REST::Neo4p::Node->new( { name => 'Cypress, TX' } )->set_labels('City');
my $v =
  REST::Neo4p::Node->new( { name => 'Grand Prairie, TX' } )->set_labels('City');
my $w = REST::Neo4p::Node->new( { name => 'Houston, TX' } )->set_labels('City');

# Big difference here; we don't have to search out our nodes; we have them
# in scope already. While we're messing with our in-scope copy, Neo4J is
# updating the storage to match!

$a->relate_to( $b, 'MARRIAGE',
    { date => '2017-03-04', place => 'Houston, TX' } );
$d->relate_to( $e, 'MARRIAGE',
    { date => '1990-12-01', place => 'Chicago, IL' } );
$a->relate_to( $c, 'CHILD' );
$d->relate_to( $f, 'CHILD' );
$e->relate_to( $f, 'CHILD' );
$b->relate_to( $c, 'STEPCHILD' );
$a->relate_to( $v, 'BORN_IN' );
$b->relate_to( $t, 'BORN_IN' );
$c->relate_to( $f, 'DATING' );
$a->relate_to( $u, 'LIVES_IN' );
$b->relate_to( $u, 'LIVES_IN' );
$a->relate_to( $w, 'WORKS_IN' );
$a->relate_to( $d, 'FRIEND' );
$a->relate_to( $e, 'FRIEND' );

At this point, if you ran the script, you could go to your Neo4j browser and run this query:

MATCH (n)
RETURN n

...and see the same graph that you saw in the prior article. Let's examine some code snippets for querying the graph. All of these assume you're already connected to the database.

my $query = REST::Neo4p::Query->new('MATCH (n)
                                     RETURN n');
$query->execute;
while (my $result = $query->fetch) {
    my $labels = join ( ',', $result->[0]->get_labels );
    my $name = $result->[0]->get_property('name');
    print "Labels: $labels --- Name: $name\n";
}

With this query, we get back a list of all the nodes. But where are the relationships? In the browser, the database automatically added relationships to the display, if the relationship was attached to two nodes that were in the graph. In Perl, that's not the case, and you need to explore those relationship objects specifically:

my $query = REST::Neo4p::Query->new('MATCH (a:Person)-[:MARRIAGE]->(b:Person)
                                     RETURN a,b');
$query->execute;
while (my $result = $query->fetch) {
    my $name_a = $result->[0]->get_property('name');
    my $name_b = $result->[1]->get_property('name');
    print "$name_a is married to $name_b\n";
}

This gives us both of the married couples in our graph:

Jane Doe is married to John Doe
Robert Roe is married to Rhonda Roe

It's a little bit different from working in the browser interface, but you can do anything in Perl that you can in the browser.

Remember in the first article, where I said that direction of relationships doesn't have to matter, if you don't want it to? Let's change one thing in this query and see what happens. If we change the arrow in the query above to a dash, then we get:

John Doe is married to Jane Doe
Jane Doe is married to John Doe
Rhonda Roe is married to Robert Roe
Robert Roe is married to Rhonda Roe

The relationships were defined as directed, because there isn't any other way to do it in Neo4j. But in our query, we don't have to worry about that, and it still gives us the reverse result. This behavior may or may not be useful to you, but it's definitely something to be aware of when you start writing queries!

We've really just touched on the very basic beginnings of Neo4j and graph databases in this series. If Perl isn't your language of choice, there are drivers for many popular development languages already available, thanks to the thriving developer community that exists around Neo4j. You can find out more about those on the Neo4j website. Additionally, Neo4j comes equipped with a REST interface right out of the box, so any application that can use REST can use it to fetch JSON results describing the results of any Cypher query.

Graph databases power some of the largest pools of information on the planet, including Facebook, Twitter, and more. This quick look at the fundamentals gives you a chance to dip your toe in the water, and hopefully gets you thinking about how a graph could help your next big data project!

User profile image.
Ruth Holloway has been a system administrator and software developer for a long, long time, getting her professional start on a VAX 11/780, way back when. She spent a lot of her career (so far) serving the technology needs of libraries, and has been a contributor since 2008 to the Koha open source library automation suite. Ruth is currently a Perl developer and project lead at Clearbuilt.

Comments are closed.

Creative Commons LicenseThis work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License.