Knowledge Check

Node Identification

Which of the following should be a node in a graph model?

  • ❏ A. Product price (unitPrice)

  • ❏ B. Order date (orderDate)

  • ✓ C. Customer

  • ❏ D. Surname

Hint

Nodes represent entities - distinct things with identity, properties, and connections.

Solution

The correct answer is Customer.

Product price (unitPrice), Order date (orderDate) are properties that describe other entities, not entities themselves. Surname is a property that describes a customer, not an entity itself.

Relationships vs Properties

When should you use a relationship instead of a property?

  • ✓ A. To connect a customer to their orders

  • ❏ B. To store a product’s unit price

  • ❏ C. To store a customer’s email address

  • ❏ D. To store an order’s shipping address

Hint

Relationships connect entities. Properties describe entities.

Solution

A is correct: Relationships connect entities. A customer placing orders is a connection between two entities.

C, B, D are attributes that describe single entities, not connections.

Recall Module 3: Relationships have type, direction, and represent associations between entities.

Many-to-Many Transformation

In a graph, how do you typically handle a many-to-many join table?

  • ❏ A. Keep it as a separate node type

  • ❏ B. Store it as properties on both nodes

  • ✓ C. Transform it into direct relationships

  • ❏ D. Ignore it, graphs don’t support many-to-many

Hint

Think about how order_details became CONTAINS relationships in Module 4.

Solution

C is correct: join tables become direct relationships. The 2,155 order_details rows became CONTAINS relationships.

Properties from the join table (quantity, unitPrice) move to the relationship.

Recall Module 4: Entire join table → relationships with properties. This eliminates an extra JOIN.

Cypher Pattern Matching

What does this Cypher pattern match?

cypher
MATCH (c:Customer)-[:PLACED]->(o:Order)
  • ❏ A. All customers

  • ❏ B. A serialized view of customers and orders

  • ✓ C. Customers and their orders

  • ❏ D. Only customers named 'PLACED'

Hint

Count the hops: Customer → Order

Solution

This pattern matches the PLACED relationship from Customer through Order.

Negative Patterns

What does this negative pattern do?

cypher
WHERE NOT (me)-[:PLACED]->(:Order)-[:CONTAINS]->(rec)
  • ❏ A. Finds products I have ordered

  • ✓ B. Filters out products I have already ordered

  • ❏ C. Finds customers who haven’t ordered

  • ❏ D. Deletes my orders

Hint

WHERE NOT excludes matches where the pattern exists.

Solution

B is correct: This negative pattern excludes products where a path exists from me to that product.

In recommendations, this ensures you don’t recommend products the customer already owns.

Collaborative Filtering

What is the core idea behind collaborative filtering?

  • ❏ A. Filter products by price

  • ❏ B. Sort products by popularity

  • ✓ C. Recommend products that similar customers bought

  • ❏ D. Remove out-of-stock products

Hint

Think about "people like you also bought…​"

Solution

C is correct: Collaborative filtering finds "people like you" and recommends what they bought.

Pattern: My products → Similar customers → Their products (minus mine)

Graph vs SQL Performance

Why are graph databases faster for deep relationship queries?

  • ❏ A. They skip data validation

  • ✓ B. They follow indexed pointers instead of scanning tables

  • ❏ C. They use more RAM

  • ❏ D. They don’t support transactions

Hint

Graph databases store adjacency directly; traversals follow indexed pointers in memory instead of scanning tables and materializing joins.

Solution

Graphs follow indexed pointers instead of scanning tables.

Graphs follow indexed pointers from node to node (pointer chasing in memory), instead of scanning tables and doing repeated index lookups and JOINs. Cost scales with the connections actually traversed, not with total data size.

The collect() Function

What does the collect() function do in Cypher?

  • ❏ A. Deletes nodes

  • ❏ B. Counts nodes

  • ✓ C. Gathers values into a list during aggregation

  • ❏ D. Creates new relationships

Hint

Think about gathering multiple values into one result.

Solution

C is correct: collect() aggregates values into a list, useful for filtering with WHERE NOT IN.

Example: collect(p.name) creates a list of product names.

Uniqueness Constraints

What does a uniqueness constraint do?

  • ❏ A. Speeds up all queries

  • ✓ B. Prevents duplicate values and automatically creates an index

  • ❏ C. Deletes duplicate nodes

  • ❏ D. Requires a property to exist

Hint

Think about product names or customer IDs being unique.

Solution

B is correct: Uniqueness constraints prevent duplicates (e.g., no two customers with same ID) and auto-create indexes.

Creating a unique constraint on a property also dramatically improves lookup performance for start nodes.

Congratulations!

You did it! You’ve built a complete product recommendation system from relational data using Neo4j.

Starting with flat CSV files, you:

  1. Designed a graph model - Identified which entities become nodes and how they connect

  2. Imported data visually - Used the Import tool without writing code

  3. Created relationships - Built PLACED, CONTAINS, and IN_CATEGORY connections

  4. Wrote a recommendation query - 10 lines of Cypher that would take 38 lines in SQL

Your Final Graph Model

Run this query to see the schema you built:

cypher
CALL db.schema.visualization()

You should see nodes for Customer, Order, Product, and Category connected by the relationships you created.

Key Concepts You Learned

  • Nodes are nouns - Entities with identity and properties (Customer, Product, Order)

  • Relationships are verbs - Connections with meaning and direction (PLACED, CONTAINS)

  • Graph traversal - Following relationships in memory (fast) vs. JOINs across tables (slow)

  • Collaborative filtering - "People like me bought these products"

  • Anchor node + traversal - One index lookup, then pointer chasing along relationships

The Recommendation Query

Here’s the query you built, ready to run:

cypher
MATCH (me:Customer {id: 'ALFKI'})-[:PLACED]->(:Order)-[:CONTAINS]->(myProduct:Product)
MATCH (myProduct)<-[:CONTAINS]-(:Order)<-[:PLACED]-(other:Customer)
WHERE other <> me
MATCH (other)-[:PLACED]->(:Order)-[:CONTAINS]->(rec:Product)
WHERE NOT (me)-[:PLACED]->(:Order)-[:CONTAINS]->(rec)
  AND rec.unitsInStock > 0
RETURN rec.name, rec.unitPrice,
       count(DISTINCT other) AS recommendedBy
ORDER BY recommendedBy DESC
LIMIT 10

Try changing 'ALFKI' to other customer IDs to see different recommendations.

Continue Learning

Thank you for completing this workshop!

Summary

You completed the workshop! Key accomplishments:

  • Built a complete product recommendation system

  • Learned graph modeling principles (nodes = nouns, relationships = verbs)

  • Imported data visually without writing code

  • Wrote a 10-line recommendation query that would take 38 lines in SQL

Chatbot

How can I help you today?

Data Model

Your data model will appear here.