Exercise: First Contact with Neo4j

Belongs to: Graph_Databases · Duration: ~35 min · Work in pairs

You get a prepared social shop: 1 000 people who are friends with each other and buy products. You don’t create anything today — you explore the graph and learn to read and adapt simple Cypher queries.


0. Start and load the data (5 min)

In the nosql-lab folder:

docker compose --profile graph up -d

Wait ~30 seconds (Neo4j needs a moment), then load the dataset:

docker exec neo4j cypher-shell -u neo4j -p insy-neo4j -f /import/graph_lab.cypher

Error “Connection refused”? Neo4j is not ready yet — wait 20 seconds and try again.

Open http://localhost:7474 and log in with neo4j / insy-neo4j. You type queries into the editor at the top and run them with Ctrl+Enter (Mac: Cmd+Enter). Results can be shown as Graph, Table or Text (buttons on the left of the result).


1. What is in the database? (5 min)

CALL db.schema.visualization()

Draw the schema in your notes: which labels and which relationship types exist?

MATCH (n) RETURN labels(n) AS label, count(*) AS amount
MATCH ()-[r]->() RETURN type(r) AS type, count(*) AS amount

How many people, products, friendships and purchases are there?


2. Meet Anna (5 min)

MATCH (a:Person {name: "Anna Berger"})
RETURN a

In the graph view, double-click Anna’s node to expand her neighbours. Click a node or a relationship and look at its properties on the right.

Her friends as a table:

MATCH (a:Person {name: "Anna Berger"})-[:FRIENDS_WITH]-(f:Person)
RETURN f.name, f.city
ORDER BY f.name

How many friends does she have? Now add an arrow head: -[:FRIENDS_WITH]-> . Why do you get fewer results?


3. Adapt the query (8 min)

Change the query from task 2 so that it answers:

a) Which of Anna’s friends live in the same city as Anna? (Tip: WHERE f.city = a.city) b) What did Anna buy? (Tip: relationship BOUGHT, node label Product) c) What did Anna’s friends buy? Return the friend’s name and the product name. d) Show c) as a graph: replace the RETURN … line with

MATCH p = (a:Person {name: "Anna Berger"})-[:FRIENDS_WITH]-(f)-[:BOUGHT]->(pr:Product)
RETURN p

4. Friends of friends (5 min)

MATCH (a:Person {name: "Anna Berger"})-[:FRIENDS_WITH*2]-(fof:Person)
WHERE fof <> a AND NOT (a)-[:FRIENDS_WITH]-(fof)
RETURN count(DISTINCT fof)

a) Explain each line in your own words. What do *2, fof <> a and NOT (a)-[:FRIENDS_WITH]-(fof) do? b) How many people can Anna reach in 1 to 3 steps? Change only the pattern. c) How many in 1 to 4 steps? What do you notice?


5. A recommendation engine in 5 lines (5 min)

MATCH (a:Person {name: "Anna Berger"})-[:FRIENDS_WITH]-(f)-[:BOUGHT]->(p:Product)
WHERE NOT (a)-[:BOUGHT]->(p)
RETURN p.name AS product, count(DISTINCT f) AS friends_who_bought_it
ORDER BY friends_who_bought_it DESC, product
LIMIT 5

a) Read the query aloud as an English sentence. b) Which products would you recommend to Anna first? Why is product in the ORDER BY, too? c) Change the query so it only counts friends from Anna’s city.


6. Bonus (if you have time)

a) Which product was bought most often in total? b) Who has the most friends? (Tip: count(f) per person, ORDER BY … DESC LIMIT 3)


Leave the containers running if the next lesson follows directly — otherwise: docker compose --profile graph down.


Hand-in

  1. Your schema drawing and the numbers from task 1.
  2. Your queries and results for tasks 2–5.
  3. Answers to the questions in tasks 2, 4 and 5.
  4. Fill in the graph column of the classification grid.