├── .gitignore
├── .gitmodules
├── README.md
├── configuration
├── pom.xml
└── src
│ └── main
│ └── java
│ └── org
│ └── neo4j
│ └── graphdatabases
│ ├── AccessControlConfig.java
│ ├── AccessControlWithRelationshipPropertiesConfig.java
│ ├── LogisticsConfig.java
│ ├── SimpleSocialNetworkConfig.java
│ └── SocialNetworkConfig.java
├── data-generation
├── pom.xml
└── src
│ └── test
│ └── java
│ └── org
│ └── neo4j
│ └── graphdatabases
│ └── dataset_builders
│ ├── AccessControl.java
│ ├── AccessControlWithRelationshipProperties.java
│ ├── Logistics.java
│ ├── SimpleSocialNetwork.java
│ ├── SocialNetwork.java
│ ├── helpers
│ └── SevenDays.java
│ ├── properties
│ ├── DurationOnProjectProperty.java
│ ├── ProjectDuration.java
│ ├── ProjectDurationGenerator.java
│ └── ProjectDurationProperty.java
│ └── traversers
│ ├── FindAllColleagues.java
│ ├── FindColleagues.java
│ └── IsCompanyProject.java
├── performance-testing
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── org
│ │ └── neo4j
│ │ └── graphdatabases
│ │ └── performance_tests
│ │ └── testing
│ │ ├── DefaultExecutionEngineWrapper.java
│ │ ├── DoNothingWithTestResults.java
│ │ ├── MultipleTestRuns.java
│ │ ├── ParamsGenerator.java
│ │ ├── PrintTestResults.java
│ │ ├── QueryType.java
│ │ ├── ResultFormatter.java
│ │ ├── ResultsContainSameElementsUnordered.java
│ │ ├── SingleTest.java
│ │ ├── SingleTestRunResultHandler.java
│ │ ├── SingleTestRunResultHandlerFactory.java
│ │ ├── SysOutWriter.java
│ │ ├── TakeXTestResults.java
│ │ └── TestResultsHandler.java
│ └── test
│ └── java
│ └── org
│ └── neo4j
│ └── graphdatabases
│ └── performance_tests
│ ├── AccessControl.java
│ ├── AccessControlWithRelationshipProperties.java
│ ├── Logistics.java
│ ├── SimpleSocialNetwork.java
│ ├── SocialNetwork.java
│ └── testing
│ └── ResultsContainSameElementsUnorderedTest.java
├── pom.xml
└── queries
├── pom.xml
└── src
├── main
├── java
│ └── org
│ │ └── neo4j
│ │ └── graphdatabases
│ │ └── queries
│ │ ├── AccessControlQueries.java
│ │ ├── AccessControlWithRelationshipPropertiesQueries.java
│ │ ├── EmailQueries.java
│ │ ├── LogisticsQueries.java
│ │ ├── ShakespeareQueries.java
│ │ ├── ShakespeareQueriesUsingAutoIndexes.java
│ │ ├── SimpleSocialNetworkQueries.java
│ │ ├── SocialNetworkQueries.java
│ │ ├── helpers
│ │ ├── DbUtils.java
│ │ ├── ExecutionEngineWrapper.java
│ │ ├── ExecutionResultIterator.java
│ │ ├── ExecutionResultsIterator.java
│ │ ├── IndexNodeByOtherNodeIndexer.java
│ │ ├── QueryUnionExecutionEngine.java
│ │ └── QueryUnionExecutionResult.java
│ │ ├── server
│ │ └── SimpleSocialNetworkExtension.java
│ │ ├── testing
│ │ ├── IndexParam.java
│ │ ├── IndexParams.java
│ │ └── TestOutputWriter.java
│ │ └── traversals
│ │ ├── FriendOfAFriendDepth4.java
│ │ ├── IndexResources.java
│ │ ├── ParcelRouteCalculator.java
│ │ └── SimpleParcelRouteCalculator.java
└── resources
│ └── META_INF
│ └── services
│ ├── javax.script.ScriptEngineFactory
│ └── org.neo4j.server.plugins.ServerPlugin
└── test
└── java
└── org
└── neo4j
└── graphdatabases
└── queries
├── AccessControlQueriesTest.java
├── AccessControlWithRelationshipPropertiesQueriesTest.java
├── EmailQueriesTest.java
├── LogisticsQueriesTest.java
├── ShakespeareQueriesTest.java
├── SimpleSocialNetworkQueriesTest.java
├── SocialNetworkQueriesTest.java
├── helpers
├── Db.java
├── IndexNodeByOtherNodeIndexerTest.java
├── PrintingExecutionEngineWrapper.java
└── QueryUnionExecutionEngineTest.java
└── server
└── SimpleSocialNetworkExtensionTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | datasets/
2 | examples/
3 | datasets-old/
4 | .DS_Store
5 | build
6 | target
7 | .settings
8 | .project
9 | .idea
10 | .classpath
11 | *.iml
12 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "neode"]
2 | path = neode
3 | url = https://github.com/jexp/neode.git
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Graph Databases Use Cases
2 | =========================
3 |
4 | Example use case implementations from the O'Reilly book [Graph Databases](http://graphdatabases.com/) by [@iansrobinson](http://twitter.com/iansrobinson), [@jimwebber](http://twitter.com/jimwebber) and [@emileifrem](http://twitter.com/emileifrem).
5 |
6 | Setup
7 | -----
8 |
9 | This repository contains a submodule, _neode_, which is used to build the performance datasets. After cloning the repository, you will need to initialize the submodule:
10 |
11 | git submodule init
12 |
13 | and then:
14 |
15 | git submodule update
16 |
17 | To run the use case queries:
18 |
19 | mvn clean install
20 |
21 | Overview
22 | --------
23 |
24 | Queries are developed in a test-driven fashion against small, well-known representative graphs (as described pp.83-87 of the book). The queries can then be run against a much larger, randomly-generated graph (typically, 1-2 million nodes and several million relationships), to test their relative performance. (Note: these performance tests do not test production-like scenarios; rather, they act as a sanity check, ensuring that queries that run fast against a very small graph are still reasonably performant when run against a larger graph.)
25 |
26 | The project contains 3 modules (in addition to the _neode_ submodule):
27 |
28 | * _queries_
29 |
30 | Contains the use case queries and the unit tests used to develop the queries.
31 | * _dataset_builders_
32 |
33 | Builds larger, randomly-generated sample datasets.
34 | * _performance_tests_
35 |
36 | Runs the queries against the large sample datasets.
37 |
38 | Running the Performance Tests
39 | -----------------------------
40 |
41 | First, build the project as described in Setup.
42 |
43 | Before you run the performance tests you will need to generate sample datasets. To create a sample dataset run:
44 |
45 | mvn test -pl data-generation -DargLine="-Xms2g -Xmx2g" -Dtest=AccessControl|Logistics|SocialNetwork
46 |
47 | For example, to generate a sample dataset for the Logistics queries, run:
48 |
49 | mvn test -pl data-generation -DargLine="-Xms2g -Xmx2g" -Dtest=Logistics
50 |
51 | *WARNING:* Building the sample datasets takes a long time (several tens of minutes in some cases).
52 |
53 | To execute the performance tests against a sample dataset, run:
54 |
55 | mvn test -pl performance-testing -DargLine="-Xms2g -Xmx2g" -Dtest=AccessControl|Logistics|SocialNetwork
56 |
--------------------------------------------------------------------------------
/configuration/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | org.neo4j.graphdatabases
8 | configuration
9 | 2.0-SNAPSHOT
10 | jar
11 |
12 |
13 | 1.7
14 | 1.7
15 | UTF-8
16 |
17 |
18 |
19 |
20 | joda-time
21 | joda-time
22 | 2.1
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/configuration/src/main/java/org/neo4j/graphdatabases/AccessControlConfig.java:
--------------------------------------------------------------------------------
1 | package org.neo4j.graphdatabases;
2 |
3 | public class AccessControlConfig
4 | {
5 | public static final String STORE_DIR = "../datasets/access-control-no-attributes/";
6 | public static final String TITLE = "Access Control (fine-grained permission relationships)";
7 | public static final int NUMBER_OF_ADMINS = 1000;
8 | public static final int NUMBER_OF_GROUPS = 2000;
9 | public static final int NUMBER_OF_COMPANIES = 30000;
10 | }
11 |
--------------------------------------------------------------------------------
/configuration/src/main/java/org/neo4j/graphdatabases/AccessControlWithRelationshipPropertiesConfig.java:
--------------------------------------------------------------------------------
1 | package org.neo4j.graphdatabases;
2 |
3 | public class AccessControlWithRelationshipPropertiesConfig
4 | {
5 | public static final String STORE_DIR = "../datasets/access-control/";
6 | public static final String TITLE = "Access Control";
7 | public static final int NUMBER_OF_ADMINS = 1000;
8 | public static final int NUMBER_OF_GROUPS = 2000;
9 | public static final int NUMBER_OF_COMPANIES = 30000;
10 | }
11 |
--------------------------------------------------------------------------------
/configuration/src/main/java/org/neo4j/graphdatabases/LogisticsConfig.java:
--------------------------------------------------------------------------------
1 | package org.neo4j.graphdatabases;
2 |
3 | import org.joda.time.DateTime;
4 | import org.joda.time.DateTimeZone;
5 |
6 | public class LogisticsConfig
7 | {
8 | public static final String TITLE = "Logistics";
9 | public static final String STORE_DIR = "../datasets/logistics/";
10 | public static final DateTime START_DATE = new DateTime( 2012, 10, 15, 0, 0, 0, 0, DateTimeZone.UTC );
11 | public static final int NUMBER_OF_PARCEL_CENTRES = 20;
12 | public static final int MIN_NUMBER_OF_DELIVERY_BASES_PER_PARCEL_CENTRE = 30;
13 | public static final int MAX_NUMBER_OF_DELIVERY_BASES_PER_PARCEL_CENTRE = 50;
14 | public static final int MIN_NUMBER_OF_DELIVERY_AREAS_PER_DELIVERY_BASE = 20;
15 | public static final int MAX_NUMBER_OF_DELIVERY_AREAS_PER_DELIVERY_BASE = 40;
16 | public static final int MIN_NUMBER_OF_DELIVERY_SEGMENTS_PER_DELIVERY_AREA = 50;
17 | public static final int MAX_NUMBER_OF_DELIVERY_SEGMENTS_PER_DELIVERY_AREA = 100;
18 | }
19 |
--------------------------------------------------------------------------------
/configuration/src/main/java/org/neo4j/graphdatabases/SimpleSocialNetworkConfig.java:
--------------------------------------------------------------------------------
1 | package org.neo4j.graphdatabases;
2 |
3 | public class SimpleSocialNetworkConfig
4 | {
5 | public static final String STORE_DIR = "../datasets/simple-social-network/";
6 | public static final String TITLE = "Simple Social Network";
7 | public static final int NUMBER_USERS = 20900;
8 | public static final int MIN_NUMBER_OF_FRIENDS = 50;
9 | public static final int MAX_NUMBER_OF_FRIENDS = 100;
10 | }
11 |
--------------------------------------------------------------------------------
/configuration/src/main/java/org/neo4j/graphdatabases/SocialNetworkConfig.java:
--------------------------------------------------------------------------------
1 | package org.neo4j.graphdatabases;
2 |
3 | public class SocialNetworkConfig
4 | {
5 | public static final String STORE_DIR = "../datasets/social-network";
6 | public static final String TITLE = "Social Network";
7 | public static final int NUMBER_USERS = 1000000;
8 | public static final int NUMBER_COMPANIES = 10000;
9 | public static final int NUMBER_TOPICS = 100;
10 | }
11 |
--------------------------------------------------------------------------------
/data-generation/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | org.neo4j.graphdatabases
8 | data-generation
9 | 2.0-SNAPSHOT
10 | jar
11 |
12 |
13 | 1.7
14 | 1.7
15 | UTF-8
16 | 2.0.1
17 |
18 |
19 |
20 |
21 | org.neo4j
22 | neo4j-kernel
23 | ${neo4j.version}
24 |
25 |
26 | org.neo4j
27 | neo4j-enterprise
28 | ${neo4j.version}
29 |
30 |
31 | org.neo4j.graphdatabases
32 | configuration
33 | 2.0-SNAPSHOT
34 |
35 |
36 | org.neo4j.graphdatabases
37 | queries
38 | 2.0-SNAPSHOT
39 |
40 |
41 | neode
42 | neode
43 | 2.0
44 |
45 |
46 | joda-time
47 | joda-time
48 | 2.1
49 |
50 |
51 | junit
52 | junit
53 | 4.11
54 | test
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/data-generation/src/test/java/org/neo4j/graphdatabases/dataset_builders/AccessControl.java:
--------------------------------------------------------------------------------
1 | package org.neo4j.graphdatabases.dataset_builders;
2 |
3 | import java.io.File;
4 |
5 | import org.junit.Test;
6 |
7 | import org.neo4j.graphdatabases.AccessControlConfig;
8 | import org.neo4j.graphdatabases.queries.helpers.DbUtils;
9 | import org.neo4j.graphdatabases.queries.traversals.IndexResources;
10 | import org.neo4j.graphdb.Direction;
11 | import org.neo4j.graphdb.GraphDatabaseService;
12 | import org.neo4j.graphdb.factory.GraphDatabaseFactory;
13 | import org.neo4j.kernel.impl.util.FileUtils;
14 | import org.neo4j.neode.Dataset;
15 | import org.neo4j.neode.DatasetManager;
16 | import org.neo4j.neode.NodeCollection;
17 | import org.neo4j.neode.NodeSpecification;
18 | import org.neo4j.neode.Range;
19 | import org.neo4j.neode.RelationshipSpecification;
20 | import org.neo4j.neode.RelationshipUniqueness;
21 | import org.neo4j.neode.logging.SysOutLog;
22 | import org.neo4j.neode.statistics.AsciiDocFormatter;
23 | import org.neo4j.neode.statistics.GraphStatistics;
24 |
25 | import static org.neo4j.neode.Range.minMax;
26 | import static org.neo4j.neode.TargetNodesStrategy.create;
27 | import static org.neo4j.neode.TargetNodesStrategy.getExisting;
28 | import static org.neo4j.neode.TargetNodesStrategy.getOrCreate;
29 | import static org.neo4j.neode.properties.Property.indexableProperty;
30 | import static org.neo4j.neode.properties.Property.property;
31 |
32 | public class AccessControl
33 | {
34 | public static final Range GROUPS_PER_ADMIN = minMax( 1, 3 );
35 | public static final Range ALLOWED_COMPANIES_PER_GROUP = minMax( 10, 50 );
36 | public static final Range DENIED_COMPANIES_PER_GROUP = minMax( 2, 10 );
37 | public static final Range EMPLOYEES_PER_COMPANY = minMax( 5, 100 );
38 | public static final Range ACCOUNTS_PER_EMPLOYEE = minMax( 1, 5 );
39 |
40 | @Test
41 | public void buildAccessControl() throws Exception
42 | {
43 | File dir = new File( AccessControlConfig.STORE_DIR );
44 | FileUtils.deleteRecursively( dir );
45 |
46 | GraphDatabaseService db = new GraphDatabaseFactory()
47 | .newEmbeddedDatabaseBuilder( AccessControlConfig.STORE_DIR )
48 | .setConfig( DbUtils.dbConfig() )
49 | .newGraphDatabase();
50 | DatasetManager dsm = new DatasetManager( db, SysOutLog.INSTANCE );
51 |
52 | NodeSpecification adminSpec = dsm.nodeSpecification( "Administrator", indexableProperty( db, "Administrator", "name" ) );
53 | NodeSpecification groupSpec = dsm.nodeSpecification( "Group", property( "name" ) );
54 | NodeSpecification companySpec = dsm.nodeSpecification( "Company", indexableProperty( db, "Company", "name" ) );
55 | NodeSpecification customerSpec = dsm.nodeSpecification( "Employee", indexableProperty( db, "Employee", "name", "Resource"));
56 | NodeSpecification accountSpec = dsm.nodeSpecification( "Account", indexableProperty( db, "Account", "name", "Resource"));
57 |
58 | RelationshipSpecification member_of = dsm.relationshipSpecification( "MEMBER_OF" );
59 | RelationshipSpecification allowed_inherit = dsm.relationshipSpecification( "ALLOWED_INHERIT" );
60 | RelationshipSpecification allowed_do_not_inherit = dsm.relationshipSpecification( "ALLOWED_DO_NOT_INHERIT" );
61 | RelationshipSpecification denied = dsm.relationshipSpecification( "DENIED" );
62 | RelationshipSpecification child_of = dsm.relationshipSpecification( "CHILD_OF" );
63 | RelationshipSpecification works_for = dsm.relationshipSpecification( "WORKS_FOR" );
64 | RelationshipSpecification has_account = dsm.relationshipSpecification( "HAS_ACCOUNT" );
65 |
66 | Dataset dataset = dsm.newDataset( "Access Control (without using inherit attributes)" );
67 |
68 | NodeCollection administrators = adminSpec.create( AccessControlConfig.NUMBER_OF_ADMINS ).update( dataset );
69 | NodeCollection groups = administrators.createRelationshipsTo(
70 | getOrCreate( groupSpec, AccessControlConfig.NUMBER_OF_GROUPS )
71 | .numberOfTargetNodes( GROUPS_PER_ADMIN )
72 | .relationship( member_of )
73 | .relationshipConstraints( RelationshipUniqueness.BOTH_DIRECTIONS ) )
74 | .update( dataset );
75 |
76 | NodeCollection companies1allowedInherit = groups.createRelationshipsTo(
77 | getOrCreate( companySpec, percentageOf( AccessControlConfig.NUMBER_OF_COMPANIES, 0.17 ) )
78 | .numberOfTargetNodes( ALLOWED_COMPANIES_PER_GROUP )
79 | .relationship( allowed_inherit )
80 | .relationshipConstraints( RelationshipUniqueness.BOTH_DIRECTIONS ) )
81 | .update( dataset );
82 |
83 | NodeCollection companies1allowedDoNotInherit = groups.createRelationshipsTo(
84 | getOrCreate( companySpec, percentageOf( AccessControlConfig.NUMBER_OF_COMPANIES, 0.08 ) )
85 | .numberOfTargetNodes( ALLOWED_COMPANIES_PER_GROUP )
86 | .relationship( allowed_do_not_inherit )
87 | .relationshipConstraints( RelationshipUniqueness.BOTH_DIRECTIONS ) )
88 | .update( dataset );
89 |
90 | NodeCollection companies1denied = groups.createRelationshipsTo(
91 | getOrCreate( companySpec, percentageOf( AccessControlConfig.NUMBER_OF_COMPANIES, 0.1 ) )
92 | .numberOfTargetNodes( DENIED_COMPANIES_PER_GROUP )
93 | .relationship( denied )
94 | .relationshipConstraints( RelationshipUniqueness.BOTH_DIRECTIONS ) )
95 | .update( dataset );
96 |
97 | NodeCollection companies2allowedInherit = groups.createRelationshipsTo(
98 | getOrCreate( companySpec, percentageOf( AccessControlConfig.NUMBER_OF_COMPANIES, 0.33 ) )
99 | .numberOfTargetNodes( ALLOWED_COMPANIES_PER_GROUP )
100 | .relationship( allowed_inherit )
101 | .relationshipConstraints( RelationshipUniqueness.BOTH_DIRECTIONS ) )
102 | .update( dataset );
103 |
104 | NodeCollection companies2allowedDoNotInherit = groups.createRelationshipsTo(
105 | getOrCreate( companySpec, percentageOf( AccessControlConfig.NUMBER_OF_COMPANIES, 0.17 ) )
106 | .numberOfTargetNodes( ALLOWED_COMPANIES_PER_GROUP )
107 | .relationship( allowed_do_not_inherit )
108 | .relationshipConstraints( RelationshipUniqueness.BOTH_DIRECTIONS ) )
109 | .update( dataset );
110 |
111 | NodeCollection companies2denied = groups.createRelationshipsTo(
112 | getOrCreate( companySpec, percentageOf( AccessControlConfig.NUMBER_OF_COMPANIES, 0.15 ) )
113 | .numberOfTargetNodes( DENIED_COMPANIES_PER_GROUP )
114 | .relationship( denied )
115 | .relationshipConstraints( RelationshipUniqueness.BOTH_DIRECTIONS ) )
116 | .update( dataset );
117 |
118 | NodeCollection companies1 = companies1allowedInherit.combine( companies1allowedDoNotInherit ).combine(
119 | companies1denied );
120 | NodeCollection companies2 = companies2allowedInherit.combine( companies2allowedDoNotInherit ).combine(
121 | companies2denied );
122 |
123 | companies2.createRelationshipsTo(
124 | getExisting( companies1 )
125 | .numberOfTargetNodes( 1 )
126 | .relationship( child_of )
127 | .exactlyOneRelationship() )
128 | .updateNoReturn( dataset );
129 |
130 |
131 | NodeCollection companies = companies1.combine( companies2 );
132 | NodeCollection employees = companies.createRelationshipsTo(
133 | create( customerSpec )
134 | .numberOfTargetNodes( EMPLOYEES_PER_COMPANY )
135 | .relationship( works_for, Direction.INCOMING )
136 | .exactlyOneRelationship() )
137 | .update( dataset, 1000 );
138 |
139 | employees.createRelationshipsTo(
140 | create( accountSpec )
141 | .numberOfTargetNodes( ACCOUNTS_PER_EMPLOYEE )
142 | .relationship( has_account, Direction.OUTGOING )
143 | .exactlyOneRelationship() )
144 | .updateNoReturn( dataset );
145 |
146 | dataset.end();
147 |
148 | new IndexResources( db ).execute();
149 |
150 | GraphStatistics.create( db, AccessControlConfig.TITLE )
151 | .describeTo( new AsciiDocFormatter( SysOutLog.INSTANCE ) );
152 |
153 | db.shutdown();
154 | }
155 |
156 | private int percentageOf( int i, double percentage )
157 | {
158 | return (int) (i * percentage);
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/data-generation/src/test/java/org/neo4j/graphdatabases/dataset_builders/AccessControlWithRelationshipProperties.java:
--------------------------------------------------------------------------------
1 | package org.neo4j.graphdatabases.dataset_builders;
2 |
3 | import java.io.File;
4 | import java.util.Random;
5 |
6 | import org.junit.Test;
7 |
8 | import org.neo4j.graphdatabases.AccessControlWithRelationshipPropertiesConfig;
9 | import org.neo4j.graphdatabases.queries.helpers.DbUtils;
10 | import org.neo4j.graphdatabases.queries.traversals.IndexResources;
11 | import org.neo4j.graphdb.Direction;
12 | import org.neo4j.graphdb.GraphDatabaseService;
13 | import org.neo4j.graphdb.PropertyContainer;
14 | import org.neo4j.graphdb.factory.GraphDatabaseFactory;
15 | import org.neo4j.kernel.impl.util.FileUtils;
16 | import org.neo4j.neode.Dataset;
17 | import org.neo4j.neode.DatasetManager;
18 | import org.neo4j.neode.NodeCollection;
19 | import org.neo4j.neode.NodeSpecification;
20 | import org.neo4j.neode.Range;
21 | import org.neo4j.neode.RelationshipSpecification;
22 | import org.neo4j.neode.RelationshipUniqueness;
23 | import org.neo4j.neode.logging.SysOutLog;
24 | import org.neo4j.neode.properties.Property;
25 | import org.neo4j.neode.statistics.AsciiDocFormatter;
26 | import org.neo4j.neode.statistics.GraphStatistics;
27 |
28 | import static org.neo4j.neode.Range.minMax;
29 | import static org.neo4j.neode.TargetNodesStrategy.create;
30 | import static org.neo4j.neode.TargetNodesStrategy.getExisting;
31 | import static org.neo4j.neode.TargetNodesStrategy.getOrCreate;
32 | import static org.neo4j.neode.properties.Property.indexableProperty;
33 | import static org.neo4j.neode.properties.Property.property;
34 |
35 | public class AccessControlWithRelationshipProperties
36 | {
37 | public static final Range GROUPS_PER_ADMIN = minMax( 1, 3 );
38 | public static final Range ALLOWED_COMPANIES_PER_GROUP = minMax( 10, 50 );
39 | public static final Range DENIED_COMPANIES_PER_GROUP = minMax( 2, 10 );
40 | public static final Range EMPLOYEES_PER_COMPANY = minMax( 5, 100 );
41 | public static final Range ACCOUNTS_PER_EMPLOYEE = minMax( 1, 5 );
42 |
43 | @Test
44 | public void buildAccessControl() throws Exception
45 | {
46 | File dir = new File( AccessControlWithRelationshipPropertiesConfig.STORE_DIR );
47 | FileUtils.deleteRecursively( dir );
48 |
49 | GraphDatabaseService db = new GraphDatabaseFactory()
50 | .newEmbeddedDatabaseBuilder( AccessControlWithRelationshipPropertiesConfig.STORE_DIR )
51 | .setConfig( DbUtils.dbConfig() )
52 | .newGraphDatabase();
53 | DatasetManager dsm = new DatasetManager( db, SysOutLog.INSTANCE );
54 |
55 | NodeSpecification adminSpec = dsm.nodeSpecification( "Administrator", indexableProperty( db, "Administrator", "name" ) );
56 | NodeSpecification groupSpec = dsm.nodeSpecification( "Group", property( "name" ) );
57 | NodeSpecification companySpec = dsm.nodeSpecification( "Company", indexableProperty( db, "Company", "name" ) );
58 | NodeSpecification customerSpec = dsm.nodeSpecification( "Employee", indexableProperty( db, "Employee", "name", "Resource"));
59 | NodeSpecification accountSpec = dsm.nodeSpecification( "Account", indexableProperty( db, "Account", "name", "Resource"));
60 |
61 | Property inheritProperty = new Property()
62 | {
63 | private final Random random = new Random();
64 |
65 | @Override
66 | public void setProperty( PropertyContainer propertyContainer, GraphDatabaseService graphDatabaseService,
67 | String label, int iteration )
68 | {
69 | int i = random.nextInt( 3 );
70 | boolean value = i < 2;
71 | propertyContainer.setProperty( "inherit", value );
72 | }
73 | };
74 |
75 | RelationshipSpecification member_of = dsm.relationshipSpecification( "MEMBER_OF" );
76 | RelationshipSpecification allowed = dsm.relationshipSpecification( "ALLOWED", inheritProperty );
77 | RelationshipSpecification denied = dsm.relationshipSpecification( "DENIED" );
78 | RelationshipSpecification child_of = dsm.relationshipSpecification( "CHILD_OF" );
79 | RelationshipSpecification works_for = dsm.relationshipSpecification( "WORKS_FOR" );
80 | RelationshipSpecification has_account = dsm.relationshipSpecification( "HAS_ACCOUNT" );
81 |
82 | Dataset dataset = dsm.newDataset( AccessControlWithRelationshipPropertiesConfig.TITLE );
83 |
84 | NodeCollection administrators = adminSpec.create( AccessControlWithRelationshipPropertiesConfig
85 | .NUMBER_OF_ADMINS ).update( dataset );
86 | NodeCollection groups = administrators.createRelationshipsTo(
87 | getOrCreate( groupSpec, AccessControlWithRelationshipPropertiesConfig.NUMBER_OF_GROUPS )
88 | .numberOfTargetNodes( GROUPS_PER_ADMIN )
89 | .relationship( member_of )
90 | .relationshipConstraints( RelationshipUniqueness.BOTH_DIRECTIONS ) )
91 | .update( dataset );
92 |
93 | NodeCollection companies1allowed = groups.createRelationshipsTo(
94 | getOrCreate( companySpec, percentageOf( AccessControlWithRelationshipPropertiesConfig
95 | .NUMBER_OF_COMPANIES, 0.25 ) )
96 | .numberOfTargetNodes( ALLOWED_COMPANIES_PER_GROUP )
97 | .relationship( allowed )
98 | .relationshipConstraints( RelationshipUniqueness.BOTH_DIRECTIONS ) )
99 | .update( dataset );
100 |
101 | NodeCollection companies1denied = groups.createRelationshipsTo(
102 | getOrCreate( companySpec, percentageOf( AccessControlWithRelationshipPropertiesConfig
103 | .NUMBER_OF_COMPANIES, 0.1 ) )
104 | .numberOfTargetNodes( DENIED_COMPANIES_PER_GROUP )
105 | .relationship( denied )
106 | .relationshipConstraints( RelationshipUniqueness.BOTH_DIRECTIONS ) )
107 | .update( dataset );
108 |
109 | NodeCollection companies2allowed = groups.createRelationshipsTo(
110 | getOrCreate( companySpec, percentageOf( AccessControlWithRelationshipPropertiesConfig
111 | .NUMBER_OF_COMPANIES, 0.50 ) )
112 | .numberOfTargetNodes( ALLOWED_COMPANIES_PER_GROUP )
113 | .relationship( allowed )
114 | .relationshipConstraints( RelationshipUniqueness.BOTH_DIRECTIONS ) )
115 | .update( dataset );
116 |
117 | NodeCollection companies2denied = groups.createRelationshipsTo(
118 | getOrCreate( companySpec, percentageOf( AccessControlWithRelationshipPropertiesConfig
119 | .NUMBER_OF_COMPANIES, 0.15 ) )
120 | .numberOfTargetNodes( DENIED_COMPANIES_PER_GROUP )
121 | .relationship( denied )
122 | .relationshipConstraints( RelationshipUniqueness.BOTH_DIRECTIONS ) )
123 | .update( dataset );
124 |
125 | NodeCollection companies1 = companies1allowed.combine( companies1denied );
126 | NodeCollection companies2 = companies2allowed.combine( companies2denied );
127 |
128 | companies2.createRelationshipsTo(
129 | getExisting( companies1 )
130 | .numberOfTargetNodes( 1 )
131 | .relationship( child_of )
132 | .exactlyOneRelationship() )
133 | .updateNoReturn( dataset );
134 |
135 |
136 | NodeCollection companies = companies1.combine( companies2 );
137 | NodeCollection employees = companies.createRelationshipsTo(
138 | create( customerSpec )
139 | .numberOfTargetNodes( EMPLOYEES_PER_COMPANY )
140 | .relationship( works_for, Direction.INCOMING )
141 | .exactlyOneRelationship() )
142 | .update( dataset, 1000 );
143 |
144 | employees.createRelationshipsTo(
145 | create( accountSpec )
146 | .numberOfTargetNodes( ACCOUNTS_PER_EMPLOYEE )
147 | .relationship( has_account, Direction.OUTGOING )
148 | .exactlyOneRelationship() )
149 | .updateNoReturn( dataset );
150 |
151 | dataset.end();
152 |
153 | new IndexResources( db ).execute();
154 |
155 | GraphStatistics.create( db, AccessControlWithRelationshipPropertiesConfig.TITLE )
156 | .describeTo( new AsciiDocFormatter( SysOutLog.INSTANCE ) );
157 |
158 | db.shutdown();
159 |
160 | }
161 |
162 | private int percentageOf( int i, double percentage )
163 | {
164 | return (int) (i * percentage);
165 | }
166 |
167 | }
168 |
--------------------------------------------------------------------------------
/data-generation/src/test/java/org/neo4j/graphdatabases/dataset_builders/Logistics.java:
--------------------------------------------------------------------------------
1 | package org.neo4j.graphdatabases.dataset_builders;
2 |
3 | import java.io.File;
4 | import java.util.Iterator;
5 | import java.util.NoSuchElementException;
6 | import java.util.Random;
7 |
8 | import org.joda.time.Interval;
9 | import org.junit.Test;
10 |
11 | import org.neo4j.graphdatabases.LogisticsConfig;
12 | import org.neo4j.graphdatabases.dataset_builders.helpers.SevenDays;
13 | import org.neo4j.graphdatabases.queries.helpers.DbUtils;
14 | import org.neo4j.graphdb.GraphDatabaseService;
15 | import org.neo4j.graphdb.PropertyContainer;
16 | import org.neo4j.graphdb.factory.GraphDatabaseFactory;
17 | import org.neo4j.kernel.impl.util.FileUtils;
18 | import org.neo4j.neode.Dataset;
19 | import org.neo4j.neode.DatasetManager;
20 | import org.neo4j.neode.NodeCollection;
21 | import org.neo4j.neode.NodeSpecification;
22 | import org.neo4j.neode.logging.SysOutLog;
23 | import org.neo4j.neode.properties.Property;
24 | import org.neo4j.neode.statistics.AsciiDocFormatter;
25 | import org.neo4j.neode.statistics.GraphStatistics;
26 |
27 | import static org.neo4j.neode.Range.exactly;
28 | import static org.neo4j.neode.Range.minMax;
29 | import static org.neo4j.neode.TargetNodesStrategy.create;
30 | import static org.neo4j.neode.TargetNodesStrategy.getOrCreate;
31 | import static org.neo4j.neode.properties.Property.indexableProperty;
32 |
33 | public class Logistics
34 | {
35 | @Test
36 | public void buildLogistics() throws Exception
37 | {
38 | File dir = new File( LogisticsConfig.STORE_DIR );
39 | FileUtils.deleteRecursively( dir );
40 |
41 | GraphDatabaseService db = new GraphDatabaseFactory()
42 | .newEmbeddedDatabaseBuilder( LogisticsConfig.STORE_DIR )
43 | .setConfig( DbUtils.dbConfig() )
44 | .newGraphDatabase();
45 | DatasetManager dsm = new DatasetManager( db, SysOutLog.INSTANCE );
46 |
47 | NodeSpecification parcelCentreSpec = dsm.nodeSpecification( "ParcelCentre",
48 | indexableProperty( db, "ParcelCentre", "name", "Location" ) );
49 | NodeSpecification deliveryBaseSpec = dsm.nodeSpecification( "DeliveryBase",
50 | indexableProperty( db, "DeliveryBase","name", "Location" ) );
51 | NodeSpecification deliveryAreaSpec = dsm.nodeSpecification( "DeliveryArea",
52 | indexableProperty( db, "DeliveryArea", "name", "Location" ) );
53 | NodeSpecification deliverySegmentSpec = dsm.nodeSpecification( "DeliverySegment",
54 | indexableProperty( db, "DeliverySegment", "name", "Location" ) );
55 |
56 | Property costProperty = new CostProperty();
57 |
58 | Dataset dataset = dsm.newDataset( LogisticsConfig.TITLE );
59 |
60 | NodeCollection parcelCentres = parcelCentreSpec.create( LogisticsConfig.NUMBER_OF_PARCEL_CENTRES ).update(
61 | dataset );
62 |
63 | NodeCollection deliveryBases = parcelCentres.createRelationshipsTo(
64 | getOrCreate( deliveryBaseSpec, 400 )
65 | .numberOfTargetNodes( minMax(
66 | LogisticsConfig.MIN_NUMBER_OF_DELIVERY_BASES_PER_PARCEL_CENTRE,
67 | LogisticsConfig.MAX_NUMBER_OF_DELIVERY_BASES_PER_PARCEL_CENTRE ) )
68 | .relationship( dsm.relationshipSpecification( "CONNECTED_TO",
69 | new IntervalProperty( 2 ),
70 | costProperty ) )
71 | .relationshipConstraints( exactly( 2 ) ) )
72 | .update( dataset );
73 |
74 | NodeCollection deliveryAreas = deliveryBases.createRelationshipsTo(
75 | create( deliveryAreaSpec )
76 | .numberOfTargetNodes( minMax(
77 | LogisticsConfig.MIN_NUMBER_OF_DELIVERY_AREAS_PER_DELIVERY_BASE,
78 | LogisticsConfig.MAX_NUMBER_OF_DELIVERY_AREAS_PER_DELIVERY_BASE ) )
79 | .relationship( dsm.relationshipSpecification( "DELIVERY_ROUTE",
80 | new IntervalProperty( 3 ),
81 | costProperty ) )
82 | .relationshipConstraints( exactly( 3 ) ) )
83 | .update( dataset );
84 | deliveryAreas.createRelationshipsTo(
85 | create( deliverySegmentSpec )
86 | .numberOfTargetNodes( minMax(
87 | LogisticsConfig.MIN_NUMBER_OF_DELIVERY_SEGMENTS_PER_DELIVERY_AREA,
88 | LogisticsConfig.MAX_NUMBER_OF_DELIVERY_SEGMENTS_PER_DELIVERY_AREA ) )
89 | .relationship( dsm.relationshipSpecification( "DELIVERY_ROUTE",
90 | new IntervalProperty( 3 ),
91 | costProperty ) )
92 | .relationshipConstraints( exactly( 3 ) ) )
93 | .updateNoReturn( dataset, 1000 );
94 |
95 | dataset.end();
96 |
97 | GraphStatistics.create( db, LogisticsConfig.TITLE )
98 | .describeTo( new AsciiDocFormatter( SysOutLog.INSTANCE ) );
99 |
100 | db.shutdown();
101 |
102 | }
103 |
104 | private static class IntervalProperty extends Property
105 | {
106 | private final int numberOfIntervals;
107 | private final SevenDays sevenDays = new SevenDays( LogisticsConfig.START_DATE );
108 |
109 | private Iterator intervals;
110 | private int counter;
111 |
112 | private IntervalProperty( int numberOfIntervals )
113 | {
114 | this.numberOfIntervals = numberOfIntervals;
115 | this.counter = numberOfIntervals;
116 | }
117 |
118 | @Override
119 | public void setProperty( PropertyContainer propertyContainer, GraphDatabaseService graphDatabaseService,
120 | String label, int iteration )
121 | {
122 | if ( counter++ >= numberOfIntervals )
123 | {
124 | intervals = sevenDays.calculateIntervals( numberOfIntervals ).iterator();
125 | counter = 1;
126 | }
127 |
128 | try
129 | {
130 | Interval nextInterval = intervals.next();
131 | propertyContainer.setProperty( "start_date", nextInterval.getStartMillis() );
132 | propertyContainer.setProperty( "end_date", nextInterval.getEndMillis() );
133 | }
134 | catch ( NoSuchElementException e )
135 | {
136 | throw new IllegalStateException( String.format( "counter: %s, numberOfIntervals: %s, iteration: %s",
137 | counter, numberOfIntervals, iteration ) );
138 | }
139 | }
140 | }
141 |
142 | private static class CostProperty extends Property
143 | {
144 | private final Random random = new Random();
145 |
146 | @Override
147 | public void setProperty( PropertyContainer propertyContainer, GraphDatabaseService graphDatabaseService,
148 | String s, int i )
149 | {
150 | propertyContainer.setProperty( "cost", random.nextInt( 10 ) + 1 );
151 | }
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/data-generation/src/test/java/org/neo4j/graphdatabases/dataset_builders/SimpleSocialNetwork.java:
--------------------------------------------------------------------------------
1 | package org.neo4j.graphdatabases.dataset_builders;
2 |
3 | import java.io.File;
4 |
5 | import org.junit.Test;
6 |
7 | import org.neo4j.graphdatabases.SimpleSocialNetworkConfig;
8 | import org.neo4j.graphdatabases.queries.helpers.DbUtils;
9 | import org.neo4j.graphdb.GraphDatabaseService;
10 | import org.neo4j.graphdb.factory.GraphDatabaseFactory;
11 | import org.neo4j.kernel.impl.util.FileUtils;
12 | import org.neo4j.neode.Dataset;
13 | import org.neo4j.neode.DatasetManager;
14 | import org.neo4j.neode.NodeCollection;
15 | import org.neo4j.neode.NodeSpecification;
16 | import org.neo4j.neode.RelationshipSpecification;
17 | import org.neo4j.neode.logging.Log;
18 | import org.neo4j.neode.logging.SysOutLog;
19 | import org.neo4j.neode.statistics.AsciiDocFormatter;
20 | import org.neo4j.neode.statistics.GraphStatistics;
21 |
22 | import static org.neo4j.neode.Range.minMax;
23 | import static org.neo4j.neode.RelationshipUniqueness.BOTH_DIRECTIONS;
24 | import static org.neo4j.neode.TargetNodesStrategy.getExisting;
25 | import static org.neo4j.neode.properties.Property.indexableProperty;
26 |
27 | public class SimpleSocialNetwork
28 | {
29 | @Test
30 | public void buildSocialNetwork() throws Exception
31 | {
32 | File dir = new File( SimpleSocialNetworkConfig.STORE_DIR );
33 | FileUtils.deleteRecursively( dir );
34 |
35 | GraphDatabaseService db = new GraphDatabaseFactory()
36 | .newEmbeddedDatabaseBuilder( SimpleSocialNetworkConfig.STORE_DIR )
37 | .setConfig( DbUtils.dbConfig() )
38 | .newGraphDatabase();
39 | createSampleDataset( db );
40 |
41 | GraphStatistics.create( db, SimpleSocialNetworkConfig.TITLE )
42 | .describeTo( new AsciiDocFormatter( SysOutLog.INSTANCE ) );
43 |
44 | db.shutdown();
45 | }
46 |
47 | private void createSampleDataset( GraphDatabaseService db )
48 | {
49 | DatasetManager dsm = new DatasetManager( db, new Log()
50 | {
51 | @Override
52 | public void write( String value )
53 | {
54 | System.out.println( value );
55 | }
56 | } );
57 |
58 | NodeSpecification userSpec = dsm.nodeSpecification(
59 | "User", indexableProperty( db, "User", "name" ) );
60 | RelationshipSpecification friend =
61 | dsm.relationshipSpecification( "FRIEND" );
62 |
63 | Dataset dataset =
64 | dsm.newDataset( "Simple social network example" );
65 |
66 | NodeCollection users =
67 | userSpec.create( SimpleSocialNetworkConfig.NUMBER_USERS )
68 | .update( dataset );
69 |
70 | users.createRelationshipsTo(
71 | getExisting( users )
72 | .numberOfTargetNodes( minMax( SimpleSocialNetworkConfig.MIN_NUMBER_OF_FRIENDS,
73 | SimpleSocialNetworkConfig.MAX_NUMBER_OF_FRIENDS ) )
74 | .relationship( friend )
75 | .relationshipConstraints( BOTH_DIRECTIONS ) )
76 | .updateNoReturn( dataset, 20000 );
77 |
78 | dataset.end();
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/data-generation/src/test/java/org/neo4j/graphdatabases/dataset_builders/SocialNetwork.java:
--------------------------------------------------------------------------------
1 | package org.neo4j.graphdatabases.dataset_builders;
2 |
3 | import java.io.File;
4 |
5 | import org.junit.Test;
6 |
7 | import org.neo4j.graphdatabases.SocialNetworkConfig;
8 | import org.neo4j.graphdatabases.dataset_builders.properties.DurationOnProjectProperty;
9 | import org.neo4j.graphdatabases.dataset_builders.properties.ProjectDurationProperty;
10 | import org.neo4j.graphdatabases.dataset_builders.traversers.FindAllColleagues;
11 | import org.neo4j.graphdatabases.dataset_builders.traversers.IsCompanyProject;
12 | import org.neo4j.graphdatabases.queries.helpers.DbUtils;
13 | import org.neo4j.graphdb.Direction;
14 | import org.neo4j.graphdb.GraphDatabaseService;
15 | import org.neo4j.graphdb.factory.GraphDatabaseFactory;
16 | import org.neo4j.graphdb.traversal.TraversalDescription;
17 | import org.neo4j.kernel.Traversal;
18 | import org.neo4j.kernel.Uniqueness;
19 | import org.neo4j.kernel.impl.util.FileUtils;
20 | import org.neo4j.neode.Dataset;
21 | import org.neo4j.neode.DatasetManager;
22 | import org.neo4j.neode.NodeCollection;
23 | import org.neo4j.neode.NodeSpecification;
24 | import org.neo4j.neode.RelationshipSpecification;
25 | import org.neo4j.neode.RelationshipUniqueness;
26 | import org.neo4j.neode.logging.SysOutLog;
27 | import org.neo4j.neode.properties.Property;
28 | import org.neo4j.neode.statistics.AsciiDocFormatter;
29 | import org.neo4j.neode.statistics.GraphStatistics;
30 |
31 | import static org.neo4j.graphdb.DynamicRelationshipType.withName;
32 | import static org.neo4j.neode.GraphQuery.traversal;
33 | import static org.neo4j.neode.Range.minMax;
34 | import static org.neo4j.neode.TargetNodesStrategy.getExisting;
35 | import static org.neo4j.neode.TargetNodesStrategy.getOrCreate;
36 | import static org.neo4j.neode.TargetNodesStrategy.queryBasedGetOrCreate;
37 | import static org.neo4j.neode.probabilities.ProbabilityDistribution.flatDistribution;
38 | import static org.neo4j.neode.probabilities.ProbabilityDistribution.normalDistribution;
39 | import static org.neo4j.neode.properties.Property.indexableProperty;
40 | import static org.neo4j.neode.properties.Property.property;
41 |
42 | public class SocialNetwork
43 | {
44 | @Test
45 | public void buildSocialNetwork() throws Exception
46 | {
47 | File dir = new File( SocialNetworkConfig.STORE_DIR );
48 | FileUtils.deleteRecursively( dir );
49 |
50 | GraphDatabaseService db = new GraphDatabaseFactory()
51 | .newEmbeddedDatabaseBuilder( SocialNetworkConfig.STORE_DIR )
52 | .setConfig( DbUtils.dbConfig() )
53 | .newGraphDatabase();
54 | DatasetManager dsm = new DatasetManager( db, SysOutLog.INSTANCE );
55 |
56 | TraversalDescription findCompanyProjects = createFindCompanyProjectsTraversalDescription();
57 | Property projectDuration = new ProjectDurationProperty();
58 | Property durationOnProject = new DurationOnProjectProperty();
59 |
60 | NodeSpecification userSpec = dsm.nodeSpecification( "User", indexableProperty(db, "User", "name" ) );
61 | NodeSpecification topicSpec = dsm.nodeSpecification( "Topic", indexableProperty(db, "Topic", "name" ) );
62 | NodeSpecification companySpec = dsm.nodeSpecification( "Company", indexableProperty(db, "company", "name" ) );
63 | NodeSpecification projectSpec = dsm.nodeSpecification( "Project",
64 | property( "name" ),
65 | projectDuration );
66 |
67 | RelationshipSpecification interested_in = dsm.relationshipSpecification( "INTERESTED_IN" );
68 | RelationshipSpecification works_for = dsm.relationshipSpecification( "WORKS_FOR" );
69 | RelationshipSpecification worked_on = dsm.relationshipSpecification( "WORKED_ON", durationOnProject );
70 | RelationshipSpecification worked_with = dsm.relationshipSpecification( "WORKED_WITH" );
71 |
72 | Dataset dataset = dsm.newDataset( "Social network example" );
73 |
74 | NodeCollection users = userSpec.create( SocialNetworkConfig.NUMBER_USERS ).update( dataset );
75 |
76 | users.createRelationshipsTo(
77 | getOrCreate( topicSpec, SocialNetworkConfig.NUMBER_TOPICS, normalDistribution() )
78 | .numberOfTargetNodes( minMax( 1, 3 ) )
79 | .relationship( interested_in )
80 | .exactlyOneRelationship() )
81 | .updateNoReturn( dataset );
82 |
83 | users.createRelationshipsTo(
84 | getOrCreate( companySpec, SocialNetworkConfig.NUMBER_COMPANIES, flatDistribution() )
85 | .numberOfTargetNodes( 1 )
86 | .relationship( works_for )
87 | .exactlyOneRelationship() )
88 | .updateNoReturn( dataset );
89 |
90 | NodeCollection allProjects = users.createRelationshipsTo(
91 | queryBasedGetOrCreate( projectSpec, traversal( findCompanyProjects ), 5.0 )
92 | .numberOfTargetNodes( minMax( 1, 5 ), normalDistribution() )
93 | .relationship( worked_on )
94 | .exactlyOneRelationship() )
95 | .update( dataset );
96 |
97 | users.approxPercentage( 30 ).createRelationshipsTo(
98 | getExisting( allProjects )
99 | .numberOfTargetNodes( minMax( 1, 2 ), normalDistribution() )
100 | .relationship( worked_on )
101 | .relationshipConstraints( RelationshipUniqueness.BOTH_DIRECTIONS ) )
102 | .update( dataset );
103 |
104 | users.createRelationshipsTo(
105 | getExisting( new FindAllColleagues() )
106 | .numberOfTargetNodes( 1 )
107 | .relationship( worked_with )
108 | .exactlyOneRelationship() )
109 | .updateNoReturn( dataset, 5000 );
110 |
111 |
112 | dataset.end();
113 |
114 | GraphStatistics.create( db, SocialNetworkConfig.TITLE ).describeTo(
115 | new AsciiDocFormatter( SysOutLog.INSTANCE ) );
116 |
117 | db.shutdown();
118 | }
119 |
120 | private TraversalDescription createFindCompanyProjectsTraversalDescription()
121 | {
122 | return Traversal.description()
123 | .depthFirst()
124 | .uniqueness( Uniqueness.NODE_GLOBAL )
125 | .relationships( withName( "WORKS_FOR" ), Direction.BOTH )
126 | .relationships( withName( "WORKED_ON" ), Direction.OUTGOING )
127 | .evaluator( new IsCompanyProject() );
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/data-generation/src/test/java/org/neo4j/graphdatabases/dataset_builders/helpers/SevenDays.java:
--------------------------------------------------------------------------------
1 | package org.neo4j.graphdatabases.dataset_builders.helpers;
2 |
3 | import static java.util.Arrays.asList;
4 |
5 | import java.util.ArrayList;
6 | import java.util.Collections;
7 | import java.util.List;
8 | import java.util.Random;
9 |
10 | import org.joda.time.DateTime;
11 | import org.joda.time.Interval;
12 |
13 | public class SevenDays
14 | {
15 | private final DateTime start;
16 | private final Random random;
17 |
18 | @SuppressWarnings( "unchecked" )
19 | private static final List> days = asList(
20 | asList( 1, 1, 5 ),
21 | asList( 1, 2, 4 ),
22 | asList( 1, 3, 3 ),
23 | asList( 2, 2, 3 ) );
24 |
25 | public SevenDays( DateTime start )
26 | {
27 | this.start = start;
28 | this.random = new Random();
29 | }
30 |
31 | public Iterable calculateIntervals( int numberOfIntervals )
32 | {
33 | if ( numberOfIntervals < 1 || numberOfIntervals > 3 )
34 | {
35 | throw new IllegalArgumentException( "numberOfIntervals must be 1 or 3" );
36 | }
37 |
38 | List intervals = new ArrayList();
39 |
40 | if ( numberOfIntervals == 1 )
41 | {
42 | intervals.add( new Interval( start, start.plusDays( 7 ) ) );
43 | }
44 | else if ( numberOfIntervals == 2 )
45 | {
46 | int numberOfDays = random.nextInt( 6 ) + 1;
47 | DateTime mid = start.plusDays( numberOfDays );
48 | intervals.add( new Interval( start, mid ) );
49 | intervals.add( new Interval( mid, start.plusDays( 7 ) ) );
50 | }
51 | else
52 | {
53 | int i = random.nextInt( days.size() );
54 | List plusDays = days.get( i );
55 | Collections.shuffle( plusDays, random );
56 |
57 | DateTime mid1 = start.plusDays( plusDays.get( 0 ) );
58 | DateTime mid2 = mid1.plusDays( plusDays.get( 1 ) );
59 |
60 | intervals.add( new Interval( start, mid1 ) );
61 | intervals.add( new Interval( mid1, mid2 ) );
62 | intervals.add( new Interval( mid2, start.plusDays( 7 ) ) );
63 | }
64 |
65 | return intervals;
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/data-generation/src/test/java/org/neo4j/graphdatabases/dataset_builders/properties/DurationOnProjectProperty.java:
--------------------------------------------------------------------------------
1 | package org.neo4j.graphdatabases.dataset_builders.properties;
2 |
3 | import org.neo4j.graphdb.GraphDatabaseService;
4 | import org.neo4j.graphdb.Node;
5 | import org.neo4j.graphdb.PropertyContainer;
6 | import org.neo4j.graphdb.Relationship;
7 | import org.neo4j.neode.properties.Property;
8 |
9 | public class DurationOnProjectProperty extends Property
10 | {
11 | @Override
12 | public void setProperty( PropertyContainer propertyContainer, GraphDatabaseService graphDatabaseService,
13 | String s, int i )
14 | {
15 | Node endNode = ((Relationship) propertyContainer).getEndNode();
16 |
17 | Long startDateTime = (Long) endNode.getProperty( "start_date" );
18 | Long endDateTime = (Long) endNode.getProperty( "end_date" );
19 | ProjectDuration projectDuration = new ProjectDuration( startDateTime, endDateTime );
20 | ProjectDuration durationOnProject = projectDuration.getSubDuration();
21 |
22 | propertyContainer.setProperty( "duration", durationOnProject.toString() );
23 | propertyContainer.setProperty( "start_date", durationOnProject.getStartDateMs() );
24 | propertyContainer.setProperty( "end_date", durationOnProject.getEndDateMs() );
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/data-generation/src/test/java/org/neo4j/graphdatabases/dataset_builders/properties/ProjectDuration.java:
--------------------------------------------------------------------------------
1 | package org.neo4j.graphdatabases.dataset_builders.properties;
2 |
3 | import static org.neo4j.neode.Range.minMax;
4 | import static org.neo4j.neode.probabilities.ProbabilityDistribution.normalDistribution;
5 |
6 | import org.joda.time.DateTime;
7 | import org.joda.time.DateTimeZone;
8 | import org.joda.time.Duration;
9 | import org.joda.time.format.DateTimeFormat;
10 | import org.joda.time.format.DateTimeFormatter;
11 | import org.neo4j.neode.probabilities.ProbabilityDistribution;
12 |
13 | public class ProjectDuration
14 | {
15 | private static final ProbabilityDistribution normalDistribution = normalDistribution();
16 | private static final DateTimeFormatter fmt = DateTimeFormat.forPattern( "dd-MM-yyyy" );
17 |
18 | private final Long startMs;
19 | private final Long endMs;
20 |
21 | public ProjectDuration( Long startMs, Long endMs )
22 | {
23 | this.endMs = endMs;
24 | this.startMs = startMs;
25 | }
26 |
27 | public Long getStartDateMs()
28 | {
29 | return startMs;
30 | }
31 |
32 | public Long getEndDateMs()
33 | {
34 | return endMs;
35 | }
36 |
37 | public ProjectDuration getSubDuration()
38 | {
39 | DateTime startDateTime = new DateTime( startMs, DateTimeZone.UTC );
40 | DateTime endDateTime = new DateTime( endMs, DateTimeZone.UTC );
41 |
42 | int durationInDays = (int) new Duration( startDateTime, endDateTime ).getStandardDays();
43 | int offsetDaysFromStart = normalDistribution.generateSingle( minMax( 0, (int) (durationInDays * 0.75) ) );
44 | int remainingDays = durationInDays - offsetDaysFromStart;
45 | int subDurationInDays = (int) ((remainingDays * 0.75) +
46 | (normalDistribution.generateSingle( minMax( 0, (int) (remainingDays * (0.25)) ) )));
47 |
48 | DateTime subDurationStartDateTime = startDateTime.plusDays( offsetDaysFromStart );
49 | DateTime subDurationEndDateTime = subDurationStartDateTime.plusDays( subDurationInDays );
50 |
51 | return new ProjectDuration( subDurationStartDateTime.getMillis(), subDurationEndDateTime.getMillis() );
52 | }
53 |
54 | public String toString()
55 | {
56 | return "Start: " + new DateTime( startMs, DateTimeZone.UTC ).toString( fmt )
57 | + ", End : " + new DateTime( endMs, DateTimeZone.UTC ).toString( fmt );
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/data-generation/src/test/java/org/neo4j/graphdatabases/dataset_builders/properties/ProjectDurationGenerator.java:
--------------------------------------------------------------------------------
1 | package org.neo4j.graphdatabases.dataset_builders.properties;
2 |
3 | import java.util.Random;
4 |
5 | import org.joda.time.DateTime;
6 | import org.joda.time.DateTimeZone;
7 |
8 | public class ProjectDurationGenerator
9 | {
10 | private final static DateTime durationLowerLimit = new DateTime(2000, 1, 1, 0, 0, DateTimeZone.UTC);
11 | private final Random rand = new Random();
12 |
13 | public ProjectDuration getNextProjectDuration()
14 | {
15 | DateTime startDateTime = durationLowerLimit.plusMonths( rand.nextInt( 9 *12 ) );
16 | DateTime endDateTime = startDateTime.plusMonths( 3 + (rand.nextInt(33)) ) ;
17 | return new ProjectDuration( startDateTime.getMillis(), endDateTime.getMillis() );
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/data-generation/src/test/java/org/neo4j/graphdatabases/dataset_builders/properties/ProjectDurationProperty.java:
--------------------------------------------------------------------------------
1 | package org.neo4j.graphdatabases.dataset_builders.properties;
2 |
3 | import org.neo4j.graphdb.GraphDatabaseService;
4 | import org.neo4j.graphdb.PropertyContainer;
5 | import org.neo4j.neode.properties.Property;
6 |
7 | public class ProjectDurationProperty extends Property
8 | {
9 | private final ProjectDurationGenerator generator = new ProjectDurationGenerator();
10 |
11 | @Override
12 | public void setProperty( PropertyContainer propertyContainer, GraphDatabaseService graphDatabaseService,
13 | String s, int i )
14 | {
15 | ProjectDuration projectDuration = generator.getNextProjectDuration();
16 | propertyContainer.setProperty( "duration", projectDuration.toString() );
17 | propertyContainer.setProperty( "start_date", projectDuration.getStartDateMs() );
18 | propertyContainer.setProperty( "end_date", projectDuration.getEndDateMs() );
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/data-generation/src/test/java/org/neo4j/graphdatabases/dataset_builders/traversers/FindAllColleagues.java:
--------------------------------------------------------------------------------
1 | package org.neo4j.graphdatabases.dataset_builders.traversers;
2 |
3 | import static org.neo4j.graphdb.DynamicRelationshipType.withName;
4 |
5 | import org.neo4j.graphalgo.GraphAlgoFactory;
6 | import org.neo4j.graphalgo.PathFinder;
7 | import org.neo4j.graphdb.Direction;
8 | import org.neo4j.graphdb.Node;
9 | import org.neo4j.graphdb.Path;
10 | import org.neo4j.graphdb.PathExpander;
11 | import org.neo4j.graphdb.Relationship;
12 | import org.neo4j.graphdb.RelationshipExpander;
13 | import org.neo4j.graphdb.RelationshipType;
14 | import org.neo4j.graphdb.traversal.BranchState;
15 | import org.neo4j.graphdb.traversal.Evaluation;
16 | import org.neo4j.graphdb.traversal.Evaluator;
17 | import org.neo4j.graphdb.traversal.TraversalDescription;
18 | import org.neo4j.kernel.Traversal;
19 | import org.neo4j.kernel.Uniqueness;
20 | import org.neo4j.neode.GraphQuery;
21 |
22 | public class FindAllColleagues extends GraphQuery
23 | {
24 | private static final RelationshipType WORKED_ON = withName( "WORKED_ON" );
25 | private static PathFinder workedWithPathFinder = GraphAlgoFactory.shortestPath( Traversal.expanderForTypes( withName( "WORKED_WITH" )), 1 );
26 | private static final TraversalDescription traversal = Traversal.description()
27 | .depthFirst()
28 | .uniqueness( Uniqueness.NODE_GLOBAL )
29 | .expand( new WorkOnPathExpander() )
30 | .evaluator( new Evaluator()
31 | {
32 | @Override
33 | public Evaluation evaluate( Path path )
34 | {
35 | if ( path.length() == 2 )
36 | {
37 | if ( workedWithPathFinder.findSinglePath( path.startNode(), path.endNode() ) == null)
38 | {
39 | return Evaluation.INCLUDE_AND_PRUNE;
40 | }
41 | else
42 | {
43 | return Evaluation.EXCLUDE_AND_PRUNE;
44 | }
45 | }
46 | return Evaluation.EXCLUDE_AND_CONTINUE;
47 | }
48 | } );
49 |
50 | @Override
51 | public Iterable execute( Node node )
52 | {
53 | return traversal.traverse( node ).nodes();
54 | }
55 |
56 | private static class WorkOnPathExpander implements PathExpander