Product Catalog
Domain
A product catalog is a collection of products, their categories, manufacturers with their pricing information. Products can be sold separately, included in one or more catalogs or used as substitute products
You can perform the following operations on a product: Create, Update, Delete (Not recommended, deactivate instead), Deactivate (We should deactivate products that are no longer available instead of deleting them, because they are included in past orders, quotes, or opportunities.), Search etc.
A store organizes its Products OF_TYPE Category into one or more Catalogs. A Catalog thus becomes a hierarchy of Categories. A Category can be PARENT of one or more child categories. This lending itself naturally to be modeled as a graph. Each Product and Category can have distinct set of attributes than others which also fit nicely into property graph model (otherwise would require a EAV - Entity Attribute Value relational model).
A Product can be SUBSTITUTE_FOR another Product. A product can have one or more MODELs, each model has PRICING associated with it. This is not a complete solution for all the product catalog use cases but provides a good starting point. I will slowly keep modelling more use cases.

All categories by Depth
MATCH p=(cats:Category)-[:PARENT|PARENT*]->(cat:Catalog)
WHERE cat.name='Summer Outdoor Bicycle Catalog'
RETURN LENGTH(p) AS Depth, COLLECT(cats.name) AS Categories
ORDER BY Depth ASC
All categories of a given level
MATCH p=(cats:Category)-[:PARENT*]->(cat:Catalog)
WHERE cat.name='Summer Outdoor Bicycle Catalog' AND length(p)=1
RETURN cats.name AS CategoriesOfGivenLevel
ORDER BY CategoriesOfGivenLevel
All sub-categories of a given category
MATCH p=(cats:Category)-[:PARENT]->(parentCat:Category), (parentCat)-[:PARENT*]->(c:Catalog)
WHERE parentCat.name='Road Bikes' AND c.name='Summer Outdoor Bicycle Catalog'
RETURN collect(cats.name) AS SubCategories
All Parent and their child categories
MATCH p=(child:Category)-[:PARENT*]->(parent)
RETURN parent.name, collect(child.name)
All parent and their IMMEDIATE children
MATCH p=(child:Category)-[:PARENT]->(parent)
RETURN labels(parent), parent.name, collect(child.name)
All products of a given category
MATCH (p:Product)-[:OF_TYPE]->(c:Category)
WHERE c.name='Road Bikes'
RETURN p.name
Running low on inventory? Recommend another substitute.
MATCH (p:Product)-[:SUBSTITUTE_FOR]->(other:Product {name:"Single Speed Bike"})
RETURN p.name
Get various models of the selected product
MATCH (p:Product)-[:MODEL]->(m:Model)
WHERE p.name="2013 Fuji Declaration Single Speed City Bike"
RETURN p AS Modles
All Categories and their Products of a given catalog
MATCH (p:Product)-[:OF_TYPE]->(c:Category)-[:PARENT*]->(ctl:Catalog)
WHERE ctl.name='Summer Outdoor Bicycle Catalog'
RETURN c.name AS Category, collect(p.name) AS Products
Time to get the shipping and pricing info so as to calculate the total price to be charged
MATCH (p:Product)-[:MODEL]->(m:Model)-[:PRICING]->(price:Price)
WHERE p.name="2013 Fuji Declaration Single Speed City Bike" AND m.type="Large" AND price.validFrom <= timestamp() AND price.validUntil >= timestamp()
RETURN price.list AS ListPrice, price.retail AS RetailPrice, m.height AS Height, m.weight AS Weight
All the categories of a given product in the given catalog
MATCH (p:Product)-[:OF_TYPE]->(c:Category)-[:PARENT*]->(ctl:Catalog)
WHERE p.name='Kids Road Bike' AND ctl.name='Summer Outdoor Bicycle Catalog'
RETURN c.name
Manufacturers and their products
MATCH (m:Manufacturer)<-[:MANUFACTURED_BY]-(p:Product)
RETURN m.name AS Manufacturer, collect(p.name) AS Products
Is this page helpful?