© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
Wednesday, March 22
11:00 EDT 15:00 GMT
16:00 CET 20:30 IST
Intermediate Cypher
& Data Modelling
© 2022 Neo4j, Inc. All rights reserved.
Today we will cover
● Recap: Fundamentals of Graph Databases & Cypher
● How Cypher Queries Work
● Data Modeling Fundamentals
● Advanced Cypher Techniques
● Bring your questions!
© 2022 Neo4j, Inc. All rights reserved.
Follow along with AuraDB Free
● Sign in or Register at console.neo4j.io
● Click the New Instance button
● Choose the Empty instance option
● Copy your password or download your credentials.env file
● When the instance has started, click the Open button to open
Workspace
© 2022 Neo4j, Inc. All rights reserved.
Graph Database
Fundamentals
© 2022 Neo4j, Inc. All rights reserved.
Macbook
Graph Database
Fundamentals
Nodes
© 2022 Neo4j, Inc. All rights reserved.
Macbook
Graph Database
Fundamentals
Nodes
Nodes represent things
© 2022 Neo4j, Inc. All rights reserved.
Macbook
Product
Graph Database
Fundamentals
Nodes
Nodes represent things
Nodes can be identified by
one or more labels
© 2022 Neo4j, Inc. All rights reserved.
Macbook
Product
Graph Database
Fundamentals
Nodes
Nodes represent things
Nodes can be identified by
one or more labels
Fragile
© 2022 Neo4j, Inc. All rights reserved.
Macbook
Product
name: Macbook Pro
price: 2699.00
Graph Database
Fundamentals
Nodes
Nodes represent things
Nodes can be identified by
one or more labels
Nodes can hold properties
as key/value pairs
Fragile
© 2022 Neo4j, Inc. All rights reserved.
Customer
name: Adam
email: adam@neo4j.com
Graph Database
Fundamentals
Relationships
Product
name: Macbook Pro
price: 2699.00
© 2022 Neo4j, Inc. All rights reserved.
Customer
name: Adam
email: adam@neo4j.com
Graph Database
Fundamentals
Relationships
Product
name: Macbook Pro
price: 2699.00
© 2022 Neo4j, Inc. All rights reserved.
Customer
name: Adam
email: adam@neo4j.com
Graph Database
Fundamentals
Relationships
Relationships connect two nodes
Product
name: Macbook Pro
price: 2699.00
© 2022 Neo4j, Inc. All rights reserved.
Customer
name: Adam
email: adam@neo4j.com
Graph Database
Fundamentals
Relationships
Relationships connect two nodes
Relationships have a type
Product
name: Macbook Pro
price: 2699.00
RATED
© 2022 Neo4j, Inc. All rights reserved.
Relationships have a direction
Customer
name: Adam
email: adam@neo4j.com
Graph Database
Fundamentals
Relationships
Relationships connect two nodes
Relationships have a type
Product
name: Macbook Pro
price: 2699.00
RATED
© 2022 Neo4j, Inc. All rights reserved.
Relationships have a direction
Customer
name: Adam
email: adam@neo4j.com
Graph Database
Fundamentals
Relationships
Relationships connect two nodes
Relationships have a type
Product
name: Macbook Pro
price: 2699.00
RATED
stars: 3
createdAt: 2023-03-22
Relationships can hold properties
as key/value pairs
© 2022 Neo4j, Inc. All rights reserved.
Graph Database
Fundamentals
Cypher
Introduction to Cypher
Cypher is a declarative language that allows
you to identify patterns in your data using
an ASCII-art style syntax consisting of
brackets, dashes and arrows.
© 2022 Neo4j, Inc. All rights reserved.
Graph Database
Fundamentals
Cypher
Introduction to Cypher
Cypher is a declarative language that allows
you to identify patterns in your data using
an ASCII-art style syntax consisting of
brackets, dashes and arrows.
Product
RATED
Customer
© 2022 Neo4j, Inc. All rights reserved.
Graph Database
Fundamentals
Cypher
Introduction to Cypher
Cypher is a declarative language that allows
you to identify patterns in your data using
an ASCII-art style syntax consisting of
brackets, dashes and arrows.
Product
RATED
Customer
© 2022 Neo4j, Inc. All rights reserved.
Graph Database
Fundamentals
Cypher
Introduction to Cypher
Cypher is a declarative language that allows
you to identify patterns in your data using
an ASCII-art style syntax consisting of
brackets, dashes and arrows.
Product
RATED
Customer
(c:Customer)-[r:RATED]->(p:Product)
© 2022 Neo4j, Inc. All rights reserved.
Graph Database
Fundamentals
Cypher
Introduction to Cypher
Cypher is a declarative language that allows
you to identify patterns in your data using
an ASCII-art style syntax consisting of
brackets, dashes and arrows.
Product
RATED
Customer
(c:Customer)-[r:RATED]->(p:Product)
© 2022 Neo4j, Inc. All rights reserved.
Graph Database
Fundamentals
Cypher
Introduction to Cypher
Cypher is a declarative language that allows
you to identify patterns in your data using
an ASCII-art style syntax consisting of
brackets, dashes and arrows.
Product
RATED
Customer
(c:Customer)-[r:RATED]->(p:Product)
© 2022 Neo4j, Inc. All rights reserved.
Graph Database
Fundamentals
Cypher
Introduction to Cypher
Cypher is a declarative language that allows
you to identify patterns in your data using
an ASCII-art style syntax consisting of
brackets, dashes and arrows.
Product
RATED
Customer
(c:Customer)-[r:RATED]->(p:Product)
© 2022 Neo4j, Inc. All rights reserved.
Graph Database
Fundamentals
Cypher
Introduction to Cypher
Cypher is a declarative language that allows
you to identify patterns in your data using
an ASCII-art style syntax consisting of
brackets, dashes and arrows.
Product
RATED
Customer
(c:Customer)-[r:RATED]->(p:Product)
© 2022 Neo4j, Inc. All rights reserved.
Graph Database
Fundamentals
Cypher
Introduction to Cypher
Cypher is a declarative language that allows
you to identify patterns in your data using
an ASCII-art style syntax consisting of
brackets, dashes and arrows.
Product
RATED
Customer
(c:Customer)-[r:RATED]->(p:Product)
© 2022 Neo4j, Inc. All rights reserved.
Graph Database
Fundamentals
Cypher
Introduction to Cypher
Cypher is a declarative language that allows
you to identify patterns in your data using
an ASCII-art style syntax consisting of
brackets, dashes and arrows.
Product
RATED
Customer
(c:Customer)-[r:RATED]->(p:Product)
© 2022 Neo4j, Inc. All rights reserved.
name: Adam
email: adam@neo4j.com
Graph Database
Fundamentals
The MATCH clause
Product
name: Macbook Pro
price: 2699.00
RATED
stars: 3
createdAt: 2023-03-22
MATCH (c:Customer)-[r:RATED]->(p:Product)
RETURN c.name AS customer, p.name AS product, r.stars
AS rating
Customer
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
MATCH
(c:Customer)-[:PURCHASED]->(o:Order),
(o)-[:ORDERS]->(p:Product),
(p)-[:PART_OF]>(cc:Category),
(cc)<-[:HAS_CHILD*0..3]-(cat:Category)
WHERE c.customerId = “ANTON”
AND cat.name = “Electronics”
RETURN *
The MATCH clause
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
MATCH
(c:Customer)-[:PURCHASED]->(o:Order),
(o)-[:ORDERS]->(p:Product),
(p)-[:PART_OF]>(cc:Category),
(cc)<-[:HAS_CHILD*0..3]-(cat:Category)
WHERE c.customerId = “ANTON”
AND cat.name = “Electronics”
RETURN *
The MATCH clause
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
MATCH
(c:Customer)-[:PURCHASED]->(o:Order),
(o)-[:ORDERS]->(p:Product),
(p)-[:PART_OF]>(cc:Category),
(cc)<-[:HAS_CHILD*0..3]-(cat:Category)
WHERE c.customerId = “ANTON”
AND cat.name = “Electronics”
RETURN *
The MATCH clause
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
MATCH
(c:Customer)-[:PURCHASED]->(o:Order),
(o)-[:ORDERS]->(p:Product),
(p)-[:PART_OF]>(cc:Category),
(cc)<-[:HAS_CHILD*0..3]-(cat:Category)
WHERE c.customerId = “ANTON”
AND cat.name = “Electronics”
RETURN *
The MATCH clause
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
MATCH
(c:Customer)-[:PURCHASED]->(o:Order),
(o)-[:ORDERS]->(p:Product),
(p)-[:PART_OF]>(cc:Category),
(cc)<-[:HAS_CHILD*0..3]-(cat:Category)
WHERE c.customerId = “ANTON”
AND cat.name = “Electronics”
RETURN *
The MATCH clause
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
MATCH
(c:Customer)-[:PURCHASED]->(o:Order),
(o)-[:ORDERS]->(p:Product),
(p)-[:PART_OF]->(cc:Category),
(cc)<-[:HAS_CHILD*0..3]-(cat:Category)
WHERE c.customerId = “ANTON”
AND cat.name = “Electronics”
RETURN *
The MATCH clause
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
MATCH
(c:Customer)-[:PURCHASED]->(o:Order),
(o)-[:ORDERS]->(p:Product),
(p)-[:PART_OF]>(cc:Category),
(cc)<-[:HAS_CHILD*0..3]-(cat:Category)
WHERE c.customerId = “ANTON”
AND cat.name = “Electronics”
RETURN *
The MATCH clause
© 2022 Neo4j, Inc. All rights reserved.
• CREATE - Create a pattern in the graph
• MERGE - Find or create a pattern in the graph
• SET - Add a new label to a node or property to a node or relationship
• REMOVE - Remove a label from a node or property from node or
relationship
• DELETE - Delete a node or relationship from from the graph
Writing to Neo4j
© 2022 Neo4j, Inc. All rights reserved.
AS A
Customer
I WOULD LIKE TO
Register for the website
SO THAT I CAN
Buy my groceries online
A CREATE Example
© 2022 Neo4j, Inc. All rights reserved.
CREATE (c:Customer {
customerID: randomUuid(),
contactName: “Adam Cowley”,
address: “182-194 Union Street”,
city: “London”,
postalCode: “SE1 0LH”,
country: “United Kingdom”
})
A CREATE Example
© 2022 Neo4j, Inc. All rights reserved.
• The CREATE statement is used to create new nodes and relationships
• The MERGE statement will first search for the pattern, and if not found,
will attempt to create it
• You should MERGE when a node or relationship may not exist
• The whole pattern will be created if not found, so it is best to break the
pattern up into smaller pieces
CREATE or MERGE?
© 2022 Neo4j, Inc. All rights reserved.
A MERGE Example
// ❌ BAD
MERGE (p:Product {name: "Beavertown Neck Oil IPA"})
-[:PART_OF]->(cat1:Category {categoryName: "Beverages"})
© 2022 Neo4j, Inc. All rights reserved.
A MERGE Example
// ❌ BAD
MERGE (p:Product {name: "Beavertown Neck Oil IPA"})
-[:PART_OF]->(cat1:Category {categoryName: "Beverages"})
If the category already exists
but the product doesn’t, Neo4j
will attempt to create both
nodes and the relationship
© 2022 Neo4j, Inc. All rights reserved.
A MERGE Example
// ❌ BAD
MERGE (p:Product {name: "Beavertown Neck Oil IPA"})
-[:PART_OF]->(cat1:Category {categoryName: "Beverages"})
// ✅ GOOD
MERGE (cat1:Category {name: “Beverages”})
MERGE (cat2:Category {name: “Alcohol”})
MERGE (p:Product {name: “Beavertown Neck Oil IPA”})
MERGE (p)-[:PART_OF]->(cat1)
MERGE (p)-[:PART_OF]->(cat2)
© 2022 Neo4j, Inc. All rights reserved.
MERGE (p:Product {name: “Beavertown Neck Oil IPA”})
ON CREATE SET p.createdAt = datetime()
ON MATCH SET p:RestockedProduct
SET p.updatedAt = datetime()
REMOVE p:OutOfStock
SETting Properties and Labels
© 2022 Neo4j, Inc. All rights reserved.
MERGE (p:Product {name: “Beavertown Neck Oil IPA”})
ON CREATE SET p.createdAt = datetime()
ON MATCH SET p:RestockedProduct
SET p.updatedAt = datetime()
REMOVE p:OutOfStock
SETting Properties and Labels
Set a property when the node is first created
© 2022 Neo4j, Inc. All rights reserved.
MERGE (p:Product {name: “Beavertown Neck Oil IPA”})
ON CREATE SET p.createdAt = datetime()
ON MATCH SET p:RestockedProduct
SET p.updatedAt = datetime()
REMOVE p:OutOfStock
SETting Properties and Labels
Set a property if the node already exists
© 2022 Neo4j, Inc. All rights reserved.
MERGE (p:Product {name: “Beavertown Neck Oil IPA”})
ON CREATE SET p.createdAt = datetime()
ON MATCH SET p:RestockedProduct
SET p.updatedAt = datetime()
REMOVE p:OutOfStock
SETting Properties and Labels
Set a property regardless
© 2022 Neo4j, Inc. All rights reserved.
MERGE (p:Product {name: “Beavertown Neck Oil IPA”})
ON CREATE SET p.createdAt = datetime()
ON MATCH SET p:RestockedProduct
SET p.updatedAt = datetime()
REMOVE p:OutOfStock
SETting Properties and Labels
The REMOVE keyword will remove a label or property
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
Data Modeling
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
Derive your data model from your use case
Data Modeling
© 2022 Neo4j, Inc. All rights reserved.
AS A
Customer
I WOULD LIKE TO
Order a new Laptop and accessories
SO THAT I CAN
Build a website using a graph database
Nouns, Verbs and Adjectives
© 2022 Neo4j, Inc. All rights reserved.
AS A
Customer
I WOULD LIKE TO
Order a new Laptop and accessories
SO THAT I CAN
Build a website using a graph database
Nouns, Verbs and Adjectives
Product.
© 2022 Neo4j, Inc. All rights reserved.
AS A
Customer
I WOULD LIKE TO
Order a new Laptop and accessories
SO THAT I CAN
Build a website using a graph database
Nouns, Verbs and Adjectives
Product.
© 2022 Neo4j, Inc. All rights reserved.
Nouns, Verbs and Adjectives
AS A
Customer
I WOULD LIKE TO
Order a new Laptop and accessories
SO THAT I CAN
Build a website using a graph database
Product.
© 2022 Neo4j, Inc. All rights reserved.
Intermediate Nodes
© 2022 Neo4j, Inc. All rights reserved.
Intermediate Nodes
Knowing this fact might be
enough for your use case
© 2022 Neo4j, Inc. All rights reserved.
Intermediate Nodes
Knowing this fact might be
enough for your use case
© 2022 Neo4j, Inc. All rights reserved.
Intermediate Nodes
The order information can now
be linked to multiple nodes
Knowing this fact might be
enough for your use case
© 2022 Neo4j, Inc. All rights reserved.
Property, Relationship or Node - it depends…
© 2022 Neo4j, Inc. All rights reserved.
Property, Relationship or Node - it depends…
{
"customer": {
"CustomerID": "ALFKI",
"CompanyName": "Alfreds Futterkiste",
"ContactName": "Maria Anders",
"ContactTitle": "Sales Representative",
"Phone": "030-0074321",
"Fax": "030-0076545",
"email": "maria.anders@alfreds.de"
},
"address": {
"Address": "Obere Str. 57",
"City": "Berlin",
"Region": null,
"PostalCode": "12209",
"Country": "Germany"
},
"order": {
"OrderID": 10248,
"CustomerID": "ALFKI",
"EmployeeID": 5,
"OrderDate": "1996-07-04T00:00:00",
"RequiredDate": "1996-08-01T00:00:00",
"ShippedDate": "1996-07-16T00:00:00",
"ShipVia": 3,
"Freight": 32.38,
"ShipName": "Alfreds Futterkiste",
"ShipAddress": {
"Address": "Obere Str. 57",
"City": "Berlin",
"Region": null,
"PostalCode": "12209",
"Country": "Germany"
}
}
}
© 2022 Neo4j, Inc. All rights reserved.
● Many databases will duplicate data for
read-time performance
● Address is read-only? Store as a property
● Are billing and shipping addresses saved as
part of the checkout process? Store in a Node
● Are offers served to first-time customers that
are limited by address? Store in a Node
● Is the graph used to optimise delivery routes?
Store as a Node
Property, Relationship or Node - it depends…
{
"customer": {
"CustomerID": "ALFKI",
"CompanyName": "Alfreds Futterkiste",
"ContactName": "Maria Anders",
"ContactTitle": "Sales Representative",
"Phone": "030-0074321",
"Fax": "030-0076545",
"email": "maria.anders@alfreds.de"
},
"address": {
"Address": "Obere Str. 57",
"City": "Berlin",
"Region": null,
"PostalCode": "12209",
"Country": "Germany"
},
"order": {
"OrderID": 10248,
"CustomerID": "ALFKI",
"EmployeeID": 5,
"OrderDate": "1996-07-04T00:00:00",
"RequiredDate": "1996-08-01T00:00:00",
"ShippedDate": "1996-07-16T00:00:00",
"ShipVia": 3,
"Freight": 32.38,
"ShipName": "Alfreds Futterkiste",
"ShipAddress": {
"Address": "Obere Str. 57",
"City": "Berlin",
"Region": null,
"PostalCode": "12209",
"Country": "Germany"
}
}
}
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
The easy way, RDBMS to Graph
Data Modeling
© 2022 Neo4j, Inc. All rights reserved.
The Northwind
Database
© 2022 Neo4j, Inc. All rights reserved.
The Northwind
Database
© 2022 Neo4j, Inc. All rights reserved.
Relational
to Graph
© 2022 Neo4j, Inc. All rights reserved.
Relational
to Graph
Table names become
labels, individual records
become nodes
© 2022 Neo4j, Inc. All rights reserved.
Relational
to Graph
Foreign keys become
relationships
(:Supplier)-[:SUPPLIES]->(:Product)
(:Customer)-[:PURCHASED]->(:Order)
(:Shipper)-[:SHIPS]->(:Order)
© 2022 Neo4j, Inc. All rights reserved.
The Northwind
Database
Many-to-Many
Relationships
© 2022 Neo4j, Inc. All rights reserved.
The Northwind
Database
Many-to-Many
Relationships
© 2022 Neo4j, Inc. All rights reserved.
The Northwind
Database
Many-to-Many
Relationships
© 2022 Neo4j, Inc. All rights reserved.
The Northwind
Database
Many-to-Many
Relationships
��
© 2022 Neo4j, Inc. All rights reserved.
The Northwind
Database
Many-to-Many
Relationships
Order
C
O
N
T
A
I
N
S
PRODUCT
© 2022 Neo4j, Inc. All rights reserved.
The Northwind
Database
Many-to-Many
Relationships
Order
C
O
N
T
A
I
N
S
PRODUCT
u
n
i
t
P
r
i
c
e
:
n
u
m
b
e
r
q
u
a
n
t
i
t
y
:
n
u
m
b
e
r
d
i
s
c
o
u
n
t
:
f
l
o
a
t
© 2022 Neo4j, Inc. All rights reserved.
SQL to Cypher
SELECT o.ShipName, o.ShipAddress, o.ShipCity,
o.ShipRegion, o.ShipPostalCode, o.ShipCountry,
o.CustomerID, c.CompanyName AS CustomerName,
c.Address, c.City, c.Region,
c.PostalCode, c.Country,
(e.FirstName + ' ' + e.LastName) AS Salesperson,
o.OrderID, o.OrderDate, o.RequiredDate,
o.ShippedDate, s.CompanyName As ShipperName,
od.ProductID, p.ProductName,
od.UnitPrice, od.Quantity,
od.Discount, o.Freight,
(CONVERT(money,(od.UnitPrice*Quantity*(1-Discount)/100))*100) AS ExtendedPrice
FROM Customers c
INNER JOIN Products p ON p.ProductID = od.ProductID
INNER JOIN Orders o ON c.CustomerID = o.CustomerID
INNER JOIN OrderDetails od ON o.OrderID = od.OrderID
INNER JOIN Employees e ON e.EmployeeID = o.EmployeeID
INNER JOIN Shippers s ON s.ShipperID = o.ShipVia
WHERE c.customerID = "ANTON"
MATCH (c:Customer {customerID: "ANTON"})
-[:PURCHASED]->(o:Order), (o)-[od:ORDERED]->(p:Product),
(p)<-[:SHIPS]-(s:Shipper)
RETURN o.shipName, o.shipAddress, o.shipCity,
o.shipRegion, o.shipPostalCode, o.shipCountry,
c.customerID, c.companyName AS CustomerName,
c.address, c.city, c.region,
c.postalCode, c.country,
e.firstName +" "+ e.lastName AS Salesperson,
o.shippedDate, s.companyName AS ShipperName,
p.productID, p.productName,
od.unitPrice, od.quantity,
od.discount, od.freight,
od.unitPrice * od.quantity
* (1.0-od.discount)/100 * 100 AS ExtendedPrice
https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/databases/northwind-pubs/instnwnd.sql
© 2022 Neo4j, Inc. All rights reserved.
SQL to Cypher
MATCH (c:Customer {customerID: "ANTON"})
-[:PURCHASED]->(o:Order), (o)-[od:ORDERED]->(p:Product),
(p)<-[:SHIPS]-(s:Shipper)
RETURN o.shipName, o.shipAddress, o.shipCity,
o.shipRegion, o.shipPostalCode, o.shipCountry,
c.customerID, c.companyName AS CustomerName,
c.address, c.city, c.region,
c.postalCode, c.country,
e.firstName +" "+ e.lastName AS Salesperson,
o.shippedDate, s.companyName AS ShipperName,
p.productID, p.productName,
od.unitPrice, od.quantity,
od.discount, od.freight,
od.unitPrice * od.quantity
* (1.0-od.discount)/100 * 100 AS ExtendedPrice
https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/databases/northwind-pubs/instnwnd.sql
SELECT o.ShipName, o.ShipAddress, o.ShipCity,
o.ShipRegion, o.ShipPostalCode, o.ShipCountry,
o.CustomerID, c.CompanyName AS CustomerName,
c.Address, c.City, c.Region,
c.PostalCode, c.Country,
(e.FirstName + ' ' + e.LastName) AS Salesperson,
o.OrderID, o.OrderDate, o.RequiredDate,
o.ShippedDate, s.CompanyName As ShipperName,
od.ProductID, p.ProductName,
od.UnitPrice, od.Quantity,
od.Discount, o.Freight,
(CONVERT(money,(od.UnitPrice*Quantity*(1-Discount)/100))*100) AS ExtendedPrice
FROM Customers c
INNER JOIN Products p ON p.ProductID = od.ProductID
INNER JOIN Orders o ON c.CustomerID = o.CustomerID
INNER JOIN OrderDetails od ON o.OrderID = od.OrderID
INNER JOIN Employees e ON e.EmployeeID = o.EmployeeID
INNER JOIN Shippers s ON s.ShipperID = o.ShipVia
WHERE c.customerID = "ANTON"
© 2022 Neo4j, Inc. All rights reserved.
MATCH (c:Customer {customerID: "ANTON"})
-[:PURCHASED]->(o:Order), (o)-[od:ORDERED]->(p:Product),
(p)<-[:SHIPS]-(s:Shipper)
RETURN o.shipName, o.shipAddress, o.shipCity,
o.shipRegion, o.shipPostalCode, o.shipCountry,
c.customerID, c.companyName AS CustomerName,
c.address, c.city, c.region,
c.postalCode, c.country,
e.firstName +" "+ e.lastName AS Salesperson,
o.shippedDate, s.companyName AS ShipperName,
p.productID, p.productName,
od.unitPrice, od.quantity,
od.discount, od.freight,
od.unitPrice * od.quantity
* (1.0-od.discount)/100 * 100 AS ExtendedPrice
SQL to Cypher
https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/databases/northwind-pubs/instnwnd.sql
SELECT o.ShipName, o.ShipAddress, o.ShipCity,
o.ShipRegion, o.ShipPostalCode, o.ShipCountry,
o.CustomerID, c.CompanyName AS CustomerName,
c.Address, c.City, c.Region,
c.PostalCode, c.Country,
(e.FirstName + ' ' + e.LastName) AS Salesperson,
o.OrderID, o.OrderDate, o.RequiredDate,
o.ShippedDate, s.CompanyName As ShipperName,
od.ProductID, p.ProductName,
od.UnitPrice, od.Quantity,
od.Discount, o.Freight,
(CONVERT(money,(od.UnitPrice*Quantity*(1-Discount)/100))*100) AS ExtendedPrice
FROM Customers c
INNER JOIN Products p ON p.ProductID = od.ProductID
INNER JOIN Orders o ON c.CustomerID = o.CustomerID
INNER JOIN OrderDetails od ON o.OrderID = od.OrderID
INNER JOIN Employees e ON e.EmployeeID = o.EmployeeID
INNER JOIN Shippers s ON s.ShipperID = o.ShipVia
WHERE c.customerID = "ANTON"
© 2022 Neo4j, Inc. All rights reserved.
SQL to Cypher
SELECT o.ShipName, o.ShipAddress, o.ShipCity,
o.ShipRegion, o.ShipPostalCode, o.ShipCountry,
o.CustomerID, c.CompanyName AS CustomerName,
c.Address, c.City, c.Region,
c.PostalCode, c.Country,
(e.FirstName + ' ' + e.LastName) AS Salesperson,
o.OrderID, o.OrderDate, o.RequiredDate,
o.ShippedDate, s.CompanyName As ShipperName,
od.ProductID, p.ProductName,
od.UnitPrice, od.Quantity,
od.Discount, o.Freight,
(CONVERT(money,(od.UnitPrice*Quantity*(1-Discount)/100))*100) AS ExtendedPrice
FROM Customers c
INNER JOIN Products p ON p.ProductID = od.ProductID
INNER JOIN Orders o ON c.CustomerID = o.CustomerID
INNER JOIN OrderDetails od ON o.OrderID = od.OrderID
INNER JOIN Employees e ON e.EmployeeID = o.EmployeeID
INNER JOIN Shippers s ON s.ShipperID = o.ShipVia
WHERE c.customerID = "ANTON"
https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/databases/northwind-pubs/instnwnd.sql
MATCH (c:Customer {customerID: "ANTON"})
-[:PURCHASED]->(o:Order), (o)-[od:ORDERED]->(p:Product),
(p)<-[:SHIPS]-(s:Shipper)
RETURN o.shipName, o.shipAddress, o.shipCity,
o.shipRegion, o.shipPostalCode, o.shipCountry,
c.customerID, c.companyName AS CustomerName,
c.address, c.city, c.region,
c.postalCode, c.country,
e.firstName +" "+ e.lastName AS Salesperson,
o.shippedDate, s.companyName AS ShipperName,
p.productID, p.productName,
od.unitPrice, od.quantity,
od.discount, od.freight,
od.unitPrice * od.quantity
* (1.0-od.discount)/100 * 100 AS ExtendedPrice
© 2022 Neo4j, Inc. All rights reserved.
SQL to Cypher
SELECT o.ShipName, o.ShipAddress, o.ShipCity,
o.ShipRegion, o.ShipPostalCode, o.ShipCountry,
o.CustomerID, c.CompanyName AS CustomerName,
c.Address, c.City, c.Region,
c.PostalCode, c.Country,
(e.FirstName + ' ' + e.LastName) AS Salesperson,
o.OrderID, o.OrderDate, o.RequiredDate,
o.ShippedDate, s.CompanyName As ShipperName,
od.ProductID, p.ProductName,
od.UnitPrice, od.Quantity,
od.Discount, o.Freight,
(CONVERT(money,(od.UnitPrice*Quantity*(1-Discount)/100))*100) AS ExtendedPrice
FROM Customers c
INNER JOIN Products p ON p.ProductID = od.ProductID
INNER JOIN Orders o ON c.CustomerID = o.CustomerID
INNER JOIN OrderDetails od ON o.OrderID = od.OrderID
INNER JOIN Employees e ON e.EmployeeID = o.EmployeeID
INNER JOIN Shippers s ON s.ShipperID = o.ShipVia
WHERE c.customerID = "ANTON"
https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/databases/northwind-pubs/instnwnd.sql
MATCH (c:Customer {customerID: "ANTON"})
-[:PURCHASED]->(o:Order), (o)-[od:ORDERED]->(p:Product),
(p)<-[:SHIPS]-(s:Shipper)
RETURN o.shipName, o.shipAddress, o.shipCity,
o.shipRegion, o.shipPostalCode, o.shipCountry,
c.customerID, c.companyName AS CustomerName,
c.address, c.city, c.region,
c.postalCode, c.country,
e.firstName +" "+ e.lastName AS Salesperson,
o.shippedDate, s.companyName AS ShipperName,
p.productID, p.productName,
od.unitPrice, od.quantity,
od.discount, od.freight,
od.unitPrice * od.quantity
* (1.0-od.discount)/100 * 100 AS ExtendedPrice
© 2022 Neo4j, Inc. All rights reserved.
SQL to Cypher
SELECT o.ShipName, o.ShipAddress, o.ShipCity,
o.ShipRegion, o.ShipPostalCode, o.ShipCountry,
o.CustomerID, c.CompanyName AS CustomerName,
c.Address, c.City, c.Region,
c.PostalCode, c.Country,
(e.FirstName + ' ' + e.LastName) AS Salesperson,
o.OrderID, o.OrderDate, o.RequiredDate,
o.ShippedDate, s.CompanyName As ShipperName,
od.ProductID, p.ProductName,
od.UnitPrice, od.Quantity,
od.Discount, o.Freight,
(CONVERT(money,(od.UnitPrice*Quantity*(1-Discount)/100))*100) AS ExtendedPrice
FROM Customers c
INNER JOIN Products p ON p.ProductID = od.ProductID
INNER JOIN Orders o ON c.CustomerID = o.CustomerID
INNER JOIN OrderDetails od ON o.OrderID = od.OrderID
INNER JOIN Employees e ON e.EmployeeID = o.EmployeeID
INNER JOIN Shippers s ON s.ShipperID = o.ShipVia
WHERE c.customerID = "ANTON"
MATCH (c:Customer {customerID: "ANTON"})
-[:PURCHASED]->(o:Order), (o)-[od:ORDERED]->(p:Product),
(p)<-[:SHIPS]-(s:Shipper)
RETURN o.shipName, o.shipAddress, o.shipCity,
o.shipRegion, o.shipPostalCode, o.shipCountry,
c.customerID, c.companyName AS CustomerName,
c.address, c.city, c.region,
c.postalCode, c.country,
e.firstName +" "+ e.lastName AS Salesperson,
o.shippedDate, s.companyName AS ShipperName,
p.productID, p.productName,
od.unitPrice, od.quantity,
od.discount, od.freight,
od.unitPrice * od.quantity
* (1.0-od.discount)/100 * 100 AS ExtendedPrice
https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/databases/northwind-pubs/instnwnd.sql
© 2022 Neo4j, Inc. All rights reserved.
SQL to Cypher
SELECT o.ShipName, o.ShipAddress, o.ShipCity,
o.ShipRegion, o.ShipPostalCode, o.ShipCountry,
o.CustomerID, c.CompanyName AS CustomerName,
c.Address, c.City, c.Region,
c.PostalCode, c.Country,
(e.FirstName + ' ' + e.LastName) AS Salesperson,
o.OrderID, o.OrderDate, o.RequiredDate,
o.ShippedDate, s.CompanyName As ShipperName,
od.ProductID, p.ProductName,
od.UnitPrice, od.Quantity,
od.Discount, o.Freight,
(CONVERT(money,(od.UnitPrice*Quantity*(1-Discount)/100))*100) AS ExtendedPrice
FROM Customers c
INNER JOIN Products p ON p.ProductID = od.ProductID
INNER JOIN Orders o ON c.CustomerID = o.CustomerID
INNER JOIN OrderDetails od ON o.OrderID = od.OrderID
INNER JOIN Employees e ON e.EmployeeID = o.EmployeeID
INNER JOIN Shippers s ON s.ShipperID = o.ShipVia
WHERE c.customerID = "ANTON"
MATCH (c:Customer {customerID: "ANTON"})
-[:PURCHASED]->(o:Order), (o)-[od:ORDERED]->(p:Product),
(p)<-[:SHIPS]-(s:Shipper)
RETURN o.shipName, o.shipAddress, o.shipCity,
o.shipRegion, o.shipPostalCode, o.shipCountry,
c.customerID, c.companyName AS CustomerName,
c.address, c.city, c.region,
c.postalCode, c.country,
e.firstName +" "+ e.lastName AS Salesperson,
o.shippedDate, s.companyName AS ShipperName,
p.productID, p.productName,
od.unitPrice, od.quantity,
od.discount, od.freight,
od.unitPrice * od.quantity
* (1.0-od.discount)/100 * 100 AS ExtendedPrice
https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/databases/northwind-pubs/instnwnd.sql
© 2022 Neo4j, Inc. All rights reserved.
SQL to Cypher
SELECT o.ShipName, o.ShipAddress, o.ShipCity,
o.ShipRegion, o.ShipPostalCode, o.ShipCountry,
o.CustomerID, c.CompanyName AS CustomerName,
c.Address, c.City, c.Region,
c.PostalCode, c.Country,
(e.FirstName + ' ' + e.LastName) AS Salesperson,
o.OrderID, o.OrderDate, o.RequiredDate,
o.ShippedDate, s.CompanyName As ShipperName,
od.ProductID, p.ProductName,
od.UnitPrice, od.Quantity,
od.Discount, o.Freight,
(CONVERT(money,(od.UnitPrice*Quantity*(1-Discount)/100))*100) AS ExtendedPrice
FROM Customers c
INNER JOIN Products p ON p.ProductID = od.ProductID
INNER JOIN Orders o ON c.CustomerID = o.CustomerID
INNER JOIN OrderDetails od ON o.OrderID = od.OrderID
INNER JOIN Employees e ON e.EmployeeID = o.EmployeeID
INNER JOIN Shippers s ON s.ShipperID = o.ShipVia
WHERE c.customerID = "ANTON"
MATCH (c:Customer)
-[:PURCHASED]->(o:Order), (o)-[od:ORDERED]->(p:Product),
(p)<-[:SHIPS]-(s:Shipper)
WHERE c.customerID = "ANTON"
RETURN o.shipName, o.shipAddress, o.shipCity,
o.shipRegion, o.shipPostalCode, o.shipCountry,
c.customerID, c.companyName AS CustomerName,
c.address, c.city, c.region,
c.postalCode, c.country,
e.firstName +" "+ e.lastName AS Salesperson,
o.shippedDate, s.companyName AS ShipperName,
p.productID, p.productName,
od.unitPrice, od.quantity,
od.discount, od.freight,
od.unitPrice * od.quantity
* (1.0-od.discount)/100 * 100 AS ExtendedPrice
https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/databases/northwind-pubs/instnwnd.sql
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
Graph Refactoring
© 2022 Neo4j, Inc. All rights reserved.
● The graph as modeled does not answer all of the use cases.
● A new use case has come up that you must account for in your data
model.
● The Cypher for the use cases does not perform optimally, especially
when the graph scales
Why Refactor?
© 2022 Neo4j, Inc. All rights reserved.
● Create an Index or Constraint
● Adding a new label
● Extracting a property into a Node
● Specific relationship types
Methods of Refactoring
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
Adding a label
Graph Refactoring
© 2022 Neo4j, Inc. All rights reserved.
AS A
Sales Representative
I WOULD LIKE TO
Recommend alternatives to discontinued stock
SO THAT I CAN
Ensure Customers have a viable alternative to their favorite products
Adding a label
© 2022 Neo4j, Inc. All rights reserved.
● MATCH all (:Product {discontinued: true}) nodes
● Use the SET keyword to add a new label
● Measure the results
Adding a Discontinued label
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
Extracting a property into a Node
Graph Refactoring
© 2022 Neo4j, Inc. All rights reserved.
Refactoring Addresses to Nodes
AS A
Operations Manager
I WOULD LIKE TO
Find customers that live at the same address
SO THAT I CAN
Reduce driver workloads and improve delivery times by optimising delivery
routes
© 2022 Neo4j, Inc. All rights reserved.
● Create a Unique Constraint on (:Address)
● Use a MATCH statement to find Customer address details
● Use a MERGE statement to Find or Create an (:Address) Node
● MERGE a -[:HAS_ADDRESS]-> relationship between (:Customer) and
(:Address) Node
Refactoring Addresses to Nodes
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
Specific Relationship Types
Graph Refactoring
© 2022 Neo4j, Inc. All rights reserved.
Specific Relationship Types
© 2022 Neo4j, Inc. All rights reserved.
Refactoring Addresses to Nodes
AS A
Head of Electronic Sales
I WOULD LIKE TO
Find customers who have purchased electricals
SO THAT I CAN
Meet my sales targets by recommending them similar products
© 2022 Neo4j, Inc. All rights reserved.
Specific Relationship Types
© 2022 Neo4j, Inc. All rights reserved.
Specific Relationship Types
© 2022 Neo4j, Inc. All rights reserved.
Specific Relationship Types
© 2022 Neo4j, Inc. All rights reserved.
AS A
Warehouse Manager
I WOULD LIKE TO
Predict which products will be purchased in a given month
SO THAT I CAN
Maintain stock levels and manage customer expectations
Real-time Recommendations
© 2022 Neo4j, Inc. All rights reserved.
MATCH (c:Customer)-[:PURCHASED]->(o:Order)-[:ORDERS]->(p:Product)
RETURN c.customerID, p.productName, [ (p)-[:PART_OF]->(ct) |
ct.categoryName ], count(*) AS count ORDER BY count DESC
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
Fun with Cypher
© 2022 Neo4j, Inc. All rights reserved.
● Aggregation functions / min, max, count, collect - employee -> order ->
customer, then sum() to get amount, order by total in descending
● List expression to get products [0..5]
●
● WITH
● Sub Queries - customers other orders
● Who bought biscuits
○ Text search - STARTS WITH / ENDS WITH / CONTAINS
○ Exists patterns - where category isn’t in the biscuit
Reading Data
© 2022 Neo4j, Inc. All rights reserved.
AS A
Sales Manager
I WOULD LIKE TO
Find the most customers who have the highest spend
SO THAT I CAN
Reward their loyalty with personalised offers
Real-time Recommendations
© 2022 Neo4j, Inc. All rights reserved.
AS A
Regional Sales Manager
I WOULD LIKE TO
Identify our most active customers in my territory
SO THAT I CAN
Provide them with a personalised offer
Real-time Recommendations
© 2022 Neo4j, Inc. All rights reserved.
AS A
Warehouse Manager
I WOULD LIKE TO
What customers who purchase biscuits also buy
SO THAT I CAN
Shift a palette of biscuits that are near the end of their shelf life
Real-time Recommendations
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
Fun with Cypher
© 2022 Neo4j, Inc. All rights reserved.
AS A
Warehouse Manager
I WOULD LIKE TO
Find a list of
SO THAT I CAN
Reward their loyalty with personalised offers
Real-time Recommendations
© 2022 Neo4j, Inc. All rights reserved.
● Find the top 10 orders by total value
● Use a subquery to find their most purchased
products
○ Aggregation
● Use exits
Real-time Recommendations
WITH
Aggregation functions / min, max,
count, collect
Text search - STARTS WITH /
ENDS WITH / CONTAINS
Exists patterns
Profiling
Pattern comprehension
List expressions
Variable length paths
Sub Queries
Parameters
© 2022 Neo4j, Inc. All rights reserved.
© 2022 Neo4j, Inc. All rights reserved.
AS A
Customer
I WOULD LIKE TO
Receive personalised offers
SO THAT I CAN
Save money on my weekly shop
Real-time Recommendations
© 2022 Neo4j, Inc. All rights reserved.
AS A
Warehouse Manager
I WOULD LIKE TO
Sell excess stock as quickly as possible
SO THAT I CAN
Avoid wastage and increase profits
Real-time Recommendations

Intermediate Cypher.pdf

  • 1.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. Wednesday, March 22 11:00 EDT 15:00 GMT 16:00 CET 20:30 IST Intermediate Cypher & Data Modelling
  • 2.
    © 2022 Neo4j,Inc. All rights reserved. Today we will cover ● Recap: Fundamentals of Graph Databases & Cypher ● How Cypher Queries Work ● Data Modeling Fundamentals ● Advanced Cypher Techniques ● Bring your questions!
  • 3.
    © 2022 Neo4j,Inc. All rights reserved. Follow along with AuraDB Free ● Sign in or Register at console.neo4j.io ● Click the New Instance button ● Choose the Empty instance option ● Copy your password or download your credentials.env file ● When the instance has started, click the Open button to open Workspace
  • 4.
    © 2022 Neo4j,Inc. All rights reserved. Graph Database Fundamentals
  • 5.
    © 2022 Neo4j,Inc. All rights reserved. Macbook Graph Database Fundamentals Nodes
  • 6.
    © 2022 Neo4j,Inc. All rights reserved. Macbook Graph Database Fundamentals Nodes Nodes represent things
  • 7.
    © 2022 Neo4j,Inc. All rights reserved. Macbook Product Graph Database Fundamentals Nodes Nodes represent things Nodes can be identified by one or more labels
  • 8.
    © 2022 Neo4j,Inc. All rights reserved. Macbook Product Graph Database Fundamentals Nodes Nodes represent things Nodes can be identified by one or more labels Fragile
  • 9.
    © 2022 Neo4j,Inc. All rights reserved. Macbook Product name: Macbook Pro price: 2699.00 Graph Database Fundamentals Nodes Nodes represent things Nodes can be identified by one or more labels Nodes can hold properties as key/value pairs Fragile
  • 10.
    © 2022 Neo4j,Inc. All rights reserved. Customer name: Adam email: adam@neo4j.com Graph Database Fundamentals Relationships Product name: Macbook Pro price: 2699.00
  • 11.
    © 2022 Neo4j,Inc. All rights reserved. Customer name: Adam email: adam@neo4j.com Graph Database Fundamentals Relationships Product name: Macbook Pro price: 2699.00
  • 12.
    © 2022 Neo4j,Inc. All rights reserved. Customer name: Adam email: adam@neo4j.com Graph Database Fundamentals Relationships Relationships connect two nodes Product name: Macbook Pro price: 2699.00
  • 13.
    © 2022 Neo4j,Inc. All rights reserved. Customer name: Adam email: adam@neo4j.com Graph Database Fundamentals Relationships Relationships connect two nodes Relationships have a type Product name: Macbook Pro price: 2699.00 RATED
  • 14.
    © 2022 Neo4j,Inc. All rights reserved. Relationships have a direction Customer name: Adam email: adam@neo4j.com Graph Database Fundamentals Relationships Relationships connect two nodes Relationships have a type Product name: Macbook Pro price: 2699.00 RATED
  • 15.
    © 2022 Neo4j,Inc. All rights reserved. Relationships have a direction Customer name: Adam email: adam@neo4j.com Graph Database Fundamentals Relationships Relationships connect two nodes Relationships have a type Product name: Macbook Pro price: 2699.00 RATED stars: 3 createdAt: 2023-03-22 Relationships can hold properties as key/value pairs
  • 16.
    © 2022 Neo4j,Inc. All rights reserved. Graph Database Fundamentals Cypher Introduction to Cypher Cypher is a declarative language that allows you to identify patterns in your data using an ASCII-art style syntax consisting of brackets, dashes and arrows.
  • 17.
    © 2022 Neo4j,Inc. All rights reserved. Graph Database Fundamentals Cypher Introduction to Cypher Cypher is a declarative language that allows you to identify patterns in your data using an ASCII-art style syntax consisting of brackets, dashes and arrows. Product RATED Customer
  • 18.
    © 2022 Neo4j,Inc. All rights reserved. Graph Database Fundamentals Cypher Introduction to Cypher Cypher is a declarative language that allows you to identify patterns in your data using an ASCII-art style syntax consisting of brackets, dashes and arrows. Product RATED Customer
  • 19.
    © 2022 Neo4j,Inc. All rights reserved. Graph Database Fundamentals Cypher Introduction to Cypher Cypher is a declarative language that allows you to identify patterns in your data using an ASCII-art style syntax consisting of brackets, dashes and arrows. Product RATED Customer (c:Customer)-[r:RATED]->(p:Product)
  • 20.
    © 2022 Neo4j,Inc. All rights reserved. Graph Database Fundamentals Cypher Introduction to Cypher Cypher is a declarative language that allows you to identify patterns in your data using an ASCII-art style syntax consisting of brackets, dashes and arrows. Product RATED Customer (c:Customer)-[r:RATED]->(p:Product)
  • 21.
    © 2022 Neo4j,Inc. All rights reserved. Graph Database Fundamentals Cypher Introduction to Cypher Cypher is a declarative language that allows you to identify patterns in your data using an ASCII-art style syntax consisting of brackets, dashes and arrows. Product RATED Customer (c:Customer)-[r:RATED]->(p:Product)
  • 22.
    © 2022 Neo4j,Inc. All rights reserved. Graph Database Fundamentals Cypher Introduction to Cypher Cypher is a declarative language that allows you to identify patterns in your data using an ASCII-art style syntax consisting of brackets, dashes and arrows. Product RATED Customer (c:Customer)-[r:RATED]->(p:Product)
  • 23.
    © 2022 Neo4j,Inc. All rights reserved. Graph Database Fundamentals Cypher Introduction to Cypher Cypher is a declarative language that allows you to identify patterns in your data using an ASCII-art style syntax consisting of brackets, dashes and arrows. Product RATED Customer (c:Customer)-[r:RATED]->(p:Product)
  • 24.
    © 2022 Neo4j,Inc. All rights reserved. Graph Database Fundamentals Cypher Introduction to Cypher Cypher is a declarative language that allows you to identify patterns in your data using an ASCII-art style syntax consisting of brackets, dashes and arrows. Product RATED Customer (c:Customer)-[r:RATED]->(p:Product)
  • 25.
    © 2022 Neo4j,Inc. All rights reserved. Graph Database Fundamentals Cypher Introduction to Cypher Cypher is a declarative language that allows you to identify patterns in your data using an ASCII-art style syntax consisting of brackets, dashes and arrows. Product RATED Customer (c:Customer)-[r:RATED]->(p:Product)
  • 26.
    © 2022 Neo4j,Inc. All rights reserved. name: Adam email: adam@neo4j.com Graph Database Fundamentals The MATCH clause Product name: Macbook Pro price: 2699.00 RATED stars: 3 createdAt: 2023-03-22 MATCH (c:Customer)-[r:RATED]->(p:Product) RETURN c.name AS customer, p.name AS product, r.stars AS rating Customer
  • 27.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. MATCH (c:Customer)-[:PURCHASED]->(o:Order), (o)-[:ORDERS]->(p:Product), (p)-[:PART_OF]>(cc:Category), (cc)<-[:HAS_CHILD*0..3]-(cat:Category) WHERE c.customerId = “ANTON” AND cat.name = “Electronics” RETURN * The MATCH clause
  • 28.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. MATCH (c:Customer)-[:PURCHASED]->(o:Order), (o)-[:ORDERS]->(p:Product), (p)-[:PART_OF]>(cc:Category), (cc)<-[:HAS_CHILD*0..3]-(cat:Category) WHERE c.customerId = “ANTON” AND cat.name = “Electronics” RETURN * The MATCH clause
  • 29.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. MATCH (c:Customer)-[:PURCHASED]->(o:Order), (o)-[:ORDERS]->(p:Product), (p)-[:PART_OF]>(cc:Category), (cc)<-[:HAS_CHILD*0..3]-(cat:Category) WHERE c.customerId = “ANTON” AND cat.name = “Electronics” RETURN * The MATCH clause
  • 30.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. MATCH (c:Customer)-[:PURCHASED]->(o:Order), (o)-[:ORDERS]->(p:Product), (p)-[:PART_OF]>(cc:Category), (cc)<-[:HAS_CHILD*0..3]-(cat:Category) WHERE c.customerId = “ANTON” AND cat.name = “Electronics” RETURN * The MATCH clause
  • 31.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. MATCH (c:Customer)-[:PURCHASED]->(o:Order), (o)-[:ORDERS]->(p:Product), (p)-[:PART_OF]>(cc:Category), (cc)<-[:HAS_CHILD*0..3]-(cat:Category) WHERE c.customerId = “ANTON” AND cat.name = “Electronics” RETURN * The MATCH clause
  • 32.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. MATCH (c:Customer)-[:PURCHASED]->(o:Order), (o)-[:ORDERS]->(p:Product), (p)-[:PART_OF]->(cc:Category), (cc)<-[:HAS_CHILD*0..3]-(cat:Category) WHERE c.customerId = “ANTON” AND cat.name = “Electronics” RETURN * The MATCH clause
  • 33.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. MATCH (c:Customer)-[:PURCHASED]->(o:Order), (o)-[:ORDERS]->(p:Product), (p)-[:PART_OF]>(cc:Category), (cc)<-[:HAS_CHILD*0..3]-(cat:Category) WHERE c.customerId = “ANTON” AND cat.name = “Electronics” RETURN * The MATCH clause
  • 34.
    © 2022 Neo4j,Inc. All rights reserved. • CREATE - Create a pattern in the graph • MERGE - Find or create a pattern in the graph • SET - Add a new label to a node or property to a node or relationship • REMOVE - Remove a label from a node or property from node or relationship • DELETE - Delete a node or relationship from from the graph Writing to Neo4j
  • 35.
    © 2022 Neo4j,Inc. All rights reserved. AS A Customer I WOULD LIKE TO Register for the website SO THAT I CAN Buy my groceries online A CREATE Example
  • 36.
    © 2022 Neo4j,Inc. All rights reserved. CREATE (c:Customer { customerID: randomUuid(), contactName: “Adam Cowley”, address: “182-194 Union Street”, city: “London”, postalCode: “SE1 0LH”, country: “United Kingdom” }) A CREATE Example
  • 37.
    © 2022 Neo4j,Inc. All rights reserved. • The CREATE statement is used to create new nodes and relationships • The MERGE statement will first search for the pattern, and if not found, will attempt to create it • You should MERGE when a node or relationship may not exist • The whole pattern will be created if not found, so it is best to break the pattern up into smaller pieces CREATE or MERGE?
  • 38.
    © 2022 Neo4j,Inc. All rights reserved. A MERGE Example // ❌ BAD MERGE (p:Product {name: "Beavertown Neck Oil IPA"}) -[:PART_OF]->(cat1:Category {categoryName: "Beverages"})
  • 39.
    © 2022 Neo4j,Inc. All rights reserved. A MERGE Example // ❌ BAD MERGE (p:Product {name: "Beavertown Neck Oil IPA"}) -[:PART_OF]->(cat1:Category {categoryName: "Beverages"}) If the category already exists but the product doesn’t, Neo4j will attempt to create both nodes and the relationship
  • 40.
    © 2022 Neo4j,Inc. All rights reserved. A MERGE Example // ❌ BAD MERGE (p:Product {name: "Beavertown Neck Oil IPA"}) -[:PART_OF]->(cat1:Category {categoryName: "Beverages"}) // ✅ GOOD MERGE (cat1:Category {name: “Beverages”}) MERGE (cat2:Category {name: “Alcohol”}) MERGE (p:Product {name: “Beavertown Neck Oil IPA”}) MERGE (p)-[:PART_OF]->(cat1) MERGE (p)-[:PART_OF]->(cat2)
  • 41.
    © 2022 Neo4j,Inc. All rights reserved. MERGE (p:Product {name: “Beavertown Neck Oil IPA”}) ON CREATE SET p.createdAt = datetime() ON MATCH SET p:RestockedProduct SET p.updatedAt = datetime() REMOVE p:OutOfStock SETting Properties and Labels
  • 42.
    © 2022 Neo4j,Inc. All rights reserved. MERGE (p:Product {name: “Beavertown Neck Oil IPA”}) ON CREATE SET p.createdAt = datetime() ON MATCH SET p:RestockedProduct SET p.updatedAt = datetime() REMOVE p:OutOfStock SETting Properties and Labels Set a property when the node is first created
  • 43.
    © 2022 Neo4j,Inc. All rights reserved. MERGE (p:Product {name: “Beavertown Neck Oil IPA”}) ON CREATE SET p.createdAt = datetime() ON MATCH SET p:RestockedProduct SET p.updatedAt = datetime() REMOVE p:OutOfStock SETting Properties and Labels Set a property if the node already exists
  • 44.
    © 2022 Neo4j,Inc. All rights reserved. MERGE (p:Product {name: “Beavertown Neck Oil IPA”}) ON CREATE SET p.createdAt = datetime() ON MATCH SET p:RestockedProduct SET p.updatedAt = datetime() REMOVE p:OutOfStock SETting Properties and Labels Set a property regardless
  • 45.
    © 2022 Neo4j,Inc. All rights reserved. MERGE (p:Product {name: “Beavertown Neck Oil IPA”}) ON CREATE SET p.createdAt = datetime() ON MATCH SET p:RestockedProduct SET p.updatedAt = datetime() REMOVE p:OutOfStock SETting Properties and Labels The REMOVE keyword will remove a label or property
  • 46.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. Data Modeling
  • 47.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. Derive your data model from your use case Data Modeling
  • 48.
    © 2022 Neo4j,Inc. All rights reserved. AS A Customer I WOULD LIKE TO Order a new Laptop and accessories SO THAT I CAN Build a website using a graph database Nouns, Verbs and Adjectives
  • 49.
    © 2022 Neo4j,Inc. All rights reserved. AS A Customer I WOULD LIKE TO Order a new Laptop and accessories SO THAT I CAN Build a website using a graph database Nouns, Verbs and Adjectives Product.
  • 50.
    © 2022 Neo4j,Inc. All rights reserved. AS A Customer I WOULD LIKE TO Order a new Laptop and accessories SO THAT I CAN Build a website using a graph database Nouns, Verbs and Adjectives Product.
  • 51.
    © 2022 Neo4j,Inc. All rights reserved. Nouns, Verbs and Adjectives AS A Customer I WOULD LIKE TO Order a new Laptop and accessories SO THAT I CAN Build a website using a graph database Product.
  • 52.
    © 2022 Neo4j,Inc. All rights reserved. Intermediate Nodes
  • 53.
    © 2022 Neo4j,Inc. All rights reserved. Intermediate Nodes Knowing this fact might be enough for your use case
  • 54.
    © 2022 Neo4j,Inc. All rights reserved. Intermediate Nodes Knowing this fact might be enough for your use case
  • 55.
    © 2022 Neo4j,Inc. All rights reserved. Intermediate Nodes The order information can now be linked to multiple nodes Knowing this fact might be enough for your use case
  • 56.
    © 2022 Neo4j,Inc. All rights reserved. Property, Relationship or Node - it depends…
  • 57.
    © 2022 Neo4j,Inc. All rights reserved. Property, Relationship or Node - it depends… { "customer": { "CustomerID": "ALFKI", "CompanyName": "Alfreds Futterkiste", "ContactName": "Maria Anders", "ContactTitle": "Sales Representative", "Phone": "030-0074321", "Fax": "030-0076545", "email": "maria.anders@alfreds.de" }, "address": { "Address": "Obere Str. 57", "City": "Berlin", "Region": null, "PostalCode": "12209", "Country": "Germany" }, "order": { "OrderID": 10248, "CustomerID": "ALFKI", "EmployeeID": 5, "OrderDate": "1996-07-04T00:00:00", "RequiredDate": "1996-08-01T00:00:00", "ShippedDate": "1996-07-16T00:00:00", "ShipVia": 3, "Freight": 32.38, "ShipName": "Alfreds Futterkiste", "ShipAddress": { "Address": "Obere Str. 57", "City": "Berlin", "Region": null, "PostalCode": "12209", "Country": "Germany" } } }
  • 58.
    © 2022 Neo4j,Inc. All rights reserved. ● Many databases will duplicate data for read-time performance ● Address is read-only? Store as a property ● Are billing and shipping addresses saved as part of the checkout process? Store in a Node ● Are offers served to first-time customers that are limited by address? Store in a Node ● Is the graph used to optimise delivery routes? Store as a Node Property, Relationship or Node - it depends… { "customer": { "CustomerID": "ALFKI", "CompanyName": "Alfreds Futterkiste", "ContactName": "Maria Anders", "ContactTitle": "Sales Representative", "Phone": "030-0074321", "Fax": "030-0076545", "email": "maria.anders@alfreds.de" }, "address": { "Address": "Obere Str. 57", "City": "Berlin", "Region": null, "PostalCode": "12209", "Country": "Germany" }, "order": { "OrderID": 10248, "CustomerID": "ALFKI", "EmployeeID": 5, "OrderDate": "1996-07-04T00:00:00", "RequiredDate": "1996-08-01T00:00:00", "ShippedDate": "1996-07-16T00:00:00", "ShipVia": 3, "Freight": 32.38, "ShipName": "Alfreds Futterkiste", "ShipAddress": { "Address": "Obere Str. 57", "City": "Berlin", "Region": null, "PostalCode": "12209", "Country": "Germany" } } }
  • 59.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. The easy way, RDBMS to Graph Data Modeling
  • 60.
    © 2022 Neo4j,Inc. All rights reserved. The Northwind Database
  • 61.
    © 2022 Neo4j,Inc. All rights reserved. The Northwind Database
  • 62.
    © 2022 Neo4j,Inc. All rights reserved. Relational to Graph
  • 63.
    © 2022 Neo4j,Inc. All rights reserved. Relational to Graph Table names become labels, individual records become nodes
  • 64.
    © 2022 Neo4j,Inc. All rights reserved. Relational to Graph Foreign keys become relationships (:Supplier)-[:SUPPLIES]->(:Product) (:Customer)-[:PURCHASED]->(:Order) (:Shipper)-[:SHIPS]->(:Order)
  • 65.
    © 2022 Neo4j,Inc. All rights reserved. The Northwind Database Many-to-Many Relationships
  • 66.
    © 2022 Neo4j,Inc. All rights reserved. The Northwind Database Many-to-Many Relationships
  • 67.
    © 2022 Neo4j,Inc. All rights reserved. The Northwind Database Many-to-Many Relationships
  • 68.
    © 2022 Neo4j,Inc. All rights reserved. The Northwind Database Many-to-Many Relationships ��
  • 69.
    © 2022 Neo4j,Inc. All rights reserved. The Northwind Database Many-to-Many Relationships Order C O N T A I N S PRODUCT
  • 70.
    © 2022 Neo4j,Inc. All rights reserved. The Northwind Database Many-to-Many Relationships Order C O N T A I N S PRODUCT u n i t P r i c e : n u m b e r q u a n t i t y : n u m b e r d i s c o u n t : f l o a t
  • 71.
    © 2022 Neo4j,Inc. All rights reserved. SQL to Cypher SELECT o.ShipName, o.ShipAddress, o.ShipCity, o.ShipRegion, o.ShipPostalCode, o.ShipCountry, o.CustomerID, c.CompanyName AS CustomerName, c.Address, c.City, c.Region, c.PostalCode, c.Country, (e.FirstName + ' ' + e.LastName) AS Salesperson, o.OrderID, o.OrderDate, o.RequiredDate, o.ShippedDate, s.CompanyName As ShipperName, od.ProductID, p.ProductName, od.UnitPrice, od.Quantity, od.Discount, o.Freight, (CONVERT(money,(od.UnitPrice*Quantity*(1-Discount)/100))*100) AS ExtendedPrice FROM Customers c INNER JOIN Products p ON p.ProductID = od.ProductID INNER JOIN Orders o ON c.CustomerID = o.CustomerID INNER JOIN OrderDetails od ON o.OrderID = od.OrderID INNER JOIN Employees e ON e.EmployeeID = o.EmployeeID INNER JOIN Shippers s ON s.ShipperID = o.ShipVia WHERE c.customerID = "ANTON" MATCH (c:Customer {customerID: "ANTON"}) -[:PURCHASED]->(o:Order), (o)-[od:ORDERED]->(p:Product), (p)<-[:SHIPS]-(s:Shipper) RETURN o.shipName, o.shipAddress, o.shipCity, o.shipRegion, o.shipPostalCode, o.shipCountry, c.customerID, c.companyName AS CustomerName, c.address, c.city, c.region, c.postalCode, c.country, e.firstName +" "+ e.lastName AS Salesperson, o.shippedDate, s.companyName AS ShipperName, p.productID, p.productName, od.unitPrice, od.quantity, od.discount, od.freight, od.unitPrice * od.quantity * (1.0-od.discount)/100 * 100 AS ExtendedPrice https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/databases/northwind-pubs/instnwnd.sql
  • 72.
    © 2022 Neo4j,Inc. All rights reserved. SQL to Cypher MATCH (c:Customer {customerID: "ANTON"}) -[:PURCHASED]->(o:Order), (o)-[od:ORDERED]->(p:Product), (p)<-[:SHIPS]-(s:Shipper) RETURN o.shipName, o.shipAddress, o.shipCity, o.shipRegion, o.shipPostalCode, o.shipCountry, c.customerID, c.companyName AS CustomerName, c.address, c.city, c.region, c.postalCode, c.country, e.firstName +" "+ e.lastName AS Salesperson, o.shippedDate, s.companyName AS ShipperName, p.productID, p.productName, od.unitPrice, od.quantity, od.discount, od.freight, od.unitPrice * od.quantity * (1.0-od.discount)/100 * 100 AS ExtendedPrice https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/databases/northwind-pubs/instnwnd.sql SELECT o.ShipName, o.ShipAddress, o.ShipCity, o.ShipRegion, o.ShipPostalCode, o.ShipCountry, o.CustomerID, c.CompanyName AS CustomerName, c.Address, c.City, c.Region, c.PostalCode, c.Country, (e.FirstName + ' ' + e.LastName) AS Salesperson, o.OrderID, o.OrderDate, o.RequiredDate, o.ShippedDate, s.CompanyName As ShipperName, od.ProductID, p.ProductName, od.UnitPrice, od.Quantity, od.Discount, o.Freight, (CONVERT(money,(od.UnitPrice*Quantity*(1-Discount)/100))*100) AS ExtendedPrice FROM Customers c INNER JOIN Products p ON p.ProductID = od.ProductID INNER JOIN Orders o ON c.CustomerID = o.CustomerID INNER JOIN OrderDetails od ON o.OrderID = od.OrderID INNER JOIN Employees e ON e.EmployeeID = o.EmployeeID INNER JOIN Shippers s ON s.ShipperID = o.ShipVia WHERE c.customerID = "ANTON"
  • 73.
    © 2022 Neo4j,Inc. All rights reserved. MATCH (c:Customer {customerID: "ANTON"}) -[:PURCHASED]->(o:Order), (o)-[od:ORDERED]->(p:Product), (p)<-[:SHIPS]-(s:Shipper) RETURN o.shipName, o.shipAddress, o.shipCity, o.shipRegion, o.shipPostalCode, o.shipCountry, c.customerID, c.companyName AS CustomerName, c.address, c.city, c.region, c.postalCode, c.country, e.firstName +" "+ e.lastName AS Salesperson, o.shippedDate, s.companyName AS ShipperName, p.productID, p.productName, od.unitPrice, od.quantity, od.discount, od.freight, od.unitPrice * od.quantity * (1.0-od.discount)/100 * 100 AS ExtendedPrice SQL to Cypher https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/databases/northwind-pubs/instnwnd.sql SELECT o.ShipName, o.ShipAddress, o.ShipCity, o.ShipRegion, o.ShipPostalCode, o.ShipCountry, o.CustomerID, c.CompanyName AS CustomerName, c.Address, c.City, c.Region, c.PostalCode, c.Country, (e.FirstName + ' ' + e.LastName) AS Salesperson, o.OrderID, o.OrderDate, o.RequiredDate, o.ShippedDate, s.CompanyName As ShipperName, od.ProductID, p.ProductName, od.UnitPrice, od.Quantity, od.Discount, o.Freight, (CONVERT(money,(od.UnitPrice*Quantity*(1-Discount)/100))*100) AS ExtendedPrice FROM Customers c INNER JOIN Products p ON p.ProductID = od.ProductID INNER JOIN Orders o ON c.CustomerID = o.CustomerID INNER JOIN OrderDetails od ON o.OrderID = od.OrderID INNER JOIN Employees e ON e.EmployeeID = o.EmployeeID INNER JOIN Shippers s ON s.ShipperID = o.ShipVia WHERE c.customerID = "ANTON"
  • 74.
    © 2022 Neo4j,Inc. All rights reserved. SQL to Cypher SELECT o.ShipName, o.ShipAddress, o.ShipCity, o.ShipRegion, o.ShipPostalCode, o.ShipCountry, o.CustomerID, c.CompanyName AS CustomerName, c.Address, c.City, c.Region, c.PostalCode, c.Country, (e.FirstName + ' ' + e.LastName) AS Salesperson, o.OrderID, o.OrderDate, o.RequiredDate, o.ShippedDate, s.CompanyName As ShipperName, od.ProductID, p.ProductName, od.UnitPrice, od.Quantity, od.Discount, o.Freight, (CONVERT(money,(od.UnitPrice*Quantity*(1-Discount)/100))*100) AS ExtendedPrice FROM Customers c INNER JOIN Products p ON p.ProductID = od.ProductID INNER JOIN Orders o ON c.CustomerID = o.CustomerID INNER JOIN OrderDetails od ON o.OrderID = od.OrderID INNER JOIN Employees e ON e.EmployeeID = o.EmployeeID INNER JOIN Shippers s ON s.ShipperID = o.ShipVia WHERE c.customerID = "ANTON" https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/databases/northwind-pubs/instnwnd.sql MATCH (c:Customer {customerID: "ANTON"}) -[:PURCHASED]->(o:Order), (o)-[od:ORDERED]->(p:Product), (p)<-[:SHIPS]-(s:Shipper) RETURN o.shipName, o.shipAddress, o.shipCity, o.shipRegion, o.shipPostalCode, o.shipCountry, c.customerID, c.companyName AS CustomerName, c.address, c.city, c.region, c.postalCode, c.country, e.firstName +" "+ e.lastName AS Salesperson, o.shippedDate, s.companyName AS ShipperName, p.productID, p.productName, od.unitPrice, od.quantity, od.discount, od.freight, od.unitPrice * od.quantity * (1.0-od.discount)/100 * 100 AS ExtendedPrice
  • 75.
    © 2022 Neo4j,Inc. All rights reserved. SQL to Cypher SELECT o.ShipName, o.ShipAddress, o.ShipCity, o.ShipRegion, o.ShipPostalCode, o.ShipCountry, o.CustomerID, c.CompanyName AS CustomerName, c.Address, c.City, c.Region, c.PostalCode, c.Country, (e.FirstName + ' ' + e.LastName) AS Salesperson, o.OrderID, o.OrderDate, o.RequiredDate, o.ShippedDate, s.CompanyName As ShipperName, od.ProductID, p.ProductName, od.UnitPrice, od.Quantity, od.Discount, o.Freight, (CONVERT(money,(od.UnitPrice*Quantity*(1-Discount)/100))*100) AS ExtendedPrice FROM Customers c INNER JOIN Products p ON p.ProductID = od.ProductID INNER JOIN Orders o ON c.CustomerID = o.CustomerID INNER JOIN OrderDetails od ON o.OrderID = od.OrderID INNER JOIN Employees e ON e.EmployeeID = o.EmployeeID INNER JOIN Shippers s ON s.ShipperID = o.ShipVia WHERE c.customerID = "ANTON" https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/databases/northwind-pubs/instnwnd.sql MATCH (c:Customer {customerID: "ANTON"}) -[:PURCHASED]->(o:Order), (o)-[od:ORDERED]->(p:Product), (p)<-[:SHIPS]-(s:Shipper) RETURN o.shipName, o.shipAddress, o.shipCity, o.shipRegion, o.shipPostalCode, o.shipCountry, c.customerID, c.companyName AS CustomerName, c.address, c.city, c.region, c.postalCode, c.country, e.firstName +" "+ e.lastName AS Salesperson, o.shippedDate, s.companyName AS ShipperName, p.productID, p.productName, od.unitPrice, od.quantity, od.discount, od.freight, od.unitPrice * od.quantity * (1.0-od.discount)/100 * 100 AS ExtendedPrice
  • 76.
    © 2022 Neo4j,Inc. All rights reserved. SQL to Cypher SELECT o.ShipName, o.ShipAddress, o.ShipCity, o.ShipRegion, o.ShipPostalCode, o.ShipCountry, o.CustomerID, c.CompanyName AS CustomerName, c.Address, c.City, c.Region, c.PostalCode, c.Country, (e.FirstName + ' ' + e.LastName) AS Salesperson, o.OrderID, o.OrderDate, o.RequiredDate, o.ShippedDate, s.CompanyName As ShipperName, od.ProductID, p.ProductName, od.UnitPrice, od.Quantity, od.Discount, o.Freight, (CONVERT(money,(od.UnitPrice*Quantity*(1-Discount)/100))*100) AS ExtendedPrice FROM Customers c INNER JOIN Products p ON p.ProductID = od.ProductID INNER JOIN Orders o ON c.CustomerID = o.CustomerID INNER JOIN OrderDetails od ON o.OrderID = od.OrderID INNER JOIN Employees e ON e.EmployeeID = o.EmployeeID INNER JOIN Shippers s ON s.ShipperID = o.ShipVia WHERE c.customerID = "ANTON" MATCH (c:Customer {customerID: "ANTON"}) -[:PURCHASED]->(o:Order), (o)-[od:ORDERED]->(p:Product), (p)<-[:SHIPS]-(s:Shipper) RETURN o.shipName, o.shipAddress, o.shipCity, o.shipRegion, o.shipPostalCode, o.shipCountry, c.customerID, c.companyName AS CustomerName, c.address, c.city, c.region, c.postalCode, c.country, e.firstName +" "+ e.lastName AS Salesperson, o.shippedDate, s.companyName AS ShipperName, p.productID, p.productName, od.unitPrice, od.quantity, od.discount, od.freight, od.unitPrice * od.quantity * (1.0-od.discount)/100 * 100 AS ExtendedPrice https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/databases/northwind-pubs/instnwnd.sql
  • 77.
    © 2022 Neo4j,Inc. All rights reserved. SQL to Cypher SELECT o.ShipName, o.ShipAddress, o.ShipCity, o.ShipRegion, o.ShipPostalCode, o.ShipCountry, o.CustomerID, c.CompanyName AS CustomerName, c.Address, c.City, c.Region, c.PostalCode, c.Country, (e.FirstName + ' ' + e.LastName) AS Salesperson, o.OrderID, o.OrderDate, o.RequiredDate, o.ShippedDate, s.CompanyName As ShipperName, od.ProductID, p.ProductName, od.UnitPrice, od.Quantity, od.Discount, o.Freight, (CONVERT(money,(od.UnitPrice*Quantity*(1-Discount)/100))*100) AS ExtendedPrice FROM Customers c INNER JOIN Products p ON p.ProductID = od.ProductID INNER JOIN Orders o ON c.CustomerID = o.CustomerID INNER JOIN OrderDetails od ON o.OrderID = od.OrderID INNER JOIN Employees e ON e.EmployeeID = o.EmployeeID INNER JOIN Shippers s ON s.ShipperID = o.ShipVia WHERE c.customerID = "ANTON" MATCH (c:Customer {customerID: "ANTON"}) -[:PURCHASED]->(o:Order), (o)-[od:ORDERED]->(p:Product), (p)<-[:SHIPS]-(s:Shipper) RETURN o.shipName, o.shipAddress, o.shipCity, o.shipRegion, o.shipPostalCode, o.shipCountry, c.customerID, c.companyName AS CustomerName, c.address, c.city, c.region, c.postalCode, c.country, e.firstName +" "+ e.lastName AS Salesperson, o.shippedDate, s.companyName AS ShipperName, p.productID, p.productName, od.unitPrice, od.quantity, od.discount, od.freight, od.unitPrice * od.quantity * (1.0-od.discount)/100 * 100 AS ExtendedPrice https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/databases/northwind-pubs/instnwnd.sql
  • 78.
    © 2022 Neo4j,Inc. All rights reserved. SQL to Cypher SELECT o.ShipName, o.ShipAddress, o.ShipCity, o.ShipRegion, o.ShipPostalCode, o.ShipCountry, o.CustomerID, c.CompanyName AS CustomerName, c.Address, c.City, c.Region, c.PostalCode, c.Country, (e.FirstName + ' ' + e.LastName) AS Salesperson, o.OrderID, o.OrderDate, o.RequiredDate, o.ShippedDate, s.CompanyName As ShipperName, od.ProductID, p.ProductName, od.UnitPrice, od.Quantity, od.Discount, o.Freight, (CONVERT(money,(od.UnitPrice*Quantity*(1-Discount)/100))*100) AS ExtendedPrice FROM Customers c INNER JOIN Products p ON p.ProductID = od.ProductID INNER JOIN Orders o ON c.CustomerID = o.CustomerID INNER JOIN OrderDetails od ON o.OrderID = od.OrderID INNER JOIN Employees e ON e.EmployeeID = o.EmployeeID INNER JOIN Shippers s ON s.ShipperID = o.ShipVia WHERE c.customerID = "ANTON" MATCH (c:Customer) -[:PURCHASED]->(o:Order), (o)-[od:ORDERED]->(p:Product), (p)<-[:SHIPS]-(s:Shipper) WHERE c.customerID = "ANTON" RETURN o.shipName, o.shipAddress, o.shipCity, o.shipRegion, o.shipPostalCode, o.shipCountry, c.customerID, c.companyName AS CustomerName, c.address, c.city, c.region, c.postalCode, c.country, e.firstName +" "+ e.lastName AS Salesperson, o.shippedDate, s.companyName AS ShipperName, p.productID, p.productName, od.unitPrice, od.quantity, od.discount, od.freight, od.unitPrice * od.quantity * (1.0-od.discount)/100 * 100 AS ExtendedPrice https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/databases/northwind-pubs/instnwnd.sql
  • 79.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. Graph Refactoring
  • 80.
    © 2022 Neo4j,Inc. All rights reserved. ● The graph as modeled does not answer all of the use cases. ● A new use case has come up that you must account for in your data model. ● The Cypher for the use cases does not perform optimally, especially when the graph scales Why Refactor?
  • 81.
    © 2022 Neo4j,Inc. All rights reserved. ● Create an Index or Constraint ● Adding a new label ● Extracting a property into a Node ● Specific relationship types Methods of Refactoring
  • 82.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. Adding a label Graph Refactoring
  • 83.
    © 2022 Neo4j,Inc. All rights reserved. AS A Sales Representative I WOULD LIKE TO Recommend alternatives to discontinued stock SO THAT I CAN Ensure Customers have a viable alternative to their favorite products Adding a label
  • 84.
    © 2022 Neo4j,Inc. All rights reserved. ● MATCH all (:Product {discontinued: true}) nodes ● Use the SET keyword to add a new label ● Measure the results Adding a Discontinued label
  • 85.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. Extracting a property into a Node Graph Refactoring
  • 86.
    © 2022 Neo4j,Inc. All rights reserved. Refactoring Addresses to Nodes AS A Operations Manager I WOULD LIKE TO Find customers that live at the same address SO THAT I CAN Reduce driver workloads and improve delivery times by optimising delivery routes
  • 87.
    © 2022 Neo4j,Inc. All rights reserved. ● Create a Unique Constraint on (:Address) ● Use a MATCH statement to find Customer address details ● Use a MERGE statement to Find or Create an (:Address) Node ● MERGE a -[:HAS_ADDRESS]-> relationship between (:Customer) and (:Address) Node Refactoring Addresses to Nodes
  • 88.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. Specific Relationship Types Graph Refactoring
  • 89.
    © 2022 Neo4j,Inc. All rights reserved. Specific Relationship Types
  • 90.
    © 2022 Neo4j,Inc. All rights reserved. Refactoring Addresses to Nodes AS A Head of Electronic Sales I WOULD LIKE TO Find customers who have purchased electricals SO THAT I CAN Meet my sales targets by recommending them similar products
  • 91.
    © 2022 Neo4j,Inc. All rights reserved. Specific Relationship Types
  • 92.
    © 2022 Neo4j,Inc. All rights reserved. Specific Relationship Types
  • 93.
    © 2022 Neo4j,Inc. All rights reserved. Specific Relationship Types
  • 94.
    © 2022 Neo4j,Inc. All rights reserved. AS A Warehouse Manager I WOULD LIKE TO Predict which products will be purchased in a given month SO THAT I CAN Maintain stock levels and manage customer expectations Real-time Recommendations
  • 95.
    © 2022 Neo4j,Inc. All rights reserved. MATCH (c:Customer)-[:PURCHASED]->(o:Order)-[:ORDERS]->(p:Product) RETURN c.customerID, p.productName, [ (p)-[:PART_OF]->(ct) | ct.categoryName ], count(*) AS count ORDER BY count DESC
  • 96.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. Fun with Cypher
  • 97.
    © 2022 Neo4j,Inc. All rights reserved. ● Aggregation functions / min, max, count, collect - employee -> order -> customer, then sum() to get amount, order by total in descending ● List expression to get products [0..5] ● ● WITH ● Sub Queries - customers other orders ● Who bought biscuits ○ Text search - STARTS WITH / ENDS WITH / CONTAINS ○ Exists patterns - where category isn’t in the biscuit Reading Data
  • 98.
    © 2022 Neo4j,Inc. All rights reserved. AS A Sales Manager I WOULD LIKE TO Find the most customers who have the highest spend SO THAT I CAN Reward their loyalty with personalised offers Real-time Recommendations
  • 99.
    © 2022 Neo4j,Inc. All rights reserved. AS A Regional Sales Manager I WOULD LIKE TO Identify our most active customers in my territory SO THAT I CAN Provide them with a personalised offer Real-time Recommendations
  • 100.
    © 2022 Neo4j,Inc. All rights reserved. AS A Warehouse Manager I WOULD LIKE TO What customers who purchase biscuits also buy SO THAT I CAN Shift a palette of biscuits that are near the end of their shelf life Real-time Recommendations
  • 101.
    © 2022 Neo4j,Inc. All rights reserved. © 2022 Neo4j, Inc. All rights reserved. Fun with Cypher
  • 102.
    © 2022 Neo4j,Inc. All rights reserved. AS A Warehouse Manager I WOULD LIKE TO Find a list of SO THAT I CAN Reward their loyalty with personalised offers Real-time Recommendations
  • 103.
    © 2022 Neo4j,Inc. All rights reserved. ● Find the top 10 orders by total value ● Use a subquery to find their most purchased products ○ Aggregation ● Use exits Real-time Recommendations WITH Aggregation functions / min, max, count, collect Text search - STARTS WITH / ENDS WITH / CONTAINS Exists patterns Profiling Pattern comprehension List expressions Variable length paths Sub Queries Parameters
  • 104.
    © 2022 Neo4j,Inc. All rights reserved.
  • 105.
    © 2022 Neo4j,Inc. All rights reserved. AS A Customer I WOULD LIKE TO Receive personalised offers SO THAT I CAN Save money on my weekly shop Real-time Recommendations
  • 106.
    © 2022 Neo4j,Inc. All rights reserved. AS A Warehouse Manager I WOULD LIKE TO Sell excess stock as quickly as possible SO THAT I CAN Avoid wastage and increase profits Real-time Recommendations