(Neo4j)-[:LOVES]-(Developers)
World's leading graph database, with native graph storage and processing.
Property graph model and Cypher query language makes it easy to understand.
Fast. Natural. Fun.
Test-Drive Neo4j with Cypher
Friends of Friends
Find all of Joe's second-degree friends
Joe knows Sally, and Sally knows Anna. Bob is excluded from the result because, in addition to being a 2nd-degree friend through Sally, he's also a first-degree friend.
Common Friends
Find friends in common between Joe and Sally
Joe and Sally both know Bob.
Connecting Paths
Find all paths, up to 6 degrees, between Joe and Billy
There's only one shortest path between Joe and Billy in this dataset, so that path is returned.
<?php
/**
* To install Neo4j-PHP-Client, we use Composer
*
* $ curl -sS https://getcomposer.org/installer | php
* $ php composer.phar require graphaware/neo4j-php-client
*
*/
require __DIR__.'/vendor/autoload.php';
use GraphAware\Neo4j\Client\ClientBuilder;
// change to your hostname, port, username, password
$neo4j_url = "bolt://neo4j:password@localhost";
// setup connection
$client = ClientBuilder::create()
->addConnection('default', $neo4j_url)
->build();
// setup data
$insert_query = <<<EOQ
UNWIND {pairs} as pair
MERGE (p1:Person {name:pair[0]})
MERGE (p2:Person {name:pair[1]})
MERGE (p1)-[:KNOWS]-(p2);
EOQ;
// friend data to insert
$data = [["Jim","Mike"],["Jim","Billy"],["Anna","Jim"],
["Anna","Mike"],["Sally","Anna"],["Joe","Sally"],
["Joe","Bob"],["Bob","Sally"]];
// insert data
$client->run($insert_query, ["pairs" => $data]);
// friend of friend: query
$foaf_query = <<<EOQ
MATCH (person:Person)-[:KNOWS]-(friend)-[:KNOWS]-(foaf)
WHERE person.name = {name}
AND NOT (person)-[:KNOWS]-(foaf)
RETURN foaf.name AS name
EOQ;
// friend of friend: build and execute query
$params = ['name' => 'Joe'];
$result = $client->run($foaf_query, $params);
foreach ($result->records() as $record) {
echo $record->get('name') . PHP_EOL;
}
// common friends: query
$common_friends_query = <<<EOQ
MATCH (user:Person)-[:KNOWS]-(friend)-[:KNOWS]-(foaf:Person)
WHERE user.name = {user} AND foaf.name = {foaf}
RETURN friend.name AS friend
EOQ;
// common friends: build and execute query
$params = ['user' => 'Joe', 'foaf' => 'Sally'];
$result = $client->run($common_friends_query, $params);
foreach ($result->records() as $record) {
echo $record->get('friend') . PHP_EOL;
}
// connecting paths: query
$connecting_paths_query = <<<EOQ
MATCH path = shortestPath((p1:Person)-[:KNOWS*..6]-(p2:Person))
WHERE p1.name = {name1} AND p2.name = {name2}
RETURN [n IN nodes(path) | n.name] as names
EOQ;
// connecting paths: build and execute query
$params = ['name1' => 'Joe', 'name2' => 'Billy'];
$result = $client->run($connecting_paths_query, $params);
foreach ($result->records() as $record) {
print_r($record->get('names'));
}
Downloading and Installing PHP
- Install Composer from within web directory:
$ curl -sS https://getcomposer.org/installer | php
- Install Neo4j-PHP-Client from within web directory:
$ php composer.phar require graphaware/neo4j-php-client
- Copy and paste code at left into php file and run
import org.neo4j.driver.v1.*;
import static org.neo4j.driver.v1.Values.parameters;
import java.util.List;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonMap;
public class Social {
public static void main(String...args) {
Config noSSL = Config.build().withEncryptionLevel(Config.EncryptionLevel.NONE).toConfig();
Driver driver = GraphDatabase.driver("bolt://localhost",AuthTokens.basic("neo4j","test"),noSSL); // <password>
try (Session session = driver.session()) {
List data =
asList(asList("Jim","Mike"),asList("Jim","Billy"),asList("Anna","Jim"),
asList("Anna","Mike"),asList("Sally","Anna"),asList("Joe","Sally"),
asList("Joe","Bob"),asList("Bob","Sally"));
String insertQuery = "UNWIND {pairs} as pair " +
"MERGE (p1:Person {name:pair[0]}) " +
"MERGE (p2:Person {name:pair[1]}) " +
"MERGE (p1)-[:KNOWS]-(p2);";
session.run(insertQuery,singletonMap("pairs",data)).consume();
StatementResult result;
String foafQuery =
" MATCH (person:Person)-[:KNOWS]-(friend)-[:KNOWS]-(foaf) "+
" WHERE person.name = {name} " +
" AND NOT (person)-[:KNOWS]-(foaf) " +
" RETURN foaf.name AS name ";
result = session.run(foafQuery, parameters("name","Joe"));
while (result.hasNext()) System.out.println(result.next().get("name"));
String commonFriendsQuery =
"MATCH (user:Person)-[:KNOWS]-(friend)-[:KNOWS]-(foaf:Person) " +
" WHERE user.name = {from} AND foaf.name = {to} " +
" RETURN friend.name AS friend";
result = session.run(commonFriendsQuery, parameters("from","Joe","to","Sally"));
while (result.hasNext()) System.out.println(result.next().get("friend"));
String connectingPathsQuery =
"MATCH path = shortestPath((p1:Person)-[:KNOWS*..6]-(p2:Person)) " +
" WHERE p1.name = {from} AND p2.name = {to} " +
" RETURN [n IN nodes(path) | n.name] as names";
result = session.run(connectingPathsQuery, parameters("from","Joe","to","Billy"));
while (result.hasNext()) System.out.println(result.next().get("names"));
}
}
}
Downloading and Installing Java
- Download Neo4j Driver
- Copy and paste code at left into
Social.java
- Run
javac -cp neo4j-java-driver-1.0.0.jar Social.java
- Run
java -cp neo4j-java-driver-1.0.0.jar:. Social
# pip install neo4j-driver
from neo4j.v1 import GraphDatabase, basic_auth
driver = GraphDatabase.driver("bolt://localhost", auth=basic_auth("neo4j", "<password>"))
session = driver.session()
# Insert data
insert_query = '''
UNWIND {pairs} as pair
MERGE (p1:Person {name:pair[0]})
MERGE (p2:Person {name:pair[1]})
MERGE (p1)-[:KNOWS]-(p2);
'''
data = [["Jim","Mike"],["Jim","Billy"],["Anna","Jim"],
["Anna","Mike"],["Sally","Anna"],["Joe","Sally"],
["Joe","Bob"],["Bob","Sally"]]
session.run(insert_query, parameters={"pairs": data})
# Friends of a friend
foaf_query = '''
MATCH (person:Person)-[:KNOWS]-(friend)-[:KNOWS]-(foaf)
WHERE person.name = {name}
AND NOT (person)-[:KNOWS]-(foaf)
RETURN foaf.name AS name
'''
results = session.run(foaf_query, parameters={"name": "Joe"})
for record in results:
print(record["name"])
# Common friends
common_friends_query = """
MATCH (user:Person)-[:KNOWS]-(friend)-[:KNOWS]-(foaf:Person)
WHERE user.name = {user} AND foaf.name = {foaf}
RETURN friend.name AS friend
"""
results = session.run(common_friends_query, parameters={"user": "Joe", "foaf": "Sally"})
for record in results:
print(record["friend"])
# Connecting paths
connecting_paths_query = """
MATCH path = shortestPath((p1:Person)-[:KNOWS*..6]-(p2:Person))
WHERE p1.name = {name1} AND p2.name = {name2}
RETURN path
"""
results = session.run(connecting_paths_query, parameters={"name1": "Joe", "name2": "Billy"})
for record in results:
print (record["path"])
session.close()
Downloading and Installing Python
- Install neo4j-python-driver using pip:
$ pip install neo4j-driver
- Copy and paste code at left into py file and run
# gem install neo4j-core
require 'neo4j-core'
require 'neo4j/core/cypher_session/adaptors/bolt'
adaptor = Neo4j::Core::CypherSession::Adaptors::Bolt.new('bolt://neo4j:password@localhost:7687', wrap_level: :proc)
session = Neo4j::Core::CypherSession.new(adaptor)
# Insert data
insert_query = <<QUERY
UNWIND {pairs} as pair
MERGE (p1:Person {name:pair[0]})
MERGE (p2:Person {name:pair[1]})
MERGE (p1)-[:KNOWS]-(p2)
QUERY
data = [['Jim', 'Mike'], ['Jim', 'Billy'], ['Anna', 'Jim'],
['Anna', 'Mike'], ['Sally', 'Anna'], ['Joe', 'Sally'],
['Joe', 'Bob'], ['Bob', 'Sally']]
session.query(insert_query, pairs: data)
# Friends of a friend
foaf_query = <<QUERY
MATCH (person:Person)-[:KNOWS]-(friend)-[:KNOWS]-(foaf)
WHERE person.name = {name}
AND NOT (person)-[:KNOWS]-(foaf)
RETURN foaf.name AS name
QUERY
response = session.query(foaf_query, name: 'Joe')
puts response.map(&:name)
puts '---------------------'
# Common friends
common_friends_query = <<QUERY
MATCH (user:Person)-[:KNOWS]-(friend)-[:KNOWS]-(foaf:Person)
WHERE user.name = {user} AND foaf.name = {foaf}
RETURN friend.name AS friend
QUERY
response = session.query(common_friends_query, user: 'Joe', foaf: 'Sally')
puts response.map(&:friend)
puts '---------------------'
# Connecting paths
connecting_paths_query = <<QUERY
MATCH path = shortestPath((p1:Person)-[:KNOWS*..6]-(p2:Person))
WHERE p1.name = {name1} AND p2.name = {name2}
RETURN nodes(path) AS nodes
QUERY
response = session.query(connecting_paths_query, name1: 'Joe', name2: 'Billy')
puts response.first.nodes.map {|node| node.properties[:name] }
puts '---------------------'
# ActiveNode models:
require 'neo4j'
Neo4j::ActiveBase.current_session = session
session.query('CREATE CONSTRAINT ON (p:Person) ASSERT p.uuid IS UNIQUE')
class Person
include Neo4j::ActiveNode
property :name
has_many :in, :known_people, type: :KNOWS, model_class: :Person
end
puts Person.where(name: 'Joe').query_as(:p1).match('path = shortestPath((p1:Person)-[:KNOWS*..6]-(p2:Person))').where(p2: {name: 'Billy'}).pluck('nodes(path)').first.map(&:name)
Downloading and Installing Ruby
- Install Neo4j.rb using gem:
$ gem install neo4j-core
- Copy and paste code at left into rb file and run
using System;
using System.Collections.Generic;
using System.Linq;
using Neo4jClient;
using Neo4jClient.Cypher;
using Newtonsoft.Json;
//Use this for Console Apps
internal class Program
{
private static void Main(string[] args)
{
var s = new Social();
s.Setup();
var friendsOfFriends = s.FriendsOfAFriend(new Person {Name = "Joe"});
Console.WriteLine($"Joe's friends (of friends)");
foreach (var fof in friendsOfFriends)
{
Console.WriteLine($"\t{fof.Name}");
}
Console.WriteLine();
var commonFriends = s.CommonFriends(new Person {Name = "Joe"}, new Person {Name = "Sally"});
Console.WriteLine("Joe and Sally's common friends");
foreach (var friend in commonFriends)
{
Console.WriteLine($"\t{friend.Name}");
}
Console.WriteLine();
var connectingNames = s.ConnectingPaths(new Person {Name = "Joe"}, new Person {Name = "Billy"});
Console.WriteLine("Path to Billy");
foreach (var name in connectingNames)
{
Console.WriteLine($"\t{name}");
}
}
}
public class Social
{
private readonly IGraphClient _graphClient;
public Social()
{
_graphClient = new GraphClient(new Uri("http://localhost:7474/db/data"), "user", "pass");
_graphClient.Connect();
}
public void Setup()
{
var people = new List<string[]>
{
new[] {"Jim", "Mike"}, new[] {"Jim", "Billy"}, new[] {"Anna", "Jim"},
new[] {"Anna", "Mike"}, new[] {"Sally", "Anna"}, new[] {"Joe", "Sally"},
new[] {"Joe", "Bob"}, new[] {"Bob", "Sally"}
};
_graphClient.Cypher
.Unwind(people, "pair")
.Merge("(u1:Person { name: pair[0] })")
.Merge("(u2:Person { name: pair[1] })")
.Merge("(u1)-[:KNOWS]->(u2)")
.ExecuteWithoutResults();
}
public IEnumerable<Person> FriendsOfAFriend(Person person)
{
/*
MATCH (p:Person)-[:KNOWS]-(friend)-[:KNOWS]-(foaf)
WHERE p.name = {p1}
AND NOT (p)-[:KNOWS]-(foaf)
RETURN foaf
*/
var query = _graphClient.Cypher
.Match("(p:Person)-[:KNOWS]-(friend)-[:KNOWS]-(foaf)")
.Where((Person p) => p.Name == person.Name)
.AndWhere("NOT (p)-[:KNOWS]-(foaf)")
.Return(foaf => foaf.As<Person>());
return query.Results;
}
public IEnumerable<Person> CommonFriends(Person person1, Person person2)
{
/*
MATCH (p:Person)-[:KNOWS]-(friend)-[:KNOWS]-(foaf:Person)
WHERE p.name = {p1}
AND foaf.name = {p2}
RETURN friend
*/
var query = _graphClient.Cypher
.Match("(p:Person)-[:KNOWS]-(friend)-[:KNOWS]-(foaf:Person)")
.Where((Person p) => p.Name == person1.Name)
.AndWhere((Person foaf) => foaf.Name == person2.Name)
.Return(friend => friend.As<Person>());
return query.Results;
}
public IEnumerable<string> ConnectingPaths(Person person1, Person person2)
{
/*
MATCH path = shortestPath((p1:Person)-[:KNOWS*..6]-(p2:Person))
WHERE p1.name = {p1}
AND p2.name = {p2}
RETURN [n IN nodes(path) | n.name]
*/
var query = _graphClient.Cypher
.Match("path = shortestPath((p1:Person)-[:KNOWS*..6]-(p2:Person))")
.Where((Person p1) => p1.Name == person1.Name)
.AndWhere((Person p2) => p2.Name == person2.Name)
.Return(() => Return.As<IEnumerable<string>>("[n IN nodes(path) | n.name]"));
return query.Results.Single();
}
}
public class Person
{
//This is required to make the serializer treat the 'C#' naming style as 'Java' in the DB
[JsonProperty("name")]
public string Name { get; set; }
}
Downloading and Installing C#
- Install NuGet
- Run the NuGet Package Manager Console
- Install the Neo4jClient package:
PM> Install-Package Neo4jClient
- Copy and paste code at left into your .NET project, build, and run
// npm install --save neo4j
var neo4j = require('neo4j');
var db = new neo4j.GraphDatabase('http://neo4j:<password>@localhost:7474');
var insertQuery =
"UNWIND {pairs} as pair \
MERGE (p1:Person {name:pair[0]}) \
MERGE (p2:Person {name:pair[1]}) \
MERGE (p1)-[:KNOWS]-(p2)";
var foafQuery =
"MATCH (person:Person)-[:KNOWS]-(friend)-[:KNOWS]-(foaf) \
WHERE person.name = {name} \
AND NOT (person)-[:KNOWS]-(foaf) \
RETURN foaf.name AS name";
var commonFriendsQuery =
"MATCH (user:Person)-[:KNOWS]-(friend)-[:KNOWS]-(foaf:Person) \
WHERE user.name = {name1} AND foaf.name = {name2} \
RETURN friend.name AS friend";
var connectingPathsQuery =
"MATCH path = shortestPath((p1:Person)-[:KNOWS*..6]-(p2:Person)) \
WHERE p1.name = {name1} AND p2.name = {name2} \
RETURN [n IN nodes(path) | n.name] as names";
var data = [["Jim","Mike"],["Jim","Billy"],["Anna","Jim"],
["Anna","Mike"],["Sally","Anna"],["Joe","Sally"],
["Joe","Bob"],["Bob","Sally"]];
function query(query, params, column, cb) {
function callback(err, results) {
if (err || !results) throw err;
if (!column) cb(results)
else results.forEach(function(row) { cb(row[column]) });
};
db.cypher({ query: query, params: params}, callback);
}
query(insertQuery, {pairs: data}, null, function () {
query(foafQuery, {name: "Joe"},"name", console.log);
query(commonFriendsQuery, {name1: "Joe", name2:"Sally"},"friend",console.log);
query(connectingPathsQuery, {name1: "Joe", name2:"Billy"}, "names",
function(res) { console.log(res)});
});
Downloading and Installing JavaScript
- Install neo4j-driver using npm:
$ npm install --save neo4j-driver
- Copy and paste code at left into js file and run
Impact Analysis
Find all services that depend on Server 1. These would be impacted by an outage of that server.
Only Webserver VM depends on Server 1. Because we're looking at variable length paths of DEPENDS_ON relationships, we're also able to determine that Public Website would be impacted by an outage of Server 1.
Dependency Analysis
Find all services which the Public Website depends on to be operational.
The Public Website depends on the Database VM and the Webserver VM, which each depend on other services.
Statistics
Find the most depended-upon component
As is the case in many data centers, the SAN is the most depended upon component. All six other services directly or indirectly depend on it.
<?php
/**
* To install Neo4j-PHP-Client, we use Composer
*
* $ curl -sS https://getcomposer.org/installer | php
* $ php composer.phar require graphaware/neo4j-php-client
*
*/
require __DIR__.'/vendor/autoload.php';
use GraphAware\Neo4j\Client\ClientBuilder;
// change to your hostname, port, username, password
$neo4j_url = "bolt://neo4j:password@localhost";
// setup connection
$client = ClientBuilder::create()
->addConnection('default', $neo4j_url)
->build();
// setup data
$insert_query = <<<EOQ
UNWIND {pairs} as pair
MERGE (s1:Service {name:pair[0]})
MERGE (s2:Service {name:pair[1]})
MERGE (s1)-[:DEPENDS_ON]-(s2);
EOQ;
// network data to insert
$data = [["CRM","Database VM"],["Database VM","Server 2"],["Server 2","SAN"],
["Server 1","SAN"],["Webserver VM","Server 1"],["Public Website","Webserver VM"],
["Public Website","Database VM"]];
// insert data
$client->run($insert_query, ["pairs" => $data]);
// impact analysis: query
$impact_query = <<<EOQ
MATCH (n:Service)<-[:DEPENDS_ON*]-(dependent:Service)
WHERE n.name = {service}
RETURN dependent
EOQ;
// impact analysis: build and execute query
$params = ['service' => 'Server 1'];
$result = $client->run($impact_query, $params);
echo "Services impacted by Server 1 outage:" . PHP_EOL;
foreach ($result->records() as $record) {
echo "\t" . $record->get('dependent')->value('name') . PHP_EOL;
}
// dependency analysis: query
$dependency_analysis_query = <<<EOQ
MATCH (n:Service)-[:DEPENDS_ON*]->(downstream:Service)
WHERE n.name = {service}
RETURN downstream
EOQ;
// dependency analysis: build and execute query
$params = ['service' => 'Public Website'];
$result = $client->run($dependency_analysis_query, $params);
echo "The following services depend upon Public Website, either directly or indirectly:" . PHP_EOL;
foreach ($result->records() as $record) {
echo "\t" . $record->get('downstream')->value('name') . PHP_EOL;
}
echo PHP_EOL;
// statistics: query
$statistics_query = <<<EOQ
MATCH (n:Service)<-[:DEPENDS_ON*]-(dependent:Service)
RETURN n, count(DISTINCT dependent) AS dependents
ORDER BY dependents DESC
LIMIT 1
EOQ;
// statistics: build and execute query
$result = $client->run($statistics_query);
foreach ($result->records() as $record) {
echo sprintf(
'%s is the most depended-upon component with %d dependents',
$record->get('n')->value('name'),
$record->get('dependents')
) . PHP_EOL;
}
Downloading and Installing PHP
- Install Composer from within web directory:
$ curl -sS https://getcomposer.org/installer | php
- Install Neo4j-PHP-Client from within web directory:
$ php composer.phar require graphaware/neo4j-php-client
- Copy and paste code at left into php file and run
// javac -cp neo4j-java-driver*.jar:. Network.java
// java -cp neo4j-java-driver*.jar:. Network
import org.neo4j.driver.v1.*;
import static org.neo4j.driver.v1.Values.parameters;
import java.util.List;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonMap;
public class Network {
public static void main(String...args) {
Config noSSL = Config.build().withEncryptionLevel(Config.EncryptionLevel.NONE).toConfig();
Driver driver = GraphDatabase.driver("bolt://localhost",AuthTokens.basic("neo4j","test"),noSSL); // <password>
try (Session session = driver.session()) {
List data =
asList(asList("CRM", "Database VM"), asList("Database VM", "Server 2"),
asList("Server 2", "SAN"), asList("Server 1", "SAN"), asList("Webserver VM", "Server 1"),
asList("Public Website", "Webserver VM"), asList("Public Website", "Webserver VM"));
String insertQuery = "UNWIND {pairs} AS pair " +
"MERGE (s1:Service {name: pair[0]}) " +
"MERGE (s2:Service {name: pair[1]}) " +
"MERGE (s1)-[:DEPENDS_ON]->(s2) ";
session.run(insertQuery,singletonMap("pairs",data)).consume();
StatementResult result;
String impactQuery =
"MATCH (n:Service)<-[:DEPENDS_ON*]-(dependent:Service) " +
"WHERE n.name = {name} " +
"RETURN collect(dependent.name) AS dependent_services";
result = session.run(impactQuery, parameters("name","Server 1"));
while (result.hasNext()) System.out.println(result.next().get("dependent_services"));
String dependencyQuery =
"MATCH (n:Service)-[:DEPENDS_ON*]->(downstream:Service) " +
"WHERE n.name = {name} " +
"RETURN collect(downstream.name) AS downstream_services ";
result = session.run(dependencyQuery, parameters("name","Public Website"));
while (result.hasNext()) System.out.println(result.next().get("downstream_services"));
String statsQuery =
"MATCH (n:Service)<-[:DEPENDS_ON*]-(dependent:Service) " +
"RETURN n.name AS service, count(DISTINCT dependent) AS dependents " +
"ORDER BY dependents DESC " +
"LIMIT 1";
result = session.run(statsQuery, parameters());
while (result.hasNext()) {
Record record = result.next();
System.out.printf("%s has %s dependents.%n",record.get("service"),record.get("dependents"));
}
}
}
}
Downloading and Installing Java
- Download Neo4j Driver
- Copy and paste code at left into
Network.java
- Run
javac -cp neo4j-java-driver-1.0.0.jar Network.java
- Run
java -cp neo4j-java-driver-1.0.0.jar:. Network
# npm install neo4j-driver
from neo4j.v1 import GraphDatabase, basic_auth
driver = GraphDatabase.driver("bolt://localhost", auth=basic_auth("neo4j", "<password>"))
session = driver.session()
# Insert data
insert_query = '''
UNWIND {pairs} AS pair
MERGE (s1:Service {name: pair[0]})
MERGE (s2:Service {name: pair[1]})
MERGE (s1)-[:DEPENDS_ON]->(s2);
'''
data = [["CRM", "Database VM"], ["Database VM", "Server 2"],
["Server 2", "SAN"], ["Server 1", "SAN"], ["Webserver VM", "Server 1"],
["Public Website", "Webserver VM"], ["Public Website", "Webserver VM"]]
session.run(insert_query, parameters={"pairs": data})
# Impact Analysis
impact_query = '''
MATCH (n:Service)<-[:DEPENDS_ON*]-(dependent:Service)
WHERE n.name = {service_name}
RETURN collect(dependent.name) AS dependent_services
'''
results = session.run(impact_query, parameters={"service_name": "Server 1"})
for record in results:
print(record)
# Dependency Analysis
dependency_query = """
MATCH (n:Service)-[:DEPENDS_ON*]->(downstream:Service)
WHERE n.name = {service_name}
RETURN collect(downstream.name) AS downstream_services
"""
results = session.run(dependency_query, {"service_name": "Public Website"})
for record in results:
print(record)
# Statistics
stats_query = """
MATCH (n:Service)<-[:DEPENDS_ON*]-(dependent:Service)
RETURN n.name AS service, count(DISTINCT dependent) AS dependents
ORDER BY dependents DESC
LIMIT 1
"""
results = session.run(stats_query)
for record in results:
print(record)
session.close()
Downloading and Installing Python
- Install neo4j-python-driver using pip:
$ pip install neo4j-driver
- Copy and paste code at left into py file and run
# gem install neo4j-core
require 'neo4j-core'
require 'neo4j/core/cypher_session/adaptors/bolt'
adaptor = Neo4j::Core::CypherSession::Adaptors::Bolt.new('bolt://neo4j:password@localhost:7687', wrap_level: :proc)
session = Neo4j::Core::CypherSession.new(adaptor)
# Insert data
insert_query = <<QUERY
UNWIND {pairs} AS pair
MERGE (s1:Service {name: pair[0]})
MERGE (s2:Service {name: pair[1]})
MERGE (s1)-[:DEPENDS_ON]->(s2)
QUERY
data = [['CRM', 'Database VM'], ['Database VM', 'Server 2'],
['Server 2', 'SAN'], ['Server 1', 'SAN'], ['Webserver VM', 'Server 1'],
['Public Website', 'Webserver VM'], ['Public Website', 'Webserver VM']]
session.query(insert_query, pairs: data)
# Impact Analysis
impact_query = <<QUERY
MATCH (n:Service)<-[:DEPENDS_ON*]-(dependent:Service)
WHERE n.name = {service_name}
RETURN dependent.name AS dependent_service
QUERY
response = session.query(impact_query, service_name: 'Server 1')
puts 'Dependent services: '
puts response.map(&:dependent_service)
puts '--------------------'
# Dependency Analysis
dependency_query = <<QUERY
MATCH (n:Service)-[:DEPENDS_ON*]->(downstream:Service)
WHERE n.name = {service_name}
RETURN downstream.name AS downstream_service
QUERY
response = session.query(dependency_query, service_name: 'Public Website')
puts 'Downstream services: '
puts response.map(&:downstream_service)
puts '---------------------'
# Statistics
stats_query = <<QUERY
MATCH (n:Service)<-[:DEPENDS_ON*]-(dependent:Service)
RETURN n.name AS service, count(DISTINCT dependent) AS dependents
ORDER BY dependents DESC
QUERY
puts 'Service with most dependent services: '
response = session.query(stats_query)
puts response.map {|row| "#{row.service} with #{row.dependents} dependents" }
puts '---------------------'
# ActiveNode models:
require 'neo4j'
Neo4j::ActiveBase.current_session = session
session.query('CREATE CONSTRAINT ON (s:Service) ASSERT s.uuid IS UNIQUE')
class Service
include Neo4j::ActiveNode
property :name
has_many :in, :dependencies, type: :DEPENDS_ON, model_class: :Service
end
puts 'Service with most dependent services: '
results = Service.as(:n).dependencies(:dependent, nil, rel_length: :any).order('dependents DESC').pluck('n.name', 'count(DISTINCT dependent) AS dependents')
puts results.map {|service, dependents| "#{service} with #{dependents} dependents" }
Downloading and Installing Ruby
- Install Neo4j.rb using gem:
$ gem install neo4j-core
- Copy and paste code at left into rb file and run
using System;
using System.Collections.Generic;
using System.Linq;
using Neo4j.Driver.V1;
class NetworkManagement
{
public static void NetworkManagementMain(string[] args)
{
using (var driver = GraphDatabase.Driver(new Uri("bolt://localhost:7687"), AuthTokens.Basic("neo4j", "neo4j")))
{
var data = new List<string[]>
{
new[] {"CRM", "Database VM"},
new[] {"Database VM", "Server 2"},
new[] {"Server 2", "SAN"},
new[] {"Server 1", "SAN"},
new[] {"Webserver VM", "Server 1"},
new[] {"Public Website", "Webserver VM"},
new[] {"Public Website", "Webserver VM"}
};
const string loadCypher =
"UNWIND {servers} AS row MERGE(s1: Service { name: row[0]}) MERGE(s2: Service { name: row[1]}) MERGE(s1) -[:DEPENDS_ON]->(s2)";
using (var session = driver.Session())
{
var result = session.Run(loadCypher, new {servers = data});
result.ToList();
}
//Impact Analysis
//Find all upstreams impacted by outage of Server 1.
using (var session = driver.Session())
{
var result = session.Run(
"MATCH (n:Service)<-[:DEPENDS_ON *]-(dependent:Service) " +
"WHERE n.name = 'Server 1' " +
"RETURN dependent.name AS name");
Console.WriteLine("Impacted by outage of Server 1");
foreach (var record in result)
{
Console.WriteLine($"\t{record["name"]}");
}
}
//Dependency Analysis
//Find all dependencies of the public website.
using (var session = driver.Session())
{
var result = session.Run(
"MATCH (n:Service)-[:DEPENDS_ON *]->(downstream) " +
"WHERE n.name = 'Public Website' " +
"RETURN downstream.name AS name");
Console.WriteLine("Dependencies of Public Website");
foreach (var record in result)
{
Console.WriteLine($"\t{record["name"]}");
}
}
//Statistics
//Find the most depended-upon component.
using (var session = driver.Session())
{
var result = session.Run(
"MATCH (n:Service)<-[:DEPENDS_ON*]-(dependent:Service) " +
"RETURN n.name AS service, count(DISTINCT dependent) AS dependents " +
"ORDER BY dependents DESC " +
"LIMIT 1"
);
Console.WriteLine($"Most depended-upon component is {result.Single()["service"].As<string>()}");
}
}
}
}
Downloading and Installing C#
- Install NuGet
- Run the NuGet Package Manager Console
- Install the Neo4jClient package:
PM> Install-Package Neo4jClient
- Copy and paste code at left into your .NET project, build, and run
- This sample uses the Cypher LOAD CSV syntax to load data from a CSV file. Copy and paste CSV content in 2nd comment in source code at left into c:/temp/services.csv
- Copy and paste code at left into your .NET project, build, and run
// npm install neo4j-driver
var neo4j = require('neo4j-driver').v1;
var driver = neo4j.driver("bolt://localhost", neo4j.auth.basic("neo4j", "<password>"));
var session = driver.session();
var queryCount = 0;
var insertQuery =
"UNWIND {pairs} AS pair \
MERGE (s1:Service {name: pair[0]}) \
MERGE (s2:Service {name: pair[1]}) \
MERGE (s1)-[:DEPENDS_ON]->(s2);";
var impactQuery =
"MATCH (n:Service)<-[:DEPENDS_ON*]-(dependent:Service) \
WHERE n.name = {service_name} \
RETURN collect(dependent.name) AS dependent_services";
var dependencyQuery =
"MATCH (n:Service)-[:DEPENDS_ON*]->(downstream:Service) \
WHERE n.name = {service_name} \
RETURN collect(downstream.name) AS downstream_services";
var statsQuery =
"MATCH (n:Service)<-[:DEPENDS_ON*]-(dependent:Service) \
RETURN n.name AS service, count(DISTINCT dependent) AS dependents \
ORDER BY dependents DESC \
LIMIT 1";
var data =
[["CRM", "Database VM"], ["Database VM", "Server 2"],
["Server 2", "SAN"], ["Server 1", "SAN"], ["Webserver VM", "Server 1"],
["Public Website", "Webserver VM"], ["Public Website", "Webserver VM"]];
function query(query, params, message, column) {
session
.run(query, params)
.then(function(result) {
console.log(message);
result.records.forEach(function(record) {
if (column === 'dependents') {
console.log(record.get(column).toInt());
} else {
console.log(record.get(column));
}
});
queryCount += 1;
if (queryCount > 2) {
session.close();
process.exit();
}
})
.catch(function(error){
console.log(error);
});
}
session
.run(insertQuery, {pairs: data})
.then(function(result) {
query(impactQuery, {service_name: "Server 1"}, "Dependent services: ", "dependent_services");
query(dependencyQuery, {service_name: "Public Website"}, "Downstream services: ", "downstream_services");
query(statsQuery, {}, "Dependents: ", "dependents");
})
.catch(function(error) {
console.log(error);
});
Downloading and Installing JavaScript
- Install neo4j-driver using npm:
$ npm install --save neo4j-driver
- Copy and paste code at left into js file and run
Transitive Closure
Given suspicions about Hank, find related information to investigate.
Hank shares an account with Abby. Abby shares a SSN with Sophie and Max. Given that we suspect Hank may be involved in fraudulent activity, we can flag the Cayman account, Sophie, and Abby as possible fraudulent entities.
Investigation Targeting
Fraud rings often share fraudulent identifying information. Any person with connections to more than two entities in the graph are suspicious. Find large cliques to investigate further.
Sophie, Max and Abby all share a SSN, which is suspicious. Hank is also suspicious because he is sharing an account with Abby.
Fast Insights
Given that we've identified SSN 993-63-2634 as suspcious, find all associated accounts.
We see that the Cayman account #863 is the only account where a Person using this SSN owns the account.
<?php
/**
* To install Neo4j-PHP-Client, we use Composer
*
* $ curl -sS https://getcomposer.org/installer | php
* $ php composer.phar require graphaware/neo4j-php-client
*
*/
require __DIR__.'/vendor/autoload.php';
use GraphAware\Neo4j\Client\ClientBuilder;
// change to your hostname, port, username, password
$neo4j_url = "bolt://neo4j:password@localhost";
// setup connection
$client = ClientBuilder::create()
->addConnection('default', $neo4j_url)
->build();
// setup data
$insert_query = <<<EOQ
CREATE (hank:Person {name:'Hank'}),
(abby:Person {name:'Abby'}),
(max:Person {name:'Max'}),
(sophie:Person {name: 'Sophie'}),
(jane:Person {name: 'Jane'}),
(bill:Person {name: 'Bill'}),
(ssn993632634:SSN {number: 993632634}),
(ssn123456789:SSN {number: 123456789}),
(ssn523252364:SSN {number: 523252364}),
(chase:Account {bank: 'Chase', number: 1523}),
(bofa:Account {bank: 'Bank of America', number: 4634}),
(cayman:Account {bank: 'Cayman', number: 863}),
(bill)-[:HAS_SSN]->(ssn523252364),
(bill)-[:HAS_ACCOUNT]->(bofa),
(jane)-[:HAS_SSN]->(ssn123456789),
(jane)-[:HAS_ACCOUNT]->(chase),
(hank)-[:HAS_ACCOUNT]->(cayman),
(abby)-[:HAS_ACCOUNT]->(cayman),
(abby)-[:HAS_SSN]->(ssn993632634),
(sophie)-[:HAS_SSN]->(ssn993632634),
(max)-[:HAS_SSN]->(ssn993632634)
EOQ;
// insert data
$client->run($insert_query);
// transitive closure: query
$transitive_query = <<<EOQ
MATCH (n:Person)-[*]-(o)
WHERE n.name = {name}
RETURN labels(o), o
EOQ;
// transitive closure: build and execute query
$params = ['name' => 'Hank'];
$result = $client->run($transitive_query, $params);
foreach ($result->records() as $record) {
print_r($record->values());
}
print "\n";
// investigation targeting: query
$investigation_targeting_query = <<<EOQ
MATCH (n:Person)-[*]-(o)
WITH n, count(DISTINCT o) AS size
WHERE size > 2
RETURN n
EOQ;
// investigation targeting: build and execute query
$result = $client->run($investigation_targeting_query);
echo "The following people are suspicious:" . PHP_EOL;
foreach ($result->records() as $record) {
echo $record->get('n')->value('name') . PHP_EOL;
}
// fast insights: query
$fast_insights_query = <<<EOQ
MATCH (ssn:SSN)<-[:HAS_SSN]-(:Person)-[:HAS_ACCOUNT]->(acct:Account)
WHERE ssn.number = {ssn}
RETURN acct
EOQ;
// fast insights: build and execute query
$params = ['ssn' => 993632634];
$result = $client->run($fast_insights_query, $params);
echo "Accounts owned by this SSN:" . PHP_EOL;
foreach ($result->records() as $record) {
echo "\t" . sprintf('%s@%s', $record->get('acct')->value('number'), $record->get('acct')->value('bank')) . PHP_EOL;
}
Downloading and Installing PHP
- Install Composer from within web directory:
$ curl -sS https://getcomposer.org/installer | php
- Install Neo4j-PHP-Client from within web directory:
$ php composer.phar require graphaware/neo4j-php-client
- Copy and paste code at left into php file and run
// javac -cp neo4j-java-driver*.jar:. Fraud.java
// java -cp neo4j-java-driver*.jar:. Fraud
import org.neo4j.driver.v1.*;
import static org.neo4j.driver.v1.Values.parameters;
import java.util.List;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonMap;
public class Fraud {
public static void main(String...args) {
Config noSSL = Config.build().withEncryptionLevel(Config.EncryptionLevel.NONE).toConfig();
Driver driver = GraphDatabase.driver("bolt://localhost",AuthTokens.basic("neo4j","test"),noSSL); // <password>
try (Session session = driver.session()) {
String insertQuery =
"CREATE (hank:Person {name:'Hank'})," +
"(abby:Person {name:'Abby'})," +
"(max:Person {name:'Max'})," +
"(sophie:Person {name: 'Sophie'})," +
"(jane:Person {name: 'Jane'})," +
"(bill:Person {name: 'Bill'})," +
"(ssn993632634:SSN {number: 993632634})," +
"(ssn123456789:SSN {number: 123456789})," +
"(ssn523252364:SSN {number: 523252364})," +
"(chase:Account {bank: 'Chase', number: 1523})," +
"(bofa:Account {bank: 'Bank of America', number: 4634})," +
"(cayman:Account {bank: 'Cayman', number: 863})," +
"(bill)-[:HAS_SSN]->(ssn523252364)," +
"(bill)-[:HAS_ACCOUNT]->(bofa)," +
"(jane)-[:HAS_SSN]->(ssn123456789)," +
"(jane)-[:HAS_ACCOUNT]->(chase)," +
"(hank)-[:HAS_ACCOUNT]->(cayman)," +
"(abby)-[:HAS_ACCOUNT]->(cayman)," +
"(abby)-[:HAS_SSN]->(ssn993632634)," +
"(sophie)-[:HAS_SSN]->(ssn993632634)," +
"(max)-[:HAS_SSN]->(ssn993632634)";
session.run(insertQuery,parameters()).consume();
StatementResult result;
String transitiveQuery =
" MATCH (n:Person)-[*]-(o) " +
" WHERE n.name = {name} "+
" RETURN o ";
result = session.run(transitiveQuery, parameters("name","Hank"));
while (result.hasNext()) System.out.println(result.next().get("o").asMap());
String targetingQuery =
"MATCH (n:Person)-[*]-(o) " +
" WITH n, count(DISTINCT o) AS size " +
" WHERE size > 2 " +
" RETURN n";
result = session.run(targetingQuery, parameters());
while (result.hasNext()) System.out.println(result.next().get("n").asMap());
String insightsQuery =
"MATCH (ssn:SSN)<-[:HAS_SSN]-(:Person)-[:HAS_ACCOUNT]->(acct:Account) "+
" WHERE ssn.number = {ssn} "+
" RETURN acct";
result = session.run(insightsQuery, parameters("ssn",993632634));
while (result.hasNext()) System.out.println(result.next().get("acct").asMap());
}
}
}
Downloading and Installing Java
- Download Neo4j Driver
- Copy and paste code at left into
Fraud.java
- Run
javac -cp neo4j-java-driver-1.0.0.jar Fraud.java
- Run
java -cp neo4j-java-driver-1.0.0.jar:. Fraud
# pip install neo4j-driver
from neo4j.v1 import GraphDatabase, basic_auth
driver = GraphDatabase.driver("bolt://localhost", auth=basic_auth("neo4j", "<password>"))
session = driver.session()
# Insert data
insert_query = '''
CREATE (hank:Person {name:"Hank"}),
(abby:Person {name:"Abby"}),
(max:Person {name:"Max"}),
(sophie:Person {name: "Sophie"}),
(jane:Person {name: "Jane"}),
(bill:Person {name: "Bill"}),
(ssn993632634:SSN {number: 993632634}),
(ssn123456789:SSN {number: 123456789}),
(ssn523252364:SSN {number: 523252364}),
(chase:Account {bank: "Chase", number: 1523}),
(bofa:Account {bank: "Bank of America", number: 4634}),
(cayman:Account {bank: "Cayman", number: 863}),
(bill)-[:HAS_SSN]->(ssn523252364),
(bill)-[:HAS_ACCOUNT]->(bofa),
(jane)-[:HAS_SSN]->(ssn123456789),
(jane)-[:HAS_ACCOUNT]->(chase),
(hank)-[:HAS_ACCOUNT]->(cayman),
(abby)-[:HAS_ACCOUNT]->(cayman),
(abby)-[:HAS_SSN]->(ssn993632634),
(sophie)-[:HAS_SSN]->(ssn993632634),
(max)-[:HAS_SSN]->(ssn993632634)
'''
session.run(insert_query)
# Transitive Closure
transitive_query = '''
MATCH (n:Person)-[*]-(o)
WHERE n.name = {name}
RETURN DISTINCT o AS other
'''
results = session.run(transitive_query, parameters={"name": "Hank"})
for record in results:
print(record["other"])
# Investigation Targeting
targeting_query = """
MATCH (n:Person)-[*]-(o)
WITH n, count(DISTINCT o) AS size
WHERE size > 2
RETURN n
"""
results = session.run(targeting_query)
for record in results:
print(record["n"])
# Fast Insights
insights_query = """
MATCH (ssn:SSN)<-[:HAS_SSN]-(:Person)-[:HAS_ACCOUNT]->(acct:Account)
WHERE ssn.number = {flagged_ssn}
RETURN acct
"""
results = session.run(insights_query, parameters={"flagged_ssn": 993632634})
for record in results:
print(record["acct"])
session.close()
Downloading and Installing Python
- Install neo4j-python-driver using pip:
$ pip install neo4j-driver
- Copy and paste code at left into py file and run
# gem install neo4j-core
require 'neo4j-core'
require 'neo4j/core/cypher_session/adaptors/bolt'
adaptor = Neo4j::Core::CypherSession::Adaptors::Bolt.new('bolt://neo4j:password@localhost:7687', wrap_level: :proc)
session = Neo4j::Core::CypherSession.new(adaptor)
session.query('MATCH (n) DETACH DELETE n')
# Insert data
insert_query = <<QUERY
CREATE (hank:Person {name:'Hank'}),
(abby:Person {name:'Abby'}),
(max:Person {name:'Max'}),
(sophie:Person {name: 'Sophie'}),
(jane:Person {name: 'Jane'}),
(bill:Person {name: 'Bill'}),
(ssn993632634:SSN {number: 993632634, name: 'SSN 993632634'}),
(ssn123456789:SSN {number: 123456789, name: 'SSN 123456789'}),
(ssn523252364:SSN {number: 523252364, name: 'SSN 523252364'}),
(chase:Account {bank: 'Chase', number: 1523, name: 'Chase 1523'}),
(bofa:Account {bank: 'Bank of America', number: 4634, name: 'BofA 4634'}),
(cayman:Account {bank: 'Cayman', number: 863, name: 'Cayman 863'}),
(bill)-[:HAS_SSN]->(ssn523252364),
(bill)-[:HAS_ACCOUNT]->(bofa),
(jane)-[:HAS_SSN]->(ssn123456789),
(jane)-[:HAS_ACCOUNT]->(chase),
(hank)-[:HAS_ACCOUNT]->(cayman),
(abby)-[:HAS_ACCOUNT]->(cayman),
(abby)-[:HAS_SSN]->(ssn993632634),
(sophie)-[:HAS_SSN]->(ssn993632634),
(max)-[:HAS_SSN]->(ssn993632634)
QUERY
session.query(insert_query)
# Transitive Closure
transitive_query = <<QUERY
MATCH (n:Person)-[*]-(o)
WHERE n.name = {name}
RETURN DISTINCT o.name AS other
QUERY
response = session.query(transitive_query, name: 'Hank')
puts 'Suspicious entities: '
puts response.map(&:other)
puts '---------------------'
# Investigation Targeting
targeting_query = <<QUERY
MATCH (n:Person)-[*]-(o)
WITH n, count(DISTINCT o) AS size
WHERE size > 2
RETURN n.name AS target
QUERY
response = session.query(targeting_query)
puts 'Investigation targets: '
puts response.map(&:target)
puts '----------------------'
# Fast Insights
connecting_paths_query = <<QUERY
MATCH (ssn:SSN)<-[:HAS_SSN]-(:Person)-[:HAS_ACCOUNT]->(acct:Account)
WHERE ssn.number = 993632634
RETURN acct.bank + ' ' + toString(acct.number) AS account
QUERY
response = session.query(connecting_paths_query, name1: 'Joe', name2: 'Billy')
puts 'Accounts: '
puts response.map(&:account)
puts '----------------------'
# ActiveNode models:
require 'neo4j'
Neo4j::ActiveBase.current_session = session
session.query('CREATE CONSTRAINT ON (s:SSN) ASSERT s.uuid IS UNIQUE')
session.query('CREATE CONSTRAINT ON (p:Person) ASSERT p.uuid IS UNIQUE')
session.query('CREATE CONSTRAINT ON (a:Account) ASSERT a.uuid IS UNIQUE')
class SSN
include Neo4j::ActiveNode
property :number
has_one :in, :person, type: :HAS_SSN
end
class Person
include Neo4j::ActiveNode
has_many :out, :accounts, type: :HAS_ACCOUNT
end
class Account
include Neo4j::ActiveNode
property :bank
property :number
end
# Associations are lazily evaluated to allow for chaining to build Cypher queries:
puts 'Accounts: '
puts SSN.where(number: 993632634).person.accounts(:acct).pluck("acct.bank + ' ' + toString(acct.number)")
Downloading and Installing Ruby
- Install Neo4j.rb using gem:
$ gem install neo4j-core
- Copy and paste code at left into rb file and run
using System;
using System.Collections.Generic;
using System.Linq;
using Neo4jClient;
using Neo4jClient.Cypher;
using Newtonsoft.Json;
void Main()
{
var gc = new GraphClient(new Uri("http://localhost.:7474/db/data"));
gc.Connect();
const string createCypher = @"(hank:Person {name:'Hank'}),
(abby:Person {name:'Abby'}),
(max:Person {name:'Max'}),
(sophie:Person {name: 'Sophie'}),
(jane:Person {name: 'Jane'}),
(bill:Person {name: 'Bill'}),
(ssn993632634:SSN {number: 993632634}),
(ssn123456789:SSN {number: 123456789}),
(ssn523252364:SSN {number: 523252364}),
(chase:Account {bank: 'Chase', number: 1523}),
(bofa:Account {bank: 'Bank of America', number: 4634}),
(cayman:Account {bank: 'Cayman', number: 863}),
(bill)-[:HAS_SSN]->(ssn523252364),
(bill)-[:HAS_ACCOUNT]->(bofa),
(jane)-[:HAS_SSN]->(ssn123456789),
(jane)-[:HAS_ACCOUNT]->(chase),
(hank)-[:HAS_ACCOUNT]->(cayman),
(abby)-[:HAS_ACCOUNT]->(cayman),
(abby)-[:HAS_SSN]->(ssn993632634),
(sophie)-[:HAS_SSN]->(ssn993632634),
(max)-[:HAS_SSN]->(ssn993632634)";
gc.Cypher.Create(createCypher).ExecuteWithoutResults();
//Transitive Closure
var transitiveClosure = gc.Cypher
.Match("(n:Person)-[*]-(o)")
.Where((Entity n) => n.Name == "Hank")
.Return(o => o.As<Entity>())
.Results;
Console.WriteLine("Transitive Closure");
foreach (var tc in transitiveClosure)
Console.WriteLine($"\t{tc}");
//Investigation Targeting
var investigationTargeting = gc.Cypher
.Match("(n:Person)-[*]-(o)")
.With("n, count(distinct o) AS size")
.Where("size > 2")
.Return(n => n.As<Entity>())
.Results;
Console.WriteLine("Investigation Targeting");
foreach (var it in investigationTargeting)
Console.WriteLine($"\t{it}");
//Fast Insights
var fastInsights = gc.Cypher
.Match("(ssn:SSN)<-[:HAS_SSN]-(:Person)-[:HAS_ACCOUNT]->(acct:Account)")
.Where((Entity ssn) => ssn.Number == 993632634)
.Return(acct => acct.As<Entity>())
.Results;
Console.WriteLine("Fast Insights");
foreach (var entity in fastInsights)
Console.WriteLine($"\tBank: {entity.Bank}, Number: {entity.Number}");
}
public class Entity
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("bank")]
public string Bank { get; set;}
[JsonProperty("number")]
public int Number { get; set;}
public override string ToString()
{
return (string.IsNullOrWhiteSpace(Name)) ? ((string.IsNullOrWhiteSpace(Bank))) ? Number.ToString() : Bank : Name;
}
}
Downloading and Installing C#
- Install NuGet
- Run the NuGet Package Manager Console
- Install the Neo4jClient package:
PM> Install-Package Neo4jClient
- Copy and paste code at left into your .NET project, build, and run
// npm install neo4j-driver
var neo4j = require('neo4j-driver').v1;
var driver = neo4j.driver("bolt://localhost", neo4j.auth.basic("neo4j", "<password>"));
var session = driver.session();
var queryCount = 0;
var insertQuery =
"CREATE (hank:Person {name:'Hank'}), \
(abby:Person {name:'Abby'}), \
(max:Person {name:'Max'}), \
(sophie:Person {name: 'Sophie'}), \
(jane:Person {name: 'Jane'}), \
(bill:Person {name: 'Bill'}), \
(ssn993632634:SSN {number: 993632634}), \
(ssn123456789:SSN {number: 123456789}), \
(ssn523252364:SSN {number: 523252364}), \
(chase:Account {bank: 'Chase', number: 1523}), \
(bofa:Account {bank: 'Bank of America', number: 4634}), \
(cayman:Account {bank: 'Cayman', number: 863}), \
(bill)-[:HAS_SSN]->(ssn523252364), \
(bill)-[:HAS_ACCOUNT]->(bofa), \
(jane)-[:HAS_SSN]->(ssn123456789), \
(jane)-[:HAS_ACCOUNT]->(chase), \
(hank)-[:HAS_ACCOUNT]->(cayman), \
(abby)-[:HAS_ACCOUNT]->(cayman), \
(abby)-[:HAS_SSN]->(ssn993632634), \
(sophie)-[:HAS_SSN]->(ssn993632634), \
(max)-[:HAS_SSN]->(ssn993632634)";
var transitiveQuery =
"MATCH (n:Person)-[*]-(o) \
WHERE n.name = {name} \
RETURN DISTINCT o AS other";
var targetingQuery =
"MATCH (n:Person)-[*]-(o) \
WITH n, count(DISTINCT o) AS size \
WHERE size > 2 \
RETURN n";
var insightsQuery =
"MATCH (ssn:SSN)<-[:HAS_SSN]-(:Person)-[:HAS_ACCOUNT]->(acct:Account) \
WHERE ssn.number = {ssn} \
RETURN acct";
function query(query, params, message, column) {
session
.run(query, params)
.then(function(result) {
console.log(message);
result.records.forEach(function(record) {
console.log(record.get(column));
});
queryCount += 1;
if (queryCount > 2) {
session.close();
process.exit();
}
})
.catch(function(error){
console.log(error);
});
}
session
.run(insertQuery)
.then(function(result) {
query(transitiveQuery, {name: "Hank"}, "Transitive closure: ", "other");
query(targetingQuery, {}, "Investigation targeting: ", "n");
query(insightsQuery, {ssn: 993632634}, "Associated accounts: ", "acct");
})
.catch(function(error) {
console.log(error);
});
Downloading and Installing JavaScript
- Install neo4j-driver using npm:
$ npm install --save neo4j-driver
- Copy and paste code at left into js file and run
Intro to Graph Databases
-
Play Video
Intro to Graph Databases Episode #1 - Evolution of DBs
-
Play Video
Intro to Graph Databases Episode #2 - Properties of Graph DBs & Use Cases
-
Play Video
Intro to Graph Databases Episode #3 - Property Graph Model
-
Play Video
Intro to Graph Databases Episode #4 - (RDBMS+SQL) to (Graphs+Cypher)
-
Play Video
Intro to Graph Databases Episode #5 - Cypher, the Graph Query Language
-
Play Video
Intro to Graph Databases Episode #6 - Continuing with Cypher
Training and Certification
Why Neo4j
-
Whiteboard Friendly
Model your connected data as it exists in the real-world — not as tables of columns and rows.
-
Global Community
Support for popular languages & frameworks. Learn Neo4j in different ways from our resources!
-
Native Graph Performance
Optimized graph storage and processing with the expressive Cypher query language.
- 1The property graph data model consists of nodes, relationships, properties, and labels.
- 2You can draw, model, query, and visualize your data in a way that is consistent and easily understood by others.
- 3With the property graph model, the data model you design on the whiteboard is the same as what you store in Neo4j and implement in your application.
- 1Join our interactive Community Site to post your questions and receive expert answers. You can also publish any Neo4j-related content & answer questions by other graphistas.
- 2Find the training that is right for you with GraphAcademy — providing learning online, in-person, privately, & through meetups.
- 3Show your knowledge of Neo4j by completing the certification exam to become a Neo4j Certified Developer!
- 1Native graph storage allows for constant-time local graph traversals. Query performance is not impacted by the size of the graph.
- 2Define graph patterns in the Cypher query language and efficiently traverse your graph at millions of relationships per second.
- 3Move batch processes into real time with the improved performance of native graph traversals.
What It's Made of
- 1In the property graph model, objects are represented as nodes, with relationships connecting the nodes. Both nodes and relationships can have name/value properties.
- 2Add and remove properties on the fly as your data model evolves, with optional schema constraints for flexibility.
- 3No need for schema migrations.
- 1Neo4j is a transactional database for storing your critical data.
- 2While many NoSQL databases throw ACID out the door, data reliability is a key design consideration for Neo4j. If you don't have durability, how can you call yourself a database?
- 3With Neo4j Enterprise, you have a configurable consistency model to balance performance and durability.
- 1Neo4j Enterprise can scale reads across dozens of machines, for ultimate performance with peak loads.
- 2Support for master-slave replication with master re-election and failover to keep your pager quiet at night.
- 3Monitor your whole cluster with operational metrics and integration with 3rd-party monitoring tools via Neo4j Metrics.
- 1Traverse your graph with Cypher, a declarative query language which defines graph patterns using ASCII-art for Graphs. MATCH (me:Person)-[:KNOWS]->(you:Friend)
- 2Natural patterns for multi-level querying mean you can forget nested JOINs. The openCypher project ensures that Cypher will be the language for graphs across the industry.
- 3Easy to learn for developers familiar with other query languages like SQL, and easy for everyone to read.
- 1Query and visualize your graph with the included Neo4j Browser web application. Tutorials help you get going quickly.
- 2Discover patterns in your graph which can then be encoded into Cypher queries in your code for real-time decision making in your application.
- 3Use the built-in graphical output of PROFILE and EXPLAIN to fine-tune your queries before deploying to production.
- 1Whether you use Java, C#, Python, Ruby, JavaScript, PHP, R or Go, the Neo4j community has built drivers to make interacting with Neo4j's HTTP APIs easy.
- 2
- 3Integrations with other database technologies and analytical tools, like MongoDB, Cassandra, ElasticSearch and Spark/GraphX for the polyglot environment.
- 1Easy to get your data into Neo4j in the world's most popular data format - CSV.
- 2LOAD CSV functionality enables initial and incremental transactional loading of your data using Cypher for medium-size datasets up to 10M nodes and relationships.
- 3For ultimate performance, the included neo4j-import tool enables transaction-less loading of up to 1M records per second. The Windows PowerShell module provides support for high-performance loading via the Import-CSV command.
- 1Neo4j Aura is a database-as-a-service hosted by Neo4j that provides flexible and highly reliable graph databases in the cloud for any project.
- 2Customers can also use Neo4j in cloud environments like AWS, Azure and Google Cloud Platform. These partners provide fully-hosted offerings of Neo4j in the Cloud.
- 3Official Docker image simplifies automation and deployment, making it easy to get up and running with a single instance or a full cluster. Try it out using the Neo4j Sandbox, or explore your Twitter data in Neo4j.
Featured Community Members
Featured Videos
-
Play Video
Improve Machine Learning Predictions using Graph Algorithms
-
Play Video
Neo4j for Very Large Scale Systems
-
Play Video
Live from Lyft HQ: How Lyft Drives Data Discovery
-
Play Video
Neo4j Bloom: Investigating Patterns in Financial Transactions
-
Play Video
Graphs Provide Power of Context for AI and ML - GraphConnect highlights
-
Play Video
Introduction to Neo4j Procedures & Functions and the APOC Utility Library (#1)
Online Meetup
-
Play Video
Getting started with Provenance and Neo4j (Online Meetup #66)
-
Play Video
Using Neo4j and GraphQL to build Human Connection (Online Meetup #65)
-
Play Video
3D Geological Modelling and Visualization with Neo4j and Kineviz GraphXR (Neo4j Online Meetup #64)
3D Geological Modelling and Visualization with Neo4j and Kineviz GraphXR (Neo4j Online Meetup #64)
-
Play Video
Football Exploration with Neo4r (Neo4j Online Meetup #63)
-
Play Video
Event-driven Graph Analytics using Neo4j and Apache Kafka (Neo4j Online Meetup #62)
-
Play Video
The Mega Evolution of Pokémons in a Graph (Neo4j Online Meetup #61)