Bert Radke
Senior Graph Consultant @Neo4j
Fediverse: @taseroth@chaos.social
Bert Radke
Senior Graph Consultant @Neo4j
Fediverse: @taseroth@chaos.social
*.jar
Inside /plugins/
Loaded at Startup
Live inside Neo4j JVM
Annotated with @Procedure
or @UserFunction
@Procedure("example.getRelationshipTypes",
mode = Mode.READ)
@Description("Get the different relationships going
in and out of a node.")
public Stream<RelationshipTypes>
getRelationshipTypes(@Name("node") Node node) {
@Context
public GraphDatabaseService db;
@Context
public Log log;
@Context
public Transaction tx;
Class: org.neo4j.logging.Log
Log levels: error, warn, info, debug
Placeholders: LOG.info("deleted %d nodes", nbNodes)
Class: org.neo4j.graphdb.Transaction
Starting point for most procedures
tx.createNode(Label.label("Movie"), Label.label("SciFi"));
tx.findNodes(Label.label("Person"), "surName", "Tom");
Class: org.neo4j.graphdb.GraphDatabaseService
Starting of new Transactions db.beginTx();
Name of the current database db.databaseName()
MATCH (hanks:Person {name: 'Tom Hanks'})-[:DIRECTED]->(movie)
return collect(movie.title)
var hanks = tx.findNode(Label.label("Person"),
"name", "Tom Hanks");
StreamSupport.stream(
hanks.getRelationships(
Direction.OUTGOING, RelationshipType.withName("DIRECTED"))
.spliterator(), false)
.map(Relationship::getEndNode)
.map(movie -> movie.getProperty("title"))
.collect(Collectors.toSet());
Transactions bound to Threads
Entities proxies bound to Transactions
Do NOT pass Entities to Threads
var nodeId = node.getId();
var node = tx.getNodeById(nodeId);
TraversalDescription traverseDescription =
db.beginTx().traversalDescription()
.uniqueness(NODE_GLOBAL)
.breadthFirst()
.expandand(new AllExpander())
.evaluationluator(new GreenEvaluator(minimumGreen))
Traverser traverser = traverseDescription.traverse(startNodes);
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class JoinTest {
private static final Config driverConfig =
Config.builder().withoutEncryption().build();
private Neo4j embeddedDb;
@BeforeAll
void initializeNeo4j() {
this.embeddedDb = Neo4jBuilders.newInProcessBuilder()
.withDisabledServer()
.withFunction(Join.class)
.withFixture(..)
.build();
}
@Test
void joinsStrings() {
try(
Driver driver = GraphDatabase.driver(
embeddedDb.boltURI(),
driverConfig);
Session session = driver.session()
) {
var result = session.run("CALL our.procedure()");
}
}
PRO
Maximum Flexibility
Parallel Execution
CON
Harder to maintain and test
Deployment needs Server-Restart
Not available on Aura
No EXPLAIN
or PROFILE
GitHub Template Repository
Contains examples, build and test infrastructure
Thank you for listening