Cyphers to create graph:
CREATE (:CoffeeShop { javaId: '1', name: 'CoffeeShop' });
CREATE (:Table { javaId: '1', name: 'Table', material: 'Wood' });
CREATE (:Bowl { javaId: '1', name: 'Bowl', material: 'Ceramic' });
CREATE (:Brand { javaId: '1', name: 'Nestle', country: 'USA' });
CREATE (:CoffeeType { javaId: '1', name: 'Coffee' });
CREATE (:CoffeeType { javaId: '2', name: 'Latte' });
CREATE (:CoffeeType { javaId: '3', name: 'Cappuccino' });
CREATE (:CoffeeType { javaId: '4', name: 'Americano' });
CREATE (:Creamer { javaId: '1', name: 'CoffeeMate', volume: '10ml', requiresShaking: true, requiresRefrigeration: true, expiryDate: '03-27-2025' });
CREATE (:Creamer { javaId: '2', name: 'CoffeeMate', volume: '10ml', requiresShaking: true, requiresRefrigeration: true, expiryDate: '03-27-2025' });
CREATE (:Creamer { javaId: '3', name: 'CoffeeMate', volume: '10ml', requiresShaking: true, requiresRefrigeration: true, expiryDate: '03-27-2025' });
CREATE (:Creamer { javaId: '4', name: 'CoffeeMate', volume: '10ml', requiresShaking: true, requiresRefrigeration: true, expiryDate: '03-27-2025' });
CREATE (:Creamer { javaId: '5', name: 'CoffeeMate', volume: '10ml', requiresShaking: true, requiresRefrigeration: true, expiryDate: '03-27-2025' });
CREATE (:Creamer { javaId: '6', name: 'CoffeeMate', volume: '10ml', requiresShaking: true, requiresRefrigeration: true, expiryDate: '03-27-2025' });
CREATE (:Creamer { javaId: '7', name: 'CoffeeMate', volume: '10ml', requiresShaking: true, requiresRefrigeration: true, expiryDate: '03-27-2025' });
CREATE (:Creamer { javaId: '8', name: 'CoffeeMate', volume: '10ml', requiresShaking: true, requiresRefrigeration: true, expiryDate: '03-27-2025' });
CREATE (:Creamer { javaId: '9', name: 'CoffeeMate', volume: '10ml', requiresShaking: true, requiresRefrigeration: true, expiryDate: '03-27-2025' });
CREATE (:Creamer { javaId: '10', name: 'CoffeeMate', volume: '10ml', requiresShaking: true, requiresRefrigeration: true, expiryDate: '03-27-2025' });
CREATE (:Creamer { javaId: '11', name: 'CoffeeMate', volume: '10ml', requiresShaking: true, requiresRefrigeration: true, expiryDate: '03-27-2025' });
CREATE (:Creamer { javaId: '12', name: 'CoffeeMate', volume: '10ml', requiresShaking: true, requiresRefrigeration: true, expiryDate: '03-27-2025' });
CREATE (:Creamer { javaId: '13', name: 'CoffeeMate', volume: '10ml', requiresShaking: true, requiresRefrigeration: true, expiryDate: '03-27-2025' });
CREATE (:Creamer { javaId: '14', name: 'CoffeeMate', volume: '10ml', requiresShaking: true, requiresRefrigeration: true, expiryDate: '03-27-2025' });
CREATE (:Flavour { javaId: '1', name: 'Irish Cream' });
CREATE (:Flavour { javaId: '2', name: 'Hazelnut' });
CREATE (:Flavour { javaId: '3', name: 'French Vanilla' });
CREATE (:Flavour { javaId: '4', name: 'Italian Sweet Creme' });
MATCH (a:CoffeeShop { javaId: '1'})
MATCH (b:Table { javaId: '1'})
MERGE (a)-[:HAS_CONTENTS]->(b);
MATCH (a:Table { javaId: '1'})
MATCH (b:Bowl { javaId: '1'})
MERGE (a)-[:HAS_CONTENTS]->(b);
MATCH (a:Bowl { javaId: '1'})
MATCH (b:Creamer) WHERE b.javaId IN ['1','2','3','4','5','6','7','8','9','10','11','12','13','14']
MERGE (a)-[:HAS_CONTENTS]->(b);
MATCH (a:Brand { javaId: '1'})
MATCH (b:Creamer) WHERE b.javaId IN ['1','2','3','4','5','6','7','8','9','10','11','12','13','14']
MERGE (b)-[:CREATED_BY]->(a);
MATCH (a:Flavour { javaId: '1'})
MATCH (b:Creamer) WHERE b.javaId IN ['1','2','3']
MERGE (b)-[:HAS_FLAVOUR]->(a);
MATCH (a:Flavour { javaId: '2'})
MATCH (b:Creamer) WHERE b.javaId IN ['4','5','6','7']
MERGE (b)-[:HAS_FLAVOUR]->(a);
MATCH (a:Flavour { javaId: '3'})
MATCH (b:Creamer) WHERE b.javaId IN ['8','9','10','11']
MERGE (b)-[:HAS_FLAVOUR]->(a);
MATCH (a:Flavour { javaId: '4'})
MATCH (b:Creamer) WHERE b.javaId IN ['12','13','14']
MERGE (b)-[:HAS_FLAVOUR]->(a);
MATCH (a:CoffeeType { javaId: '1'})
MATCH (b:Flavour) WHERE b.javaId IN ['1','2']
MERGE (a)-[:PAIRS_WELL_WITH]->(b);
MATCH (a:CoffeeType { javaId: '2'})
MATCH (b:Flavour) WHERE b.javaId = '4'
MERGE (a)-[:PAIRS_WELL_WITH]->(b);
MATCH (a:CoffeeType { javaId: '3'})
MATCH (b:Flavour) WHERE b.javaId IN ['2','3']
MERGE (a)-[:PAIRS_WELL_WITH]->(b);
MATCH (a:CoffeeType { javaId: '4'})
MATCH (b:Flavour) WHERE b.javaId IN ['1','2','3','4']
MERGE (a)-[:PAIRS_WELL_WITH]->(b);
This graph covers two areas of interest:
- The physical inventory of the coffee shop(only what is shown in the image)
- How the creamers relate to coffee types
From left to right in the graph, we have a CoffeeShop node representing the coffee shop itself, which has a Table. The table has a Bowl, which contains the 14 Creamers. The same HAS_CONTENTS relationship is used for the entire physical inventory hierarchy to make downstream deep traversal easier with the variable length path.
Each Creamer has some properties, and a relationship to its creator Nestle. The creamers are also related to specific Flavours(i.e. French Vanilla, Irish Creme etc.). Each Flavour has a relationship to a type of coffee with which it "pairs well" with.
See the attached cypher file for the properties associated with each node type. I used "javaId" as the unique identifier of each node.
Below are some cyphers to query the physical inventory, and coffee related data:
Get all of the downstream physical contents starting from the Table
MATCH path=(t:Table)-[:HAS_CONTENTS*]->(contents)
WHERE t.javaId = '1'
RETURN contents
Get all Creamers that have Irish Creme flavour
MATCH (c:Creamer)-[:HAS_FLAVOUR]->(f:Flavour)
WHERE f.name = 'Irish Cream'
RETURN c
Get all Flavours that pair well with Cappuccino
MATCH (f:Flavour)<-[:PAIRS_WELL_WITH]-(c:CoffeeType)
WHERE c.name = 'Cappuccino'
RETURN f
Get all Creamers that have Flavours that pair well with Coffee
MATCH (c:Creamer)-[:HAS_FLAVOUR]->(f:Flavour)<-[:PAIRS_WELL_WITH]-(ct:CoffeeType)
WHERE ct.name = 'Coffee'
RETURN c
Get the CoffeeType(s) that pair well with the most Flavours
MATCH (ct:CoffeeType)-[r:PAIRS_WELL_WITH]->(f:Flavour)
WITH ct, COUNT(r) AS relCount
ORDER BY relCount DESC
WITH COLLECT({ node: ct, count: relCount }) AS nodes
RETURN [n IN nodes WHERE n.count = nodes[0].count] AS topCoffeeTypes