© 2022 Neo4j, Inc. All rights reserved.
Michael Hunger,
Senior Director, User Innovation
@mesirii
Boost Your Neo4j Experience
with User-Defined Procedures
© 2022 Neo4j, Inc. All rights reserved.
2
Outline
• Why should I care?
• Hello World Example
• UDP bridge the gap
• Java API vs. Cypher
• When should I use UDP? When should I build one?
• Development / Testing / Deployment
• Pro's and Cons
• Real Example
• Procedure Libraries
◦ APOC, GDS, neosemantics
© 2022 Neo4j, Inc. All rights reserved.
3
Why should I care?
1 2
Efficiency Encapsulation
3 4
Integration Portability
© 2022 Neo4j, Inc. All rights reserved.
4
Hello World Example
public class Hello {
@UserFunction
public String hello(@Name(„text“) String text) {
if (text == null) {
return null;
}
return String.format(„Hello %s!“, text);
}
}
© 2022 Neo4j, Inc. All rights reserved.
User Defined Procedures & Functions
Neo4j Execution Engine
User Defined
Procedure
Applications
Bolt
User Defined Procedures & Functions let
you write custom code that is:
• Written in any JVM language
• Deployed to the Database
• Accessed by applications via Cypher
User Defined
Functions
5
© 2022 Neo4j, Inc. All rights reserved.
Built-in procedures
SHOW PROCEDURES
© 2022 Neo4j, Inc. All rights reserved.
Example: Listing all relationship types
CALL db.relationshipTypes()
© 2022 Neo4j, Inc. All rights reserved.
Usage
CALL dbms.listQueries()
YIELD queryId, query, username, elapsedTimeMillis, activeLockCount
WHERE elapsedTimeMillis > 1000
CALL dbms.killQuery(queryId) yield message
RETURN queryId, substring(query,0,100) as query, username,
elapsedTimeMillis, activeLockCount, message
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
9
User Defined
● Procedures
● Functions
● Aggregation Functions
Bridge the Gap
© 2022 Neo4j, Inc. All rights reserved.
10
Bridging the Gap
1 2
Exposed in
Cypher
Composable
Lego Blocks
3 4
Extend with
new
functionality
Power &
Ease
© 2022 Neo4j, Inc. All rights reserved.
11
Procedures
● read / write
● stateless
● stream results
● standalone and
embedded
call proc(param)
yield value1,
value2
What is available? User Defined …
Functions
● read-only
● stateless
● single result
● in expressions
return func(param)
as value
Aggregation
Functions
● read-only
● stateful
● agg results
● in aggregations
return key,
agg(value) as
aggregated
© 2022 Neo4j, Inc. All rights reserved.
12
When should I use user defined procedures & functions?
1 2
Functionality Performance
3 4
Compact-
ness
Missing
Cypher
Capability
© 2022 Neo4j, Inc. All rights reserved.
13
Development
© 2022 Neo4j, Inc. All rights reserved.
14
When should I create a user defined procedures?
1 2
Business
spec.need
Performance
SLA
3 4
Required
Integration
Missing
Cypher
Capability
© 2022 Neo4j, Inc. All rights reserved.
15
Cypher vs. Java API
• original API
• low level
• imperative
• only available in database
extensions
• allows access to all Java data
and control structures
• additional concurrency
• easy to learn, write, maintain
• declarative
• graph patterns
• available through drivers &
tools
• limited data- and control-
structures
15
© 2022 Neo4j, Inc. All rights reserved.
● any JVM language
● separate
procedure-layer
from
implementation
● avoid accessing
internal APIs
16
Develop
Development Cycle
Test
● can be unit tested
● Testcontainers for
integration tests
● IT also for
dependencies and
bolt integration
● biggest pain point
● version matches
● provide or
package
dependencies
● requires restart
● all cluster
members
Deploy
© 2022 Neo4j, Inc. All rights reserved.
17
Pros and Cons
• More involved code to maintain
long-term (JVM skills)
• Deployment (server restart, aura,
cluster)
• No planner participation
• No resource mgmt participation
• No feedback about internal
operations
• Need to know what you are
doing
• Composable Lego blocks
• Encapsulate functionality
• Write once then reuse
• Most Java language features
• Testable with Unit testing
• Refactoring
• Apply permissions to
procedures
17
© 2022 Neo4j, Inc. All rights reserved.
18
User Defined Function Example
© 2022 Neo4j, Inc. All rights reserved.
User Defined Functions
● @UserFunction annotated, named Java Methods
○ default name: package + method
● take @Name'ed parameters (with default values)
● return a single value
● are read only
● can use @Context injected GraphDatabaseService and others
● run within transaction of the Cypher statement
19
© 2022 Neo4j, Inc. All rights reserved.
20
Simple Function (Join)
public class Join {
@UserFunction
@Description("example.join(['s1','s2',...], delimiter) –
join the given strings with the given delimiter.")
public String join(
@Name("strings") List<String> strings,
@Name(value = "delimiter", defaultValue = ",") String delimiter) {
if (strings == null || delimiter == null) {
return null;
}
return String.join(delimiter, strings);
}
}
© 2022 Neo4j, Inc. All rights reserved.
Calling the function from Cypher:
RETURN example.join(["Hello", "World", "Austin"], "-")
-> „Hello-World-Austin!“
Calling from Cypher
21
© 2022 Neo4j, Inc. All rights reserved.
1. Deploy & Register in
Neo4j Server via
neo4j-harness
2. Call & test via
neo4j-java-
driver
Test Code
22
© 2022 Neo4j, Inc. All rights reserved.
● Build or download (shadow) jar
● Drop jar-file into $NEO4J_HOME/plugins
● For sandboxed / allow-listing, need to edit neo4j.conf
dbms.security.procedures.unrestricted=example.*
● Restart server
● Functions & Procedures should be available (show procedures)
● Otherwise check neo4j.log / debug.log
Deploying User Defined Code
23
© 2022 Neo4j, Inc. All rights reserved.
24
User Defined Procedure Example
© 2022 Neo4j, Inc. All rights reserved.
User Defined Procedures
● @Procedure annotated, named Java Methods
● additional mode attribute (Read, Write, Dbms, Schema)
● return a Stream of value objects (DTO) with public fields
● value object fields are turned into columns
● Runs as part of outer transaction
● Injection of @Context fields, like Transaction, Log, Database
● Same testing & deployment as functions
github.com/neo4j-examples/neo4j-procedure-template
25
© 2022 Neo4j, Inc. All rights reserved.
Procedure Code Example (Dijkstra)
@Procedure
@Description("apoc.algo.dijkstra(startNode, endNode, 'KNOWS', 'distance') YIELD path," +
" weight - run dijkstra with relationship property name as cost function")
public Stream<WeightedPathResult> dijkstra(
@Name("startNode") Node startNode,
@Name("endNode") Node endNode,
@Name("type") String type,
@Name("costProperty") String costProperty) {
PathFinder<WeightedPath> algo = GraphAlgoFactory.dijkstra(
PathExpanders.forType(RelationshipType.withName(type)),
costProperty);
Iterable<WeightedPath> allPaths = algo.findAllPaths(startNode, endNode);
return StreamSupport.stream(allPaths.spliterator(), false)
.map(WeightedPathResult::new);
}
26
© 2022 Neo4j, Inc. All rights reserved.
28
Realworld Example
Optimizing Category/Genre
Overlap
© 2022 Neo4j, Inc. All rights reserved.
29
Task: Category/Tag Overlap
Given a set of categories (names) find all items
that are in at least in these categories.
Simple for one, two or three categories:
MATCH (question)-[:TAGGED]->(:Tag {name:$name1}),
(question)-[:TAGGED]->(:Tag {name:$name2})
But not optimal, and not arbitrary.
© 2022 Neo4j, Inc. All rights reserved.
Example Query - Tag Overlap
PROFILE
WITH ['cypher','neo4j', 'python'] AS tagNames
UNWIND tagNames AS name
MATCH (t:Tag {name:name})<-[:TAGGED]-(q:Question)
WITH q, collect(t) AS tags, tagNames
WHERE size(tags) = size(tagNames)
RETURN q
// 2.075.518 total db hits
30
© 2022 Neo4j, Inc. All rights reserved.
Example Query - Tag Overlap
PROFILE
WITH ['cypher','neo4j', 'python'] AS tagNames
MATCH (t:Tag)<-[:TAGGED]-(q:Question)
WHERE t.name IN tagNames
WITH q, collect(t) AS tags, tagNames
WHERE size(tags) = size(tagNames)
RETURN q LIMIT 10
// 2.075.518 db-hits
31
© 2022 Neo4j, Inc. All rights reserved.
Example Query - Tag Overlap - Optimized
PROFILE
WITH ['cypher','neo4j', 'python'] AS tagNames
UNWIND tagNames AS name
MATCH (t:Tag {name:name})
// lowest degree first
WITH t ORDER BY size( (t)<-[:TAGGED]-() ) ASC
WITH collect(t) AS tags
WITH head(tags) AS first, tail(tags) AS rest
MATCH (first)<-[:TAGGED]-(q:Question)
WHERE all(t IN rest WHERE (q)-[:TAGGED]->(t))
RETURN q
// 89.137 total db hits
32
© 2022 Neo4j, Inc. All rights reserved.
Example Query - Tag Overlap - Optimized (2)
PROFILE
WITH ['cypher','neo4j', 'python'] AS tagNames
UNWIND tagNames AS name
MATCH (t:Tag {name:name})
// lowest degree first
WITH t ORDER BY size( (t)<-[:TAGGED]-() ) ASC
WITH collect(t) AS tags
WITH head(tags) AS first, tail(tags) AS rest
MATCH (first)<-[:TAGGED]-(q:Question)-[:TAGGED]->(other)
WITH q, collect(other) AS questionTags, rest
WHERE all(t IN rest WHERE t IN questionTags)
RETURN q
// 55.660 total db hits
33
© 2022 Neo4j, Inc. All rights reserved.
Example - Tag Overlap - Procedure
1. pass in list of tag names
2. find tag with least questions (degree) as driver
3. put other tags into Set
4. iterate over questions of minimal tag
5. for each question
6. for each tag that is in set increment counter
7. if counter = Set size
a. add/stream question to result
34
© 2022 Neo4j, Inc. All rights reserved.
Example - Genre Overlap - Procedure - Code (1)
// Procedure class with injection
public class SharedTags {
@Context public GraphDatabaseService gdb;
@Context public Log log;
enum Types implements RelationshipType {
TAGGED;
}
enum Labels implements Label {
Tag, Question
}
}
35
© 2022 Neo4j, Inc. All rights reserved.
Example - Genre Overlap - Procedure - Code (2)
// Return Type, each field a column
public static class QuestionTag {
public String title;
public String tag;
public double weight;
public QuestionTag(String title,
String tag,
double weight) {
this.title = title;
this.tag = tag;
this.weight = weight;
}
}
36
© 2022 Neo4j, Inc. All rights reserved.
Example - Genre Overlap - Procedure - Code (3)
@Procedure
public Stream<QuestionTag> sharedGenres(
@Name(”tagNames") List<String> tagNames) {
int tagCount = tagNames.size();
// lookup and order tags by degree ascending
List<Pair<Node, Integer>> tags =
tagNames.stream().map(tagName -> {
Node tag = gdb.findNode(Labels.Tag, "name", tagName);
return Pair.of(tag, tag.getDegree(Types.TAGGED,
Direction.INCOMING));
}).sorted((p1, p2) -> compare(p1.other(), p2.other())).toList();
37
© 2022 Neo4j, Inc. All rights reserved.
Example - Genre Overlap - Procedure - Code (4)
// find questions for the tag with the lowest degree
var driver = tags.get(0);
var questions = new HashMap<>(driver.other());
for (Relationship e0 : driver.first()
.getRelationships(Direction.INCOMING, Types.TAGGED)) {
Node question = e0.getStartNode();
questions.put(question,
new ArrayList<>(List.of(Pair.of(driver.first(), e0))));
}
38
© 2022 Neo4j, Inc. All rights reserved.
// check and add to found questions for remainder of tags
for (Pair<Node, Integer> tag : tags.subList(1, tags.size())) {
Node node = tag.first();
for (Relationship e1 : node.getRelationships(Direction.INCOMING,
Types.TAGGED)) {
Node question = e1.getStartNode();
if (questions.containsKey(question)) {
questions.get(question).add(Pair.of(tag.first(), e1));
}
}
}
Example - Genre Overlap - Procedure - Code (5)
39
© 2022 Neo4j, Inc. All rights reserved.
// transform map into result stream
return questions.entrySet().stream()
.filter(entry -> entry.getValue().size() == tagCount)
.flatMap(entry -> {
String title = (String) entry.getKey().getProperty("title", null);
return entry.getValue().stream().map(tagRel -> {
String tagName = (String) tagRel.first().getProperty("name");
Number weight = (Number)tagRel.other().getProperty("weight",0);
return new QuestionTag(title, tagName, weight.doubleValue());
});
});
}
}
Example - Genre Overlap - Procedure - Code (6)
40
© 2022 Neo4j, Inc. All rights reserved.
41
Existing Procedure Libraries
© 2022 Neo4j, Inc. All rights reserved.
42
Existing Procedure Libraries
1 2
Built-in APOC
3 4
graph
data
science
neosemantics
© 2022 Neo4j, Inc. All rights reserved.
43
Built In Procedures
Many built-in procedures are phased out for admin commands – Not a fan.
• Indexes & constraints esp. Fulltext (phased out)
• Schema visualization / data
• Cluster management
• Security / User Mmgt (phased out)
• Database state
• Procedures & Functions (phased out)
• Query, Transaction, Connection Management (phased out)
• Configuration Management
• Memory Pools
• Scheduler
© 2022 Neo4j, Inc. All rights reserved.
44
Areas Of Use (APOC)
© 2022 Neo4j, Inc. All rights reserved.
45
Graph Data Science
© 2022 Neo4j, Inc. All rights reserved.
46
neosemantics
© 2022 Neo4j, Inc. All rights reserved.
47
Learn more
1 2
Docs
neo4j.com/docs/java-reference
Guides
neo4j.com/developer/cypher/procedures-functions/
3 4
Example
github.com/neo4j-examples/
neo4j-procedure-template
Read the
source!
© 2022 Neo4j, Inc. All rights reserved.
48
Q&A
© 2022 Neo4j, Inc. All rights reserved.
49
Thank you!
Follow me: @mesirii
© 2022 Neo4j, Inc. All rights reserved.
• Why do we need user defined procedures and functions?
• Syntax & built in procedures
• The APOC procedure library
• Helper functions
• Data integration
• Graph algorithms
• Graph refactoring / Transaction management
• How to write and test your own procedure / function
• Turn Cypher queries into procedures
What will we learn?
© 2022 Neo4j, Inc. All rights reserved.
What are User Defined
Procedures and Functions?
© 2022 Neo4j, Inc. All rights reserved.
Neo4j Developer Surface
Native LanguageDrivers
BOLT User Defined
Procedure
2000-2010 0.x - Embedded Java API
2010-2014 1.x - REST
2014-2015 2.x - Cypher over HTTP
2016 - 3.0.x - Bolt, Official Language Drivers, and User Defined Procedures
3.1.x - User Defined Functions
© 2022 Neo4j, Inc. All rights reserved.
Using User Defined Procedures
© 2022 Neo4j, Inc. All rights reserved.
Using - User Defined Procedures
http://neo4j.com/docs/developer-manual/current/procedures
// shortcut for stand alone call
CALL dbms.procedures()
// process result columns
CALL dbms.procedures()
YIELD name, signature, description
RETURN count(name)
Exercise: List available procedures
1. List all procedures in the "dbms" namespace
2. List all procedures whose signature contains "NODE"
3. Group procedures by first part of the names (e.g. "db") and return a
count of the number of procedures and a collection containing just
the last part of the name. (e.g. "awaitIndex")
4. Play around with at least 3 procedures in the list. Which ones did you
try?
© 2022 Neo4j, Inc. All rights reserved.
Listing procedures
CALL dbms.procedures()
YIELD name, signature, description
WITH * WHERE name STARTS WITH "dbms."
RETURN *
© 2022 Neo4j, Inc. All rights reserved.
Listing procedures
CALL dbms.procedures()
YIELD name, signature, description
WITH * WHERE signature CONTAINS "NODE"
RETURN *
© 2022 Neo4j, Inc. All rights reserved.
Listing procedures
CALL dbms.procedures()
YIELD name, signature, description
WITH split(name,".") AS parts
RETURN parts[0] AS package,
count(*) AS count,
collect(parts[-1]) AS names
© 2022 Neo4j, Inc. All rights reserved.
Cons of User-Defined Procedures
• Quite involved CALL clause for simple, read-only computation,
conversion functions or predicates
• Need to YIELD and select result columns
• Can’t be part of expressions
© 2022 Neo4j, Inc. All rights reserved.
User Defined Functions
© 2022 Neo4j, Inc. All rights reserved.
User-Defined Functions
• Allows users to create their own functions and use them with Cypher
• Useful for expressing common computations, rules, conversions,
predicates
• Functions can be used in any expression, predicates
• Extend the Neo4j 3.0 Stored Procedure mechanism
© 2022 Neo4j, Inc. All rights reserved.
Creating a UUID with a Procedure vs. with a Function
CALL apoc.create.uuid() YIELD uuid
CALL apoc.data.formatDefault(timestamp(), "ms")
YIELD value AS date
CREATE (:Document {id: uuid, created:date})
vs
CREATE (:Document {
id: apoc.create.uuid(),
date: apoc.data.formatDefault(timestamp(), "ms")})
© 2022 Neo4j, Inc. All rights reserved.
APOC
Awesome Procedures on Cypher
Why and How?
© 2022 Neo4j, Inc. All rights reserved.
Download the appropriate version of APOC and put it
in the $NEO4J_HOME/plugins directory
https://github.com/neo4j-contrib/neo4j-apoc-
procedures#version-compatibility-matrix
After you’ve done this restart Neo4j
Install APOC
APOC Procedures
• Cypher is expressive and great for graph operations but misses some
utilities so people built their own one-off solutions
• APOC is a "Standard Library" of helpful procedures and functions
• Started as an experiment but has evolved into an active community
project with 500+ procedures and 75+ functions
• github.com/neo4j-contrib/neo4j-apoc-procedures
What does APOC cover?
• Functions for date, time, data conversion, collection handling
• Procedures for data integration, graph algorithms, graph refactoring,
metadata, Cypher batching
• TimeToLive (TTL), triggers, parallelization
• And much more!
© 2022 Neo4j, Inc. All rights reserved.
Documentation
• documentation site github.com/neo4j-contrib/neo4j-apoc-procedures
• browser guide :play http://guides.neo4j.com/apoc
• many articles & blog posts neo4j.com/tag/apoc
© 2022 Neo4j, Inc. All rights reserved.
User-Defined Functions in APOC - Packages
© 2022 Neo4j, Inc. All rights reserved.
(Meta)-Utilities, Converters
© 2022 Neo4j, Inc. All rights reserved.
(Meta)-Utilities, Converters
• apoc.date.format(timestamp(),"ms","YYYY-MM-dd")
• apoc.number.parse("12.000,00")
© 2022 Neo4j, Inc. All rights reserved.
The Meta Graph
Use dbms.functions() to:
1. List all functions in the "apoc" namespace
2. Play around with at least 3 other functions. Which ones did you try?
Exercise: Explore APOC functions
RETURN apoc.coll.toSet([1,2,3,4,4,4,4,5,6,7])
APOC functions
RETURN apoc.text.clean(" Neo4j ")
APOC functions
© 2022 Neo4j, Inc. All rights reserved.
Data Import and Export
© 2022 Neo4j, Inc. All rights reserved.
Data Integration / Import
• Databases
• JDBC
• MongoDB
• Cassandra
• Elastic
• CouchDB
• File formats
• JSON
• XML
© 2022 Neo4j, Inc. All rights reserved.
LOAD JDBC
Load from relational database, either a full table or a sql statement
CALL apoc.load.jdbc('jdbc-url','TABLE') YIELD row
CALL apoc.load.jdbc('jdbc-url','SQL-STATEMENT') YIELD row
To simplify the JDBC URL syntax and protect credentials, you can
configure aliases in conf/neo4j.conf:
apoc.jdbc.alias.url=jdbc:mysql://localhost:3306/<database>?user=<username>
CALL apoc.load.jdbc('alias','TABLE')
© 2022 Neo4j, Inc. All rights reserved.
Load Northwind data from MySQL
© 2022 Neo4j, Inc. All rights reserved.
Load Northwind data: Products and Orders
© 2022 Neo4j, Inc. All rights reserved.
Load Northwind data: Order Details
© 2022 Neo4j, Inc. All rights reserved.
Load Northwind data: Customers
© 2022 Neo4j, Inc. All rights reserved.
// import XML as single nested map with attributes and `_type`, `_text` fields
// and `_<childtype>` collections per child-element-type.
CALL apoc.load.xmlSimple('xml-url')
YIELD value as doc
Loading data from XML
© 2022 Neo4j, Inc. All rights reserved.
Load Northwind data: Graph Result
© 2022 Neo4j, Inc. All rights reserved.
Product Recommendations
© 2022 Neo4j, Inc. All rights reserved.
// load from JSON URL (e.g. web-api) to import JSON as stream of values if the JSON
was an array or a single value if it was a map
CALL apoc.load.json('json-url')
YIELD value as row
Loading data from JSON
© 2022 Neo4j, Inc. All rights reserved.
// load CSV fom URL as stream of values
CALL apoc.load.csv('csv-url',{config})
YIELD lineNo, list, map
// config contains any of:
{skip: 1,
limit: 5,
header: false,
sep: 'TAB',
ignore:['tmp'],
arraySep: ';',
mapping: {
years: { type:'int', arraySep:'-', array:false, name:'age', ignore:false}
}
Loading data from CSV
© 2022 Neo4j, Inc. All rights reserved.
Exercise: Import StackOverflow
Use APOC's apoc.load.json to import StackOverflow from this URI:
https://api.stackexchange.com/2.2/questions?pagesize=1
00&tagged=neo4j&site=stackoverflow
You can also find it in the documentation:
• neo4j-contrib.github.io/neo4j-apoc-procedures
• Search for "Load JSON StackOverflow Example"
© 2022 Neo4j, Inc. All rights reserved.
Simple Example:
Write, Test, Use a Function
© 2022 Neo4j, Inc. All rights reserved.
User Defined Functions
● @UserFunction annotated, named Java Methods
○ default name: package + method
● take @Name'ed parameters (with default values)
● return a single value
● are read only
● can use @Context injected GraphDatabaseService
● run within transaction of the Cypher statement
© 2022 Neo4j, Inc. All rights reserved.
@UserFunction("create.uuid")
@Description("creates an UUID (universally unique id)")
public String uuid() {
return UUID.randomUUID().toString();
}
Simple Function (UUID)
© 2022 Neo4j, Inc. All rights reserved.
@UserFunction("create.uuid")
@Description("creates an UUID (universally unique id)")
public String uuid() {
return UUID.randomUUID().toString();
}
Calling the function from Cypher:
RETURN create.uuid();
CREATE (p:Person {id: create.uuid(), name:{name}})
Simple Function (UUID)
1. Deploy & Register in Neo4j Server via neo4j-harness
2. Call & test via neo4j-java-driver
Test Code
https://github.com/neo4j-contrib/training/
1. Deploy & Register in Neo4j Server via neo4j-harness
2. Call & test via neo4j-java-driver
@Rule
public Neo4jRule neo4j = new Neo4jRule().withFunction( UUIDs.class );
try( Driver driver = GraphDatabase.driver( neo4j.boltURI() , config ) {
Session session = driver.session();
String uuid = session.run("RETURN create.uuid() AS uuid")
.single().get( 0 ).asString();
assertThat( uuid,....);
}
Test Code
© 2022 Neo4j, Inc. All rights reserved.
● Build or download (shadow) jar
● Drop jar-file into $NEO4J_HOME/plugins
● Restart server
● Functions & Procedures should be available
● Otherwise check neo4j.log / debug.log
Deploying User Defined Code
© 2022 Neo4j, Inc. All rights reserved.
● @Procedure annotated, named Java Methods
● additional mode attribute (Read, Write, Dbms)
● return a Stream of value objects with public fields
● value object fields are turned into columns
User Defined Procedures
https://github.com/neo4j-examples/neo4j-procedure-template
© 2022 Neo4j, Inc. All rights reserved.
Procedure Code Example (Dijkstra)
@Procedure
@Description("apoc.algo.dijkstra(startNode, endNode, 'KNOWS', 'distance') YIELD path,"
+
" weight - run dijkstra with relationship property name as cost function")
public Stream<WeightedPathResult> dijkstra(
@Name("startNode") Node startNode,
@Name("endNode") Node endNode,
@Name("type") String type,
@Name("costProperty") String costProperty) {
PathFinder<WeightedPath> algo = GraphAlgoFactory.dijkstra(
PathExpanders.forType(RelationshipType.withName(type)),
costProperty);
Iterable<WeightedPath> allPaths = algo.findAllPaths(startNode, endNode);
return Iterables.asCollection(allPaths).stream()
.map(WeightedPathResult::new);
}
@Rule
public Neo4jRule neo4j = new Neo4jRule()
.withProcedure( Dijkstra.class );
try( Driver driver = GraphDatabase.driver( neo4j.boltURI() , config ) {
Session session = driver.session();
String query =
"MATCH ... CALL apoc.algo.dijkstra(...) YIELD path RETURN ...";
String pathNames = session.run(query)
.single().get( 0 ).asString();
assertThat( pathNames, ....);
}
Test Procedure
© 2022 Neo4j, Inc. All rights reserved.
Periodic Execution &
Transaction Control
© 2022 Neo4j, Inc. All rights reserved.
Large operations? Consider TX batching
CALL apoc.periodic.iterate('
CALL apoc.load.jdbc(
"jdbc:mysql://localhost:3306/northwind?user=root", "company")',
'CREATE (p:Person) SET p += value',
{batchSize:10000, parallel:true})
RETURN batches, total
© 2022 Neo4j, Inc. All rights reserved.
Exercise 2: Import 5 pages of StackOverflow
Use APOC's apoc.periodic.iterate with the apoc.load.json
solution you wrote earlier.
You can also find information about in the documentation:
neo4j-contrib.github.io/neo4j-apoc-procedures
© 2022 Neo4j, Inc. All rights reserved.
Graph Algorithms
101
© 2022 Neo4j, Inc. All rights reserved.
Graph Algorithms
• While these are neat, favor the Graph Algo procedures instead
• https://neo4j.com/docs/graph-algorithms/current/
• Pathfinding: apoc.algo.dijkstra, apoc.algo.aStar
• PageRank: apoc.algo.pageRankStats, apoc.algo.pageRankWithCypher
• Centrality: apoc.algo.betweenness, apoc.algo.closeness
• Clustering: apoc.algo.community, apoc.algo.wcc, apoc.algo.cliques
• Node-Cover: apoc.algo.cover
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
103
Split 3rds - bullets
When using bullets on the left ,
select all the bullets and use:
Add space after list item
to visually separate them
Example of bullets:
• Short point
here not more
than 3 lines
• Another point
which is not too
long
• Short and
sweet
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
104
Neo4j Aura Enterprise is allowing us to realize our
vision to build a knowledge graph that unifies all
product knowledge to improve our retail
recommendations, search and merchandising.”
“
- Name and position, Company
© 2022 Neo4j, Inc. All rights reserved.
105
Special slides examples
1 2
Arial
Extra Bold 86pt
for big numbers
Arial
Normal 14pt for
small text
3 4
Arial
Extra Bold 86pt
for big numbers
Arial
Normal 14pt for
small text
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
106
Thing to compare 2
Thing to compare 1
• Comparison 1
• Comparison 2
◦ Details
• Comparison 1
• Comparison 2
◦ Details
© 2022 Neo4j, Inc. All rights reserved.
107
1. Use Media Slide from Master
2. Image is cropped at width
4.62in, so it takes up half of
the slide (and aligned with
blue rectangle on the left)
Media
© 2022 Neo4j, Inc. All rights reserved.
108
Image Placeholder
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
109
© 2022 Neo4j, Inc. All rights reserved.
110
Your Logo Here
© 2022 Neo4j, Inc. All rights reserved.
111
111
Your Logo Here

Boost Your Neo4j with User-Defined Procedures

  • 1.
    © 2022 Neo4j,Inc. All rights reserved. Michael Hunger, Senior Director, User Innovation @mesirii Boost Your Neo4j Experience with User-Defined Procedures
  • 2.
    © 2022 Neo4j,Inc. All rights reserved. 2 Outline • Why should I care? • Hello World Example • UDP bridge the gap • Java API vs. Cypher • When should I use UDP? When should I build one? • Development / Testing / Deployment • Pro's and Cons • Real Example • Procedure Libraries ◦ APOC, GDS, neosemantics
  • 3.
    © 2022 Neo4j,Inc. All rights reserved. 3 Why should I care? 1 2 Efficiency Encapsulation 3 4 Integration Portability
  • 4.
    © 2022 Neo4j,Inc. All rights reserved. 4 Hello World Example public class Hello { @UserFunction public String hello(@Name(„text“) String text) { if (text == null) { return null; } return String.format(„Hello %s!“, text); } }
  • 5.
    © 2022 Neo4j,Inc. All rights reserved. User Defined Procedures & Functions Neo4j Execution Engine User Defined Procedure Applications Bolt User Defined Procedures & Functions let you write custom code that is: • Written in any JVM language • Deployed to the Database • Accessed by applications via Cypher User Defined Functions 5
  • 6.
    © 2022 Neo4j,Inc. All rights reserved. Built-in procedures SHOW PROCEDURES
  • 7.
    © 2022 Neo4j,Inc. All rights reserved. Example: Listing all relationship types CALL db.relationshipTypes()
  • 8.
    © 2022 Neo4j,Inc. All rights reserved. Usage CALL dbms.listQueries() YIELD queryId, query, username, elapsedTimeMillis, activeLockCount WHERE elapsedTimeMillis > 1000 CALL dbms.killQuery(queryId) yield message RETURN queryId, substring(query,0,100) as query, username, elapsedTimeMillis, activeLockCount, message
  • 9.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. 9 User Defined ● Procedures ● Functions ● Aggregation Functions Bridge the Gap
  • 10.
    © 2022 Neo4j,Inc. All rights reserved. 10 Bridging the Gap 1 2 Exposed in Cypher Composable Lego Blocks 3 4 Extend with new functionality Power & Ease
  • 11.
    © 2022 Neo4j,Inc. All rights reserved. 11 Procedures ● read / write ● stateless ● stream results ● standalone and embedded call proc(param) yield value1, value2 What is available? User Defined … Functions ● read-only ● stateless ● single result ● in expressions return func(param) as value Aggregation Functions ● read-only ● stateful ● agg results ● in aggregations return key, agg(value) as aggregated
  • 12.
    © 2022 Neo4j,Inc. All rights reserved. 12 When should I use user defined procedures & functions? 1 2 Functionality Performance 3 4 Compact- ness Missing Cypher Capability
  • 13.
    © 2022 Neo4j,Inc. All rights reserved. 13 Development
  • 14.
    © 2022 Neo4j,Inc. All rights reserved. 14 When should I create a user defined procedures? 1 2 Business spec.need Performance SLA 3 4 Required Integration Missing Cypher Capability
  • 15.
    © 2022 Neo4j,Inc. All rights reserved. 15 Cypher vs. Java API • original API • low level • imperative • only available in database extensions • allows access to all Java data and control structures • additional concurrency • easy to learn, write, maintain • declarative • graph patterns • available through drivers & tools • limited data- and control- structures 15
  • 16.
    © 2022 Neo4j,Inc. All rights reserved. ● any JVM language ● separate procedure-layer from implementation ● avoid accessing internal APIs 16 Develop Development Cycle Test ● can be unit tested ● Testcontainers for integration tests ● IT also for dependencies and bolt integration ● biggest pain point ● version matches ● provide or package dependencies ● requires restart ● all cluster members Deploy
  • 17.
    © 2022 Neo4j,Inc. All rights reserved. 17 Pros and Cons • More involved code to maintain long-term (JVM skills) • Deployment (server restart, aura, cluster) • No planner participation • No resource mgmt participation • No feedback about internal operations • Need to know what you are doing • Composable Lego blocks • Encapsulate functionality • Write once then reuse • Most Java language features • Testable with Unit testing • Refactoring • Apply permissions to procedures 17
  • 18.
    © 2022 Neo4j,Inc. All rights reserved. 18 User Defined Function Example
  • 19.
    © 2022 Neo4j,Inc. All rights reserved. User Defined Functions ● @UserFunction annotated, named Java Methods ○ default name: package + method ● take @Name'ed parameters (with default values) ● return a single value ● are read only ● can use @Context injected GraphDatabaseService and others ● run within transaction of the Cypher statement 19
  • 20.
    © 2022 Neo4j,Inc. All rights reserved. 20 Simple Function (Join) public class Join { @UserFunction @Description("example.join(['s1','s2',...], delimiter) – join the given strings with the given delimiter.") public String join( @Name("strings") List<String> strings, @Name(value = "delimiter", defaultValue = ",") String delimiter) { if (strings == null || delimiter == null) { return null; } return String.join(delimiter, strings); } }
  • 21.
    © 2022 Neo4j,Inc. All rights reserved. Calling the function from Cypher: RETURN example.join(["Hello", "World", "Austin"], "-") -> „Hello-World-Austin!“ Calling from Cypher 21
  • 22.
    © 2022 Neo4j,Inc. All rights reserved. 1. Deploy & Register in Neo4j Server via neo4j-harness 2. Call & test via neo4j-java- driver Test Code 22
  • 23.
    © 2022 Neo4j,Inc. All rights reserved. ● Build or download (shadow) jar ● Drop jar-file into $NEO4J_HOME/plugins ● For sandboxed / allow-listing, need to edit neo4j.conf dbms.security.procedures.unrestricted=example.* ● Restart server ● Functions & Procedures should be available (show procedures) ● Otherwise check neo4j.log / debug.log Deploying User Defined Code 23
  • 24.
    © 2022 Neo4j,Inc. All rights reserved. 24 User Defined Procedure Example
  • 25.
    © 2022 Neo4j,Inc. All rights reserved. User Defined Procedures ● @Procedure annotated, named Java Methods ● additional mode attribute (Read, Write, Dbms, Schema) ● return a Stream of value objects (DTO) with public fields ● value object fields are turned into columns ● Runs as part of outer transaction ● Injection of @Context fields, like Transaction, Log, Database ● Same testing & deployment as functions github.com/neo4j-examples/neo4j-procedure-template 25
  • 26.
    © 2022 Neo4j,Inc. All rights reserved. Procedure Code Example (Dijkstra) @Procedure @Description("apoc.algo.dijkstra(startNode, endNode, 'KNOWS', 'distance') YIELD path," + " weight - run dijkstra with relationship property name as cost function") public Stream<WeightedPathResult> dijkstra( @Name("startNode") Node startNode, @Name("endNode") Node endNode, @Name("type") String type, @Name("costProperty") String costProperty) { PathFinder<WeightedPath> algo = GraphAlgoFactory.dijkstra( PathExpanders.forType(RelationshipType.withName(type)), costProperty); Iterable<WeightedPath> allPaths = algo.findAllPaths(startNode, endNode); return StreamSupport.stream(allPaths.spliterator(), false) .map(WeightedPathResult::new); } 26
  • 27.
    © 2022 Neo4j,Inc. All rights reserved. 28 Realworld Example Optimizing Category/Genre Overlap
  • 28.
    © 2022 Neo4j,Inc. All rights reserved. 29 Task: Category/Tag Overlap Given a set of categories (names) find all items that are in at least in these categories. Simple for one, two or three categories: MATCH (question)-[:TAGGED]->(:Tag {name:$name1}), (question)-[:TAGGED]->(:Tag {name:$name2}) But not optimal, and not arbitrary.
  • 29.
    © 2022 Neo4j,Inc. All rights reserved. Example Query - Tag Overlap PROFILE WITH ['cypher','neo4j', 'python'] AS tagNames UNWIND tagNames AS name MATCH (t:Tag {name:name})<-[:TAGGED]-(q:Question) WITH q, collect(t) AS tags, tagNames WHERE size(tags) = size(tagNames) RETURN q // 2.075.518 total db hits 30
  • 30.
    © 2022 Neo4j,Inc. All rights reserved. Example Query - Tag Overlap PROFILE WITH ['cypher','neo4j', 'python'] AS tagNames MATCH (t:Tag)<-[:TAGGED]-(q:Question) WHERE t.name IN tagNames WITH q, collect(t) AS tags, tagNames WHERE size(tags) = size(tagNames) RETURN q LIMIT 10 // 2.075.518 db-hits 31
  • 31.
    © 2022 Neo4j,Inc. All rights reserved. Example Query - Tag Overlap - Optimized PROFILE WITH ['cypher','neo4j', 'python'] AS tagNames UNWIND tagNames AS name MATCH (t:Tag {name:name}) // lowest degree first WITH t ORDER BY size( (t)<-[:TAGGED]-() ) ASC WITH collect(t) AS tags WITH head(tags) AS first, tail(tags) AS rest MATCH (first)<-[:TAGGED]-(q:Question) WHERE all(t IN rest WHERE (q)-[:TAGGED]->(t)) RETURN q // 89.137 total db hits 32
  • 32.
    © 2022 Neo4j,Inc. All rights reserved. Example Query - Tag Overlap - Optimized (2) PROFILE WITH ['cypher','neo4j', 'python'] AS tagNames UNWIND tagNames AS name MATCH (t:Tag {name:name}) // lowest degree first WITH t ORDER BY size( (t)<-[:TAGGED]-() ) ASC WITH collect(t) AS tags WITH head(tags) AS first, tail(tags) AS rest MATCH (first)<-[:TAGGED]-(q:Question)-[:TAGGED]->(other) WITH q, collect(other) AS questionTags, rest WHERE all(t IN rest WHERE t IN questionTags) RETURN q // 55.660 total db hits 33
  • 33.
    © 2022 Neo4j,Inc. All rights reserved. Example - Tag Overlap - Procedure 1. pass in list of tag names 2. find tag with least questions (degree) as driver 3. put other tags into Set 4. iterate over questions of minimal tag 5. for each question 6. for each tag that is in set increment counter 7. if counter = Set size a. add/stream question to result 34
  • 34.
    © 2022 Neo4j,Inc. All rights reserved. Example - Genre Overlap - Procedure - Code (1) // Procedure class with injection public class SharedTags { @Context public GraphDatabaseService gdb; @Context public Log log; enum Types implements RelationshipType { TAGGED; } enum Labels implements Label { Tag, Question } } 35
  • 35.
    © 2022 Neo4j,Inc. All rights reserved. Example - Genre Overlap - Procedure - Code (2) // Return Type, each field a column public static class QuestionTag { public String title; public String tag; public double weight; public QuestionTag(String title, String tag, double weight) { this.title = title; this.tag = tag; this.weight = weight; } } 36
  • 36.
    © 2022 Neo4j,Inc. All rights reserved. Example - Genre Overlap - Procedure - Code (3) @Procedure public Stream<QuestionTag> sharedGenres( @Name(”tagNames") List<String> tagNames) { int tagCount = tagNames.size(); // lookup and order tags by degree ascending List<Pair<Node, Integer>> tags = tagNames.stream().map(tagName -> { Node tag = gdb.findNode(Labels.Tag, "name", tagName); return Pair.of(tag, tag.getDegree(Types.TAGGED, Direction.INCOMING)); }).sorted((p1, p2) -> compare(p1.other(), p2.other())).toList(); 37
  • 37.
    © 2022 Neo4j,Inc. All rights reserved. Example - Genre Overlap - Procedure - Code (4) // find questions for the tag with the lowest degree var driver = tags.get(0); var questions = new HashMap<>(driver.other()); for (Relationship e0 : driver.first() .getRelationships(Direction.INCOMING, Types.TAGGED)) { Node question = e0.getStartNode(); questions.put(question, new ArrayList<>(List.of(Pair.of(driver.first(), e0)))); } 38
  • 38.
    © 2022 Neo4j,Inc. All rights reserved. // check and add to found questions for remainder of tags for (Pair<Node, Integer> tag : tags.subList(1, tags.size())) { Node node = tag.first(); for (Relationship e1 : node.getRelationships(Direction.INCOMING, Types.TAGGED)) { Node question = e1.getStartNode(); if (questions.containsKey(question)) { questions.get(question).add(Pair.of(tag.first(), e1)); } } } Example - Genre Overlap - Procedure - Code (5) 39
  • 39.
    © 2022 Neo4j,Inc. All rights reserved. // transform map into result stream return questions.entrySet().stream() .filter(entry -> entry.getValue().size() == tagCount) .flatMap(entry -> { String title = (String) entry.getKey().getProperty("title", null); return entry.getValue().stream().map(tagRel -> { String tagName = (String) tagRel.first().getProperty("name"); Number weight = (Number)tagRel.other().getProperty("weight",0); return new QuestionTag(title, tagName, weight.doubleValue()); }); }); } } Example - Genre Overlap - Procedure - Code (6) 40
  • 40.
    © 2022 Neo4j,Inc. All rights reserved. 41 Existing Procedure Libraries
  • 41.
    © 2022 Neo4j,Inc. All rights reserved. 42 Existing Procedure Libraries 1 2 Built-in APOC 3 4 graph data science neosemantics
  • 42.
    © 2022 Neo4j,Inc. All rights reserved. 43 Built In Procedures Many built-in procedures are phased out for admin commands – Not a fan. • Indexes & constraints esp. Fulltext (phased out) • Schema visualization / data • Cluster management • Security / User Mmgt (phased out) • Database state • Procedures & Functions (phased out) • Query, Transaction, Connection Management (phased out) • Configuration Management • Memory Pools • Scheduler
  • 43.
    © 2022 Neo4j,Inc. All rights reserved. 44 Areas Of Use (APOC)
  • 44.
    © 2022 Neo4j,Inc. All rights reserved. 45 Graph Data Science
  • 45.
    © 2022 Neo4j,Inc. All rights reserved. 46 neosemantics
  • 46.
    © 2022 Neo4j,Inc. All rights reserved. 47 Learn more 1 2 Docs neo4j.com/docs/java-reference Guides neo4j.com/developer/cypher/procedures-functions/ 3 4 Example github.com/neo4j-examples/ neo4j-procedure-template Read the source!
  • 47.
    © 2022 Neo4j,Inc. All rights reserved. 48 Q&A
  • 48.
    © 2022 Neo4j,Inc. All rights reserved. 49 Thank you! Follow me: @mesirii
  • 49.
    © 2022 Neo4j,Inc. All rights reserved. • Why do we need user defined procedures and functions? • Syntax & built in procedures • The APOC procedure library • Helper functions • Data integration • Graph algorithms • Graph refactoring / Transaction management • How to write and test your own procedure / function • Turn Cypher queries into procedures What will we learn?
  • 50.
    © 2022 Neo4j,Inc. All rights reserved. What are User Defined Procedures and Functions?
  • 51.
    © 2022 Neo4j,Inc. All rights reserved. Neo4j Developer Surface Native LanguageDrivers BOLT User Defined Procedure 2000-2010 0.x - Embedded Java API 2010-2014 1.x - REST 2014-2015 2.x - Cypher over HTTP 2016 - 3.0.x - Bolt, Official Language Drivers, and User Defined Procedures 3.1.x - User Defined Functions
  • 52.
    © 2022 Neo4j,Inc. All rights reserved. Using User Defined Procedures
  • 53.
    © 2022 Neo4j,Inc. All rights reserved. Using - User Defined Procedures http://neo4j.com/docs/developer-manual/current/procedures // shortcut for stand alone call CALL dbms.procedures() // process result columns CALL dbms.procedures() YIELD name, signature, description RETURN count(name)
  • 54.
    Exercise: List availableprocedures 1. List all procedures in the "dbms" namespace 2. List all procedures whose signature contains "NODE" 3. Group procedures by first part of the names (e.g. "db") and return a count of the number of procedures and a collection containing just the last part of the name. (e.g. "awaitIndex") 4. Play around with at least 3 procedures in the list. Which ones did you try?
  • 55.
    © 2022 Neo4j,Inc. All rights reserved. Listing procedures CALL dbms.procedures() YIELD name, signature, description WITH * WHERE name STARTS WITH "dbms." RETURN *
  • 56.
    © 2022 Neo4j,Inc. All rights reserved. Listing procedures CALL dbms.procedures() YIELD name, signature, description WITH * WHERE signature CONTAINS "NODE" RETURN *
  • 57.
    © 2022 Neo4j,Inc. All rights reserved. Listing procedures CALL dbms.procedures() YIELD name, signature, description WITH split(name,".") AS parts RETURN parts[0] AS package, count(*) AS count, collect(parts[-1]) AS names
  • 58.
    © 2022 Neo4j,Inc. All rights reserved. Cons of User-Defined Procedures • Quite involved CALL clause for simple, read-only computation, conversion functions or predicates • Need to YIELD and select result columns • Can’t be part of expressions
  • 59.
    © 2022 Neo4j,Inc. All rights reserved. User Defined Functions
  • 60.
    © 2022 Neo4j,Inc. All rights reserved. User-Defined Functions • Allows users to create their own functions and use them with Cypher • Useful for expressing common computations, rules, conversions, predicates • Functions can be used in any expression, predicates • Extend the Neo4j 3.0 Stored Procedure mechanism
  • 61.
    © 2022 Neo4j,Inc. All rights reserved. Creating a UUID with a Procedure vs. with a Function CALL apoc.create.uuid() YIELD uuid CALL apoc.data.formatDefault(timestamp(), "ms") YIELD value AS date CREATE (:Document {id: uuid, created:date}) vs CREATE (:Document { id: apoc.create.uuid(), date: apoc.data.formatDefault(timestamp(), "ms")})
  • 62.
    © 2022 Neo4j,Inc. All rights reserved. APOC Awesome Procedures on Cypher Why and How?
  • 63.
    © 2022 Neo4j,Inc. All rights reserved. Download the appropriate version of APOC and put it in the $NEO4J_HOME/plugins directory https://github.com/neo4j-contrib/neo4j-apoc- procedures#version-compatibility-matrix After you’ve done this restart Neo4j Install APOC
  • 64.
    APOC Procedures • Cypheris expressive and great for graph operations but misses some utilities so people built their own one-off solutions • APOC is a "Standard Library" of helpful procedures and functions • Started as an experiment but has evolved into an active community project with 500+ procedures and 75+ functions • github.com/neo4j-contrib/neo4j-apoc-procedures
  • 65.
    What does APOCcover? • Functions for date, time, data conversion, collection handling • Procedures for data integration, graph algorithms, graph refactoring, metadata, Cypher batching • TimeToLive (TTL), triggers, parallelization • And much more!
  • 66.
    © 2022 Neo4j,Inc. All rights reserved. Documentation • documentation site github.com/neo4j-contrib/neo4j-apoc-procedures • browser guide :play http://guides.neo4j.com/apoc • many articles & blog posts neo4j.com/tag/apoc
  • 67.
    © 2022 Neo4j,Inc. All rights reserved. User-Defined Functions in APOC - Packages
  • 68.
    © 2022 Neo4j,Inc. All rights reserved. (Meta)-Utilities, Converters
  • 69.
    © 2022 Neo4j,Inc. All rights reserved. (Meta)-Utilities, Converters • apoc.date.format(timestamp(),"ms","YYYY-MM-dd") • apoc.number.parse("12.000,00")
  • 70.
    © 2022 Neo4j,Inc. All rights reserved. The Meta Graph
  • 71.
    Use dbms.functions() to: 1.List all functions in the "apoc" namespace 2. Play around with at least 3 other functions. Which ones did you try? Exercise: Explore APOC functions
  • 72.
  • 73.
  • 74.
    © 2022 Neo4j,Inc. All rights reserved. Data Import and Export
  • 75.
    © 2022 Neo4j,Inc. All rights reserved. Data Integration / Import • Databases • JDBC • MongoDB • Cassandra • Elastic • CouchDB • File formats • JSON • XML
  • 76.
    © 2022 Neo4j,Inc. All rights reserved. LOAD JDBC Load from relational database, either a full table or a sql statement CALL apoc.load.jdbc('jdbc-url','TABLE') YIELD row CALL apoc.load.jdbc('jdbc-url','SQL-STATEMENT') YIELD row To simplify the JDBC URL syntax and protect credentials, you can configure aliases in conf/neo4j.conf: apoc.jdbc.alias.url=jdbc:mysql://localhost:3306/<database>?user=<username> CALL apoc.load.jdbc('alias','TABLE')
  • 77.
    © 2022 Neo4j,Inc. All rights reserved. Load Northwind data from MySQL
  • 78.
    © 2022 Neo4j,Inc. All rights reserved. Load Northwind data: Products and Orders
  • 79.
    © 2022 Neo4j,Inc. All rights reserved. Load Northwind data: Order Details
  • 80.
    © 2022 Neo4j,Inc. All rights reserved. Load Northwind data: Customers
  • 81.
    © 2022 Neo4j,Inc. All rights reserved. // import XML as single nested map with attributes and `_type`, `_text` fields // and `_<childtype>` collections per child-element-type. CALL apoc.load.xmlSimple('xml-url') YIELD value as doc Loading data from XML
  • 82.
    © 2022 Neo4j,Inc. All rights reserved. Load Northwind data: Graph Result
  • 83.
    © 2022 Neo4j,Inc. All rights reserved. Product Recommendations
  • 84.
    © 2022 Neo4j,Inc. All rights reserved. // load from JSON URL (e.g. web-api) to import JSON as stream of values if the JSON was an array or a single value if it was a map CALL apoc.load.json('json-url') YIELD value as row Loading data from JSON
  • 85.
    © 2022 Neo4j,Inc. All rights reserved. // load CSV fom URL as stream of values CALL apoc.load.csv('csv-url',{config}) YIELD lineNo, list, map // config contains any of: {skip: 1, limit: 5, header: false, sep: 'TAB', ignore:['tmp'], arraySep: ';', mapping: { years: { type:'int', arraySep:'-', array:false, name:'age', ignore:false} } Loading data from CSV
  • 86.
    © 2022 Neo4j,Inc. All rights reserved. Exercise: Import StackOverflow Use APOC's apoc.load.json to import StackOverflow from this URI: https://api.stackexchange.com/2.2/questions?pagesize=1 00&tagged=neo4j&site=stackoverflow You can also find it in the documentation: • neo4j-contrib.github.io/neo4j-apoc-procedures • Search for "Load JSON StackOverflow Example"
  • 87.
    © 2022 Neo4j,Inc. All rights reserved. Simple Example: Write, Test, Use a Function
  • 88.
    © 2022 Neo4j,Inc. All rights reserved. User Defined Functions ● @UserFunction annotated, named Java Methods ○ default name: package + method ● take @Name'ed parameters (with default values) ● return a single value ● are read only ● can use @Context injected GraphDatabaseService ● run within transaction of the Cypher statement
  • 89.
    © 2022 Neo4j,Inc. All rights reserved. @UserFunction("create.uuid") @Description("creates an UUID (universally unique id)") public String uuid() { return UUID.randomUUID().toString(); } Simple Function (UUID)
  • 90.
    © 2022 Neo4j,Inc. All rights reserved. @UserFunction("create.uuid") @Description("creates an UUID (universally unique id)") public String uuid() { return UUID.randomUUID().toString(); } Calling the function from Cypher: RETURN create.uuid(); CREATE (p:Person {id: create.uuid(), name:{name}}) Simple Function (UUID)
  • 91.
    1. Deploy &Register in Neo4j Server via neo4j-harness 2. Call & test via neo4j-java-driver Test Code https://github.com/neo4j-contrib/training/
  • 92.
    1. Deploy &Register in Neo4j Server via neo4j-harness 2. Call & test via neo4j-java-driver @Rule public Neo4jRule neo4j = new Neo4jRule().withFunction( UUIDs.class ); try( Driver driver = GraphDatabase.driver( neo4j.boltURI() , config ) { Session session = driver.session(); String uuid = session.run("RETURN create.uuid() AS uuid") .single().get( 0 ).asString(); assertThat( uuid,....); } Test Code
  • 93.
    © 2022 Neo4j,Inc. All rights reserved. ● Build or download (shadow) jar ● Drop jar-file into $NEO4J_HOME/plugins ● Restart server ● Functions & Procedures should be available ● Otherwise check neo4j.log / debug.log Deploying User Defined Code
  • 94.
    © 2022 Neo4j,Inc. All rights reserved. ● @Procedure annotated, named Java Methods ● additional mode attribute (Read, Write, Dbms) ● return a Stream of value objects with public fields ● value object fields are turned into columns User Defined Procedures https://github.com/neo4j-examples/neo4j-procedure-template
  • 95.
    © 2022 Neo4j,Inc. All rights reserved. Procedure Code Example (Dijkstra) @Procedure @Description("apoc.algo.dijkstra(startNode, endNode, 'KNOWS', 'distance') YIELD path," + " weight - run dijkstra with relationship property name as cost function") public Stream<WeightedPathResult> dijkstra( @Name("startNode") Node startNode, @Name("endNode") Node endNode, @Name("type") String type, @Name("costProperty") String costProperty) { PathFinder<WeightedPath> algo = GraphAlgoFactory.dijkstra( PathExpanders.forType(RelationshipType.withName(type)), costProperty); Iterable<WeightedPath> allPaths = algo.findAllPaths(startNode, endNode); return Iterables.asCollection(allPaths).stream() .map(WeightedPathResult::new); }
  • 96.
    @Rule public Neo4jRule neo4j= new Neo4jRule() .withProcedure( Dijkstra.class ); try( Driver driver = GraphDatabase.driver( neo4j.boltURI() , config ) { Session session = driver.session(); String query = "MATCH ... CALL apoc.algo.dijkstra(...) YIELD path RETURN ..."; String pathNames = session.run(query) .single().get( 0 ).asString(); assertThat( pathNames, ....); } Test Procedure
  • 97.
    © 2022 Neo4j,Inc. All rights reserved. Periodic Execution & Transaction Control
  • 98.
    © 2022 Neo4j,Inc. All rights reserved. Large operations? Consider TX batching CALL apoc.periodic.iterate(' CALL apoc.load.jdbc( "jdbc:mysql://localhost:3306/northwind?user=root", "company")', 'CREATE (p:Person) SET p += value', {batchSize:10000, parallel:true}) RETURN batches, total
  • 99.
    © 2022 Neo4j,Inc. All rights reserved. Exercise 2: Import 5 pages of StackOverflow Use APOC's apoc.periodic.iterate with the apoc.load.json solution you wrote earlier. You can also find information about in the documentation: neo4j-contrib.github.io/neo4j-apoc-procedures
  • 100.
    © 2022 Neo4j,Inc. All rights reserved. Graph Algorithms 101
  • 101.
    © 2022 Neo4j,Inc. All rights reserved. Graph Algorithms • While these are neat, favor the Graph Algo procedures instead • https://neo4j.com/docs/graph-algorithms/current/ • Pathfinding: apoc.algo.dijkstra, apoc.algo.aStar • PageRank: apoc.algo.pageRankStats, apoc.algo.pageRankWithCypher • Centrality: apoc.algo.betweenness, apoc.algo.closeness • Clustering: apoc.algo.community, apoc.algo.wcc, apoc.algo.cliques • Node-Cover: apoc.algo.cover
  • 102.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. 103 Split 3rds - bullets When using bullets on the left , select all the bullets and use: Add space after list item to visually separate them Example of bullets: • Short point here not more than 3 lines • Another point which is not too long • Short and sweet
  • 103.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. 104 Neo4j Aura Enterprise is allowing us to realize our vision to build a knowledge graph that unifies all product knowledge to improve our retail recommendations, search and merchandising.” “ - Name and position, Company
  • 104.
    © 2022 Neo4j,Inc. All rights reserved. 105 Special slides examples 1 2 Arial Extra Bold 86pt for big numbers Arial Normal 14pt for small text 3 4 Arial Extra Bold 86pt for big numbers Arial Normal 14pt for small text
  • 105.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. 106 Thing to compare 2 Thing to compare 1 • Comparison 1 • Comparison 2 ◦ Details • Comparison 1 • Comparison 2 ◦ Details
  • 106.
    © 2022 Neo4j,Inc. All rights reserved. 107 1. Use Media Slide from Master 2. Image is cropped at width 4.62in, so it takes up half of the slide (and aligned with blue rectangle on the left) Media
  • 107.
    © 2022 Neo4j,Inc. All rights reserved. 108 Image Placeholder
  • 108.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. 109
  • 109.
    © 2022 Neo4j,Inc. All rights reserved. 110 Your Logo Here
  • 110.
    © 2022 Neo4j,Inc. All rights reserved. 111 111 Your Logo Here