Hi, great challenge!
Here goes my attempt:
Here are the queries to create the graph:
// Define node labels and their properties using MERGE for idempotent execution
// Product node (Coffee-mate brand)
MERGE (brand:Brand {name: "Coffee-mate"})
ON CREATE SET brand.manufacturer = "Nestlé"
// Region/Country nodes
MERGE (france:Region {name: "France"})
ON CREATE SET france.type = "Country", france.continent = "Europe"
MERGE (italy:Region {name: "Italy"})
ON CREATE SET italy.type = "Country", italy.continent = "Europe"
MERGE (ireland:Region {name: "Ireland"})
ON CREATE SET ireland.type = "Country", ireland.continent = "Europe"
// Flavor nodes
MERGE (hazelnut:Flavor {name: "Hazelnut"})
ON CREATE SET hazelnut.type = "Nut", hazelnut.isArtificial = true
MERGE (frenchVanilla:Flavor {name: "French Vanilla"})
ON CREATE SET frenchVanilla.type = "Vanilla", frenchVanilla.isArtificial = true, frenchVanilla.isNatural = true
MERGE (italianCreme:Flavor {name: "Italian Sweet Creme"})
ON CREATE SET italianCreme.type = "Cream", italianCreme.isArtificial = true
MERGE (irishCreme:Flavor {name: "Irish Creme"})
ON CREATE SET irishCreme.type = "Cream", irishCreme.isArtificial = true
// Ingredient nodes
MERGE (milk:Ingredient {name: "Milk Derivative"})
MERGE (sugar:Ingredient {name: "Sugar"})
MERGE (vegetableOil:Ingredient {name: "Vegetable Oil"})
// Packaging nodes
MERGE (singleServe:Packaging {type: "Single Serve"})
ON CREATE SET singleServe.material = "Plastic"
// Product type nodes
MERGE (hazelnutCreamer:ProductType {name: "Hazelnut Coffee Creamer"})
ON CREATE SET hazelnutCreamer.sku = "CM-HZ-001"
MERGE (frenchVanillaCreamer:ProductType {name: "French Vanilla Coffee Creamer"})
ON CREATE SET frenchVanillaCreamer.sku = "CM-FV-001"
MERGE (italianCremeCreamer:ProductType {name: "Italian Sweet Creme Coffee Creamer"})
ON CREATE SET italianCremeCreamer.sku = "CM-IC-001"
MERGE (irishCremeCreamer:ProductType {name: "Irish Creme Coffee Creamer"})
ON CREATE SET irishCremeCreamer.sku = "CM-IRC-001"
// Storage nodes
MERGE (refrigeration:StorageRequirement {type: "Refrigeration"})
ON CREATE SET refrigeration.temperature = "Below 40°F"
// Dietary notes
MERGE (lactose:DietaryNote {type: "Contains Lactose"})
MERGE (shakeWell:Instruction {instruction: "Shake Well"})
// Create relationships between nodes for product types
// Brand to Product Types
MERGE (brand)-[:PRODUCES]->(hazelnutCreamer)
MERGE (brand)-[:PRODUCES]->(frenchVanillaCreamer)
MERGE (brand)-[:PRODUCES]->(italianCremeCreamer)
MERGE (brand)-[:PRODUCES]->(irishCremeCreamer)
// Product Types to Flavors
MERGE (hazelnutCreamer)-[:HAS_FLAVOR]->(hazelnut)
MERGE (frenchVanillaCreamer)-[:HAS_FLAVOR]->(frenchVanilla)
MERGE (italianCremeCreamer)-[:HAS_FLAVOR]->(italianCreme)
MERGE (irishCremeCreamer)-[:HAS_FLAVOR]->(irishCreme)
// Flavors to Regions
MERGE (frenchVanilla)-[:INSPIRED_BY]->(france)
MERGE (italianCreme)-[:INSPIRED_BY]->(italy)
MERGE (irishCreme)-[:INSPIRED_BY]->(ireland)
// Product Types to Ingredients
MERGE (hazelnutCreamer)-[:CONTAINS]->(milk)
MERGE (hazelnutCreamer)-[:CONTAINS]->(sugar)
MERGE (hazelnutCreamer)-[:CONTAINS]->(vegetableOil)
MERGE (frenchVanillaCreamer)-[:CONTAINS]->(milk)
MERGE (frenchVanillaCreamer)-[:CONTAINS]->(sugar)
MERGE (frenchVanillaCreamer)-[:CONTAINS]->(vegetableOil)
MERGE (italianCremeCreamer)-[:CONTAINS]->(milk)
MERGE (italianCremeCreamer)-[:CONTAINS]->(sugar)
MERGE (italianCremeCreamer)-[:CONTAINS]->(vegetableOil)
MERGE (irishCremeCreamer)-[:CONTAINS]->(milk)
MERGE (irishCremeCreamer)-[:CONTAINS]->(sugar)
MERGE (irishCremeCreamer)-[:CONTAINS]->(vegetableOil)
// Product Types to Packaging
MERGE (hazelnutCreamer)-[:PACKAGED_IN]->(singleServe)
MERGE (frenchVanillaCreamer)-[:PACKAGED_IN]->(singleServe)
MERGE (italianCremeCreamer)-[:PACKAGED_IN]->(singleServe)
MERGE (irishCremeCreamer)-[:PACKAGED_IN]->(singleServe)
// Product Types to Storage Requirements
MERGE (hazelnutCreamer)-[:REQUIRES]->(refrigeration)
MERGE (frenchVanillaCreamer)-[:REQUIRES]->(refrigeration)
MERGE (italianCremeCreamer)-[:REQUIRES]->(refrigeration)
MERGE (irishCremeCreamer)-[:REQUIRES]->(refrigeration)
// Product Types to Instructions
MERGE (hazelnutCreamer)-[:INSTRUCTION]->(shakeWell)
MERGE (frenchVanillaCreamer)-[:INSTRUCTION]->(shakeWell)
MERGE (italianCremeCreamer)-[:INSTRUCTION]->(shakeWell)
MERGE (irishCremeCreamer)-[:INSTRUCTION]->(shakeWell)
// Product Types to Dietary Notes
MERGE (hazelnutCreamer)-[:DIETARY_NOTE]->(lactose)
MERGE (frenchVanillaCreamer)-[:DIETARY_NOTE]->(lactose)
MERGE (italianCremeCreamer)-[:DIETARY_NOTE]->(lactose)
MERGE (irishCremeCreamer)-[:DIETARY_NOTE]->(lactose)
// Individual CoffeeMate creamer units
// Based on the image, create individual creamer unit nodes with unique IDs
// Hazelnut creamer units (3 units in the image)
MERGE (hz1:CreamerUnit {id: "HZ-001"})
ON CREATE SET hz1.productionDate = "2025-01-15"
MERGE (hz1)-[:IS_TYPE_OF]->(hazelnutCreamer)
MERGE (hz2:CreamerUnit {id: "HZ-002"})
ON CREATE SET hz2.productionDate = "2025-01-15"
MERGE (hz2)-[:IS_TYPE_OF]->(hazelnutCreamer)
MERGE (hz3:CreamerUnit {id: "HZ-003"})
ON CREATE SET hz3.productionDate = "2025-01-16"
MERGE (hz3)-[:IS_TYPE_OF]->(hazelnutCreamer)
// French Vanilla creamer units (4 units in the image)
MERGE (fv1:CreamerUnit {id: "FV-001"})
ON CREATE SET fv1.productionDate = "2025-01-10"
MERGE (fv1)-[:IS_TYPE_OF]->(frenchVanillaCreamer)
MERGE (fv2:CreamerUnit {id: "FV-002"})
ON CREATE SET fv2.productionDate = "2025-01-10"
MERGE (fv2)-[:IS_TYPE_OF]->(frenchVanillaCreamer)
MERGE (fv3:CreamerUnit {id: "FV-003"})
ON CREATE SET fv3.productionDate = "2025-01-11"
MERGE (fv3)-[:IS_TYPE_OF]->(frenchVanillaCreamer)
MERGE (fv4:CreamerUnit {id: "FV-004"})
ON CREATE SET fv4.productionDate = "2025-01-11"
MERGE (fv4)-[:IS_TYPE_OF]->(frenchVanillaCreamer)
// Italian Sweet Creme creamer units (4 units in the image)
MERGE (ic1:CreamerUnit {id: "IC-001"})
ON CREATE SET ic1.productionDate = "2025-01-12"
MERGE (ic1)-[:IS_TYPE_OF]->(italianCremeCreamer)
MERGE (ic2:CreamerUnit {id: "IC-002"})
ON CREATE SET ic2.productionDate = "2025-01-12"
MERGE (ic2)-[:IS_TYPE_OF]->(italianCremeCreamer)
MERGE (ic3:CreamerUnit {id: "IC-003"})
ON CREATE SET ic3.productionDate = "2025-01-13"
MERGE (ic3)-[:IS_TYPE_OF]->(italianCremeCreamer)
MERGE (ic4:CreamerUnit {id: "IC-004"})
ON CREATE SET ic4.productionDate = "2025-01-13"
MERGE (ic4)-[:IS_TYPE_OF]->(italianCremeCreamer)
// Irish Creme creamer units (3 units in the image)
MERGE (irc1:CreamerUnit {id: "IRC-001"})
ON CREATE SET irc1.productionDate = "2025-01-14"
MERGE (irc1)-[:IS_TYPE_OF]->(irishCremeCreamer)
MERGE (irc2:CreamerUnit {id: "IRC-002"})
ON CREATE SET irc2.productionDate = "2025-01-14"
MERGE (irc2)-[:IS_TYPE_OF]->(irishCremeCreamer)
MERGE (irc3:CreamerUnit {id: "IRC-003"})
ON CREATE SET irc3.productionDate = "2025-01-15"
MERGE (irc3)-[:IS_TYPE_OF]->(irishCremeCreamer)
// Spatial relationships between creamer units based on the image
// These relationships represent which creamers are adjacent to each other in the photo
// Creating [:ADJACENT_TO] relationships to represent spatial proximity
// Using MERGE for each relationship to ensure they're created only once
// Center of the arrangement has the most connections
// Looking at the image, there appears to be a central French Vanilla unit (fv3) with many connections
// Hazelnut adjacency relationships
MERGE (hz1)-[:ADJACENT_TO]->(fv1)
MERGE (hz1)-[:ADJACENT_TO]->(hz2)
MERGE (hz1)-[:ADJACENT_TO]->(fv2)
MERGE (hz2)-[:ADJACENT_TO]->(hz1)
MERGE (hz2)-[:ADJACENT_TO]->(fv2)
MERGE (hz2)-[:ADJACENT_TO]->(ic1)
MERGE (hz2)-[:ADJACENT_TO]->(hz3)
MERGE (hz3)-[:ADJACENT_TO]->(hz2)
MERGE (hz3)-[:ADJACENT_TO]->(ic1)
MERGE (hz3)-[:ADJACENT_TO]->(ic2)
// French Vanilla adjacency relationships
MERGE (fv1)-[:ADJACENT_TO]->(hz1)
MERGE (fv1)-[:ADJACENT_TO]->(fv2)
MERGE (fv1)-[:ADJACENT_TO]->(fv3)
MERGE (fv2)-[:ADJACENT_TO]->(fv1)
MERGE (fv2)-[:ADJACENT_TO]->(hz1)
MERGE (fv2)-[:ADJACENT_TO]->(hz2)
MERGE (fv2)-[:ADJACENT_TO]->(fv3)
MERGE (fv2)-[:ADJACENT_TO]->(ic1)
MERGE (fv3)-[:ADJACENT_TO]->(fv1)
MERGE (fv3)-[:ADJACENT_TO]->(fv2)
MERGE (fv3)-[:ADJACENT_TO]->(ic1)
MERGE (fv3)-[:ADJACENT_TO]->(ic4)
MERGE (fv3)-[:ADJACENT_TO]->(fv4)
MERGE (fv3)-[:ADJACENT_TO]->(irc1)
MERGE (fv4)-[:ADJACENT_TO]->(fv3)
MERGE (fv4)-[:ADJACENT_TO]->(irc1)
MERGE (fv4)-[:ADJACENT_TO]->(ic4)
MERGE (fv4)-[:ADJACENT_TO]->(irc2)
// Italian Sweet Creme adjacency relationships
MERGE (ic1)-[:ADJACENT_TO]->(hz2)
MERGE (ic1)-[:ADJACENT_TO]->(hz3)
MERGE (ic1)-[:ADJACENT_TO]->(fv2)
MERGE (ic1)-[:ADJACENT_TO]->(fv3)
MERGE (ic1)-[:ADJACENT_TO]->(ic2)
MERGE (ic1)-[:ADJACENT_TO]->(ic4)
MERGE (ic2)-[:ADJACENT_TO]->(hz3)
MERGE (ic2)-[:ADJACENT_TO]->(ic1)
MERGE (ic2)-[:ADJACENT_TO]->(ic3)
MERGE (ic2)-[:ADJACENT_TO]->(ic4)
MERGE (ic3)-[:ADJACENT_TO]->(ic2)
MERGE (ic3)-[:ADJACENT_TO]->(ic4)
MERGE (ic3)-[:ADJACENT_TO]->(irc2)
MERGE (ic3)-[:ADJACENT_TO]->(irc3)
MERGE (ic4)-[:ADJACENT_TO]->(ic1)
MERGE (ic4)-[:ADJACENT_TO]->(ic2)
MERGE (ic4)-[:ADJACENT_TO]->(ic3)
MERGE (ic4)-[:ADJACENT_TO]->(fv3)
MERGE (ic4)-[:ADJACENT_TO]->(fv4)
MERGE (ic4)-[:ADJACENT_TO]->(irc1)
MERGE (ic4)-[:ADJACENT_TO]->(irc2)
// Irish Creme adjacency relationships
MERGE (irc1)-[:ADJACENT_TO]->(fv3)
MERGE (irc1)-[:ADJACENT_TO]->(fv4)
MERGE (irc1)-[:ADJACENT_TO]->(ic4)
MERGE (irc1)-[:ADJACENT_TO]->(irc2)
MERGE (irc2)-[:ADJACENT_TO]->(irc1)
MERGE (irc2)-[:ADJACENT_TO]->(fv4)
MERGE (irc2)-[:ADJACENT_TO]->(ic4)
MERGE (irc2)-[:ADJACENT_TO]->(ic3)
MERGE (irc2)-[:ADJACENT_TO]->(irc3)
MERGE (irc3)-[:ADJACENT_TO]->(irc2)
MERGE (irc3)-[:ADJACENT_TO]->(ic3)
Here are some sample queries:
// Sample queries to retrieve information
// Count the number of creamer units by flavor
MATCH (cu:CreamerUnit)-[:IS_TYPE_OF]->(pt:ProductType)-[:HAS_FLAVOR]->(f:Flavor)
RETURN f.name AS Flavor, COUNT(cu) AS UnitCount
ORDER BY UnitCount DESC
// Count the number of creamer units by product type
MATCH (cu:CreamerUnit)-[:IS_TYPE_OF]->(pt:ProductType)
RETURN pt.name AS ProductType, COUNT(cu) AS UnitCount
ORDER BY UnitCount DESC
// Find all flavors of Coffee-mate products
MATCH (b:Brand {name: "Coffee-mate"})-[:PRODUCES]->(pt:ProductType)-[:HAS_FLAVOR]->(f:Flavor)
RETURN pt.name AS ProductType, f.name AS Flavor
// Find all products with flavors inspired by European regions
MATCH (pt:ProductType)-[:HAS_FLAVOR]->(f:Flavor)-[:INSPIRED_BY]->(r:Region {continent: "Europe"})
RETURN pt.name AS ProductType, f.name AS Flavor, r.name AS Region
// Count how many creamer units have flavors inspired by each region
MATCH (cu:CreamerUnit)-[:IS_TYPE_OF]->(pt:ProductType)-[:HAS_FLAVOR]->(f:Flavor)-[:INSPIRED_BY]->(r:Region)
RETURN r.name AS Region, COUNT(cu) AS CreamerCount
ORDER BY CreamerCount DESC
// Find the most common flavor in the collection
MATCH (cu:CreamerUnit)-[:IS_TYPE_OF]->(pt:ProductType)-[:HAS_FLAVOR]->(f:Flavor)
RETURN f.name AS Flavor, COUNT(cu) AS Count
ORDER BY Count DESC
LIMIT 1
// Find all creamer units adjacent to a specific unit
MATCH (cu:CreamerUnit {id: "FV-001"})-[:ADJACENT_TO]->(adjacent:CreamerUnit)
RETURN cu.id AS Unit, adjacent.id AS AdjacentUnit
// Count how many adjacent units each creamer has
MATCH (cu:CreamerUnit)-[:ADJACENT_TO]->(adjacent:CreamerUnit)
RETURN cu.id AS CreamerUnit, COUNT(adjacent) AS AdjacentCount
ORDER BY AdjacentCount DESC
// Find clusters of creamers (units that form groups based on adjacency)
MATCH path = (start:CreamerUnit)-[:ADJACENT_TO*1..14]-(connected:CreamerUnit)
WHERE id(start) < id(connected)
RETURN start.id AS StartUnit, collect(connected.id) AS ConnectedUnits
// Find units with the most adjacent neighbors
MATCH (cu:CreamerUnit)-[:ADJACENT_TO]->(adjacent:CreamerUnit)
RETURN cu.id AS UnitID,
[(cu)-[:IS_TYPE_OF]->(pt:ProductType)-[:HAS_FLAVOR]->(f:Flavor) | f.name][0] AS Flavor,
COUNT(adjacent) AS ConnectionCount
ORDER BY ConnectionCount DESC
LIMIT 5
// Identify the most central creamer unit (highest degree centrality)
MATCH (cu:CreamerUnit)
OPTIONAL MATCH (cu)-[:ADJACENT_TO]->(neighbor:CreamerUnit)
WITH cu, COUNT(neighbor) AS degree
RETURN cu.id AS UnitID,
[(cu)-[:IS_TYPE_OF]->(pt:ProductType)-[:HAS_FLAVOR]->(f:Flavor) | f.name][0] AS Flavor,
degree AS Centrality
ORDER BY Centrality DESC
LIMIT 1
// Find which flavor has the most connections to other flavors
MATCH (cu1:CreamerUnit)-[:IS_TYPE_OF]->(pt1:ProductType)-[:HAS_FLAVOR]->(f1:Flavor),
(cu1)-[:ADJACENT_TO]->(cu2:CreamerUnit)-[:IS_TYPE_OF]->(pt2:ProductType)-[:HAS_FLAVOR]->(f2:Flavor)
WHERE f1 <> f2
RETURN f1.name AS Flavor, COUNT(DISTINCT f2) AS ConnectedToOtherFlavors
ORDER BY ConnectedToOtherFlavors DESC