Skip to content

Instantly share code, notes, and snippets.

@mneedham
Last active February 28, 2021 00:07
Show Gist options
  • Save mneedham/a35f146dbe09266d574d to your computer and use it in GitHub Desktop.
Save mneedham/a35f146dbe09266d574d to your computer and use it in GitHub Desktop.
All different ways of searching relationships in Neo4j
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.neo4j</groupId>
<artifactId>vague</artifactId>
<version>1.0</version>
<name>Vague</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>
src/main/resources/META-INF/MANIFEST.MF
</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-kernel</artifactId>
<version>2.1.4</version>
<type>test-jar</type>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-kernel</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-lucene-index</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>org.neo4j.app</groupId>
<artifactId>neo4j-server</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>org.neo4j.app</groupId>
<artifactId>neo4j-server</artifactId>
<version>2.1.4</version>
<type>test-jar</type>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.3</version>
</dependency>
</dependencies>
</project>
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.DynamicLabel;
import org.neo4j.graphdb.DynamicRelationshipType;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Label;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import static org.neo4j.graphdb.DynamicRelationshipType.withName;
public class VagueRelationshipTypes
{
private static final DynamicRelationshipType HAS = withName( "HAS" );
private static final DynamicRelationshipType HAS_ADDRESS = withName( "HAS_ADDRESS" );
private static final DynamicRelationshipType HAS_FRIEND = withName( "HAS_FRIEND" );
private static final Label ADDRESS = DynamicLabel.label( "Address" );
private static final Label FRIEND = DynamicLabel.label( "Friend" );
private static final int ITERATIONS = 100;
private static final int RELATIONSHIPS_TO_CREATE = 10_000;
private static final int OTHER_RELATIONSHIPS_TO_CREATE = 50_000;
public static void main( String[] args ) throws IOException
{
GraphDatabaseService propertyCheckDb = dbWithPropertiesOnEndNode();
GraphDatabaseService labelDb = dbWithLabels();
GraphDatabaseService relationshipNameDb = dbWithSpecificRelationshipNames();
GraphDatabaseService propertyOnRelDb = dbWithPropertiesOnRel();
printPercentiles( queryPropertyOnEndNode( propertyCheckDb ) );
printPercentiles( queryPropertyOnRel( propertyOnRelDb ) );
printPercentiles( queryOnLabels( labelDb ) );
printPercentiles( queryOnRelName( relationshipNameDb ) );
labelDb.shutdown();
propertyCheckDb.shutdown();
relationshipNameDb.shutdown();
propertyOnRelDb.shutdown();
}
public static String padRight(String s, int n) {
return String.format("%1$-" + n + "s", s);
}
private static void printPercentiles( DescriptiveStatistics stats )
{
System.out.println(padRight( "50%ile: " + stats.getPercentile( 50 ), 15 ) +
padRight( "75%ile: " + stats.getPercentile( 75 ), 15 ) +
padRight( "99%ile: " + stats.getPercentile( 99 ), 15 ));
}
private static DescriptiveStatistics queryOnRelName( GraphDatabaseService db )
{
System.out.println();
System.out.println("relationship name");
DescriptiveStatistics stats = new DescriptiveStatistics();
for ( int i = 0; i < ITERATIONS; i++ )
{
long start = System.currentTimeMillis();
int numberOfAddresses = 0;
try(Transaction tx = db.beginTx()) {
Node startNode = db.getNodeById( 0 );
Iterable<Relationship> relationships = startNode.getRelationships( Direction.OUTGOING, HAS_ADDRESS );
for ( Relationship relationship : relationships )
{
numberOfAddresses++;
}
tx.failure();
}
long runningTime = System.currentTimeMillis() - start;
stats.addValue( runningTime );
// System.out.println(numberOfAddresses + " " + runningTime );
}
return stats;
}
private static DescriptiveStatistics queryOnLabels( GraphDatabaseService db )
{
DescriptiveStatistics stats = new DescriptiveStatistics();
System.out.println();
System.out.println("labels");
for ( int i = 0; i < ITERATIONS; i++ )
{
long start = System.currentTimeMillis();
int numberOfAddresses = 0;
try(Transaction tx = db.beginTx()) {
Node startNode = db.getNodeById( 0 );
Iterable<Relationship> relationships = startNode.getRelationships( Direction.OUTGOING, HAS );
for ( Relationship relationship : relationships )
{
if(relationship.getEndNode().hasLabel( ADDRESS )) {
numberOfAddresses++;
}
}
tx.failure();
}
long runningTime = System.currentTimeMillis() - start;
stats.addValue( runningTime );
// System.out.println(numberOfAddresses + " " + runningTime );
}
return stats;
}
private static DescriptiveStatistics queryPropertyOnRel( GraphDatabaseService db )
{
System.out.println();
System.out.println("property on rel");
DescriptiveStatistics stats = new DescriptiveStatistics();
for ( int i = 0; i < ITERATIONS; i++ )
{
long start = System.currentTimeMillis();
int numberOfAddresses = 0;
try(Transaction tx = db.beginTx()) {
Node startNode = db.getNodeById( 0 );
Iterable<Relationship> relationships = startNode.getRelationships( Direction.OUTGOING, HAS );
for ( Relationship relationship : relationships )
{
if(relationship.getProperty( "type" ).toString().equals( "address" )) {
numberOfAddresses++;
}
}
tx.failure();
}
long runningTime = System.currentTimeMillis() - start;
stats.addValue( runningTime );
// System.out.println(numberOfAddresses + " " + runningTime );
}
return stats;
}
private static DescriptiveStatistics queryPropertyOnEndNode( GraphDatabaseService db )
{
DescriptiveStatistics stats = new DescriptiveStatistics();
System.out.println("property on end node");
for ( int i = 0; i < ITERATIONS; i++ )
{
long start = System.currentTimeMillis();
int numberOfAddresses = 0;
try(Transaction tx = db.beginTx()) {
Node startNode = db.getNodeById( 0 );
Iterable<Relationship> relationships = startNode.getRelationships( Direction.OUTGOING, HAS );
for ( Relationship relationship : relationships )
{
if(relationship.getEndNode().getProperty( "type" ).toString().equals( "address" )) {
numberOfAddresses++;
}
}
tx.failure();
}
long runningTime = System.currentTimeMillis() - start;
stats.addValue( runningTime);
// System.err.println(numberOfAddresses + " " + runningTime );
}
return stats;
}
private static GraphDatabaseService dbWithPropertiesOnRel() throws IOException
{
String path = "/tmp/properties-on-rel";
FileUtils.deleteDirectory( new File(path) );
GraphDatabaseService db = new GraphDatabaseFactory().newEmbeddedDatabase( path );
try(Transaction tx = db.beginTx()) {
Node node = db.createNode();
for ( int i = 0; i < RELATIONSHIPS_TO_CREATE; i++ )
{
Node otherNode = db.createNode();
Relationship rel = node.createRelationshipTo( otherNode, HAS );
rel.setProperty( "type", "address" );
}
for ( int i = 0; i < OTHER_RELATIONSHIPS_TO_CREATE; i++ )
{
Node otherNode = db.createNode();
Relationship rel = node.createRelationshipTo( otherNode, HAS );
rel.setProperty( "type", "friend" );
}
tx.success();
}
return db;
}
private static GraphDatabaseService dbWithPropertiesOnEndNode() throws IOException
{
String path = "/tmp/properties";
FileUtils.deleteDirectory( new File(path) );
GraphDatabaseService db = new GraphDatabaseFactory().newEmbeddedDatabase( path );
try(Transaction tx = db.beginTx()) {
Node node = db.createNode();
for ( int i = 0; i < RELATIONSHIPS_TO_CREATE; i++ )
{
Node otherNode = db.createNode();
otherNode.setProperty( "type", "address" );
node.createRelationshipTo( otherNode, HAS );
}
for ( int i = 0; i < OTHER_RELATIONSHIPS_TO_CREATE; i++ )
{
Node otherNode = db.createNode();
otherNode.setProperty( "type", "friend" );
node.createRelationshipTo( otherNode, HAS );
}
tx.success();
}
return db;
}
private static GraphDatabaseService dbWithLabels() throws IOException
{
String path = "/tmp/labels";
FileUtils.deleteDirectory( new File(path) );
GraphDatabaseService db = new GraphDatabaseFactory().newEmbeddedDatabase( path );
try(Transaction tx = db.beginTx()) {
Node node = db.createNode();
for ( int i = 0; i < RELATIONSHIPS_TO_CREATE; i++ )
{
Node otherNode = db.createNode();
otherNode.addLabel( ADDRESS );
node.createRelationshipTo( otherNode, HAS );
}
for ( int i = 0; i < OTHER_RELATIONSHIPS_TO_CREATE; i++ )
{
Node otherNode = db.createNode();
otherNode.addLabel( FRIEND );
node.createRelationshipTo( otherNode, HAS );
}
tx.success();
}
return db;
}
private static GraphDatabaseService dbWithSpecificRelationshipNames() throws IOException
{
String path = "/tmp/specific-rel-names";
FileUtils.deleteDirectory( new File(path) );
GraphDatabaseService db = new GraphDatabaseFactory().newEmbeddedDatabase( path );
try(Transaction tx = db.beginTx()) {
Node node = db.createNode();
for ( int i = 0; i < 10_000; i++ )
{
Node otherNode = db.createNode();
node.createRelationshipTo( otherNode, HAS_ADDRESS );
}
for ( int i = 0; i < OTHER_RELATIONSHIPS_TO_CREATE; i++ )
{
Node otherNode = db.createNode();
node.createRelationshipTo( otherNode, HAS_FRIEND );
}
tx.success();
}
return db;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment