+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Part 487 of 541

๐Ÿ“˜ Neo4j: Graph Database

Master neo4j: graph database in Python with practical examples, best practices, and real-world applications ๐Ÿš€

๐Ÿš€Intermediate
25 min read

Prerequisites

  • Basic understanding of programming concepts ๐Ÿ“
  • Python installation (3.8+) ๐Ÿ
  • VS Code or preferred IDE ๐Ÿ’ป

What you'll learn

  • Understand the concept fundamentals ๐ŸŽฏ
  • Apply the concept in real projects ๐Ÿ—๏ธ
  • Debug common issues ๐Ÿ›
  • Write clean, Pythonic code โœจ

๐ŸŽฏ Introduction

Welcome to the fascinating world of Neo4j and graph databases! ๐ŸŽ‰ Ever wondered how social networks like Facebook or LinkedIn manage to show you โ€œfriends of friendsโ€ or โ€œpeople you may knowโ€ so quickly? The secret is graph databases!

In this tutorial, weโ€™ll explore Neo4j, the most popular graph database that makes working with connected data feel like magic. Whether youโ€™re building a social network ๐Ÿ‘ฅ, recommendation engine ๐ŸŽฏ, or knowledge graph ๐Ÿง , Neo4j will transform how you think about data relationships.

By the end of this tutorial, youโ€™ll be creating and querying graph databases like a pro! Letโ€™s embark on this exciting journey! ๐Ÿš€

๐Ÿ“š Understanding Neo4j and Graph Databases

๐Ÿค” What is a Graph Database?

A graph database is like a mind map on steroids! ๐Ÿง  Think of it as a digital version of those connection boards you see in detective movies ๐Ÿ•ต๏ธ - with strings connecting photos, documents, and clues.

In technical terms, a graph database stores data as:

  • Nodes ๐Ÿ”ต: The entities (like people, products, or places)
  • Relationships โžก๏ธ: The connections between nodes
  • Properties ๐Ÿท๏ธ: Attributes of both nodes and relationships

This means you can:

  • โœจ Model real-world relationships naturally
  • ๐Ÿš€ Query connected data lightning fast
  • ๐Ÿ›ก๏ธ Maintain data integrity through relationships

๐Ÿ’ก Why Use Neo4j?

Hereโ€™s why developers love Neo4j:

  1. Intuitive Data Modeling ๐ŸŽจ: Your data model looks like a whiteboard sketch
  2. Cypher Query Language ๐Ÿ’ป: SQL-like syntax designed for graphs
  3. Blazing Fast Traversals โšก: Find connections in milliseconds, not minutes
  4. ACID Compliance ๐Ÿ”’: Enterprise-grade reliability

Real-world example: Imagine building a movie recommendation system ๐ŸŽฌ. With Neo4j, finding โ€œmovies liked by people who also liked The Matrixโ€ is a simple query, not a complex join nightmare!

๐Ÿ”ง Basic Syntax and Usage

๐Ÿ“ Installing and Connecting to Neo4j

Letโ€™s start with getting Neo4j up and running:

# ๐ŸŽฏ First, install the Neo4j Python driver
# pip install neo4j

from neo4j import GraphDatabase
import os

# ๐Ÿ” Connection details (use environment variables in production!)
class Neo4jConnection:
    def __init__(self, uri, user, password):
        self.driver = GraphDatabase.driver(uri, auth=(user, password))
    
    def close(self):
        self.driver.close()
    
    def test_connection(self):
        with self.driver.session() as session:
            result = session.run("RETURN 'Hello, Neo4j! ๐ŸŽ‰' AS message")
            return result.single()["message"]

# ๐Ÿš€ Connect to Neo4j
neo4j_conn = Neo4jConnection(
    uri="bolt://localhost:7687",  # ๐Ÿ“ Default Neo4j port
    user="neo4j",
    password="your-password"       # ๐Ÿ”‘ Change this!
)

# ๐Ÿ‘‹ Test the connection
print(neo4j_conn.test_connection())

๐ŸŽฏ Creating Your First Graph

Hereโ€™s how to create nodes and relationships:

# ๐ŸŽจ Creating nodes and relationships
def create_social_network(tx):
    # ๐Ÿ‘ฅ Create people nodes
    tx.run("""
        CREATE (alice:Person {name: 'Alice', age: 30, hobby: 'Photography ๐Ÿ“ธ'})
        CREATE (bob:Person {name: 'Bob', age: 28, hobby: 'Gaming ๐ŸŽฎ'})
        CREATE (charlie:Person {name: 'Charlie', age: 32, hobby: 'Cooking ๐Ÿณ'})
        CREATE (diana:Person {name: 'Diana', age: 29, hobby: 'Reading ๐Ÿ“š'})
    """)
    
    # ๐Ÿค Create friendships
    tx.run("""
        MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'})
        CREATE (a)-[:FRIENDS_WITH {since: 2020}]->(b)
    """)
    
    tx.run("""
        MATCH (a:Person {name: 'Alice'}), (c:Person {name: 'Charlie'})
        CREATE (a)-[:FRIENDS_WITH {since: 2019}]->(c)
    """)
    
    tx.run("""
        MATCH (b:Person {name: 'Bob'}), (d:Person {name: 'Diana'})
        CREATE (b)-[:FRIENDS_WITH {since: 2021}]->(d)
    """)

# ๐Ÿ—๏ธ Execute the creation
with neo4j_conn.driver.session() as session:
    session.execute_write(create_social_network)
    print("Social network created! ๐ŸŽ‰")

๐Ÿ’ก Practical Examples

๐Ÿ›’ Example 1: E-commerce Recommendation Engine

Letโ€™s build a product recommendation system:

# ๐Ÿ›๏ธ E-commerce graph database
class EcommerceGraph:
    def __init__(self, driver):
        self.driver = driver
    
    def create_shopping_data(self):
        with self.driver.session() as session:
            # ๐Ÿ›’ Create products
            session.run("""
                CREATE (laptop:Product {name: 'Gaming Laptop', price: 1299, emoji: '๐Ÿ’ป'})
                CREATE (mouse:Product {name: 'Gaming Mouse', price: 79, emoji: '๐Ÿ–ฑ๏ธ'})
                CREATE (keyboard:Product {name: 'Mechanical Keyboard', price: 149, emoji: 'โŒจ๏ธ'})
                CREATE (headset:Product {name: 'Gaming Headset', price: 99, emoji: '๐ŸŽง'})
                CREATE (monitor:Product {name: '4K Monitor', price: 599, emoji: '๐Ÿ–ฅ๏ธ'})
            """)
            
            # ๐Ÿ‘ค Create customers
            session.run("""
                CREATE (john:Customer {name: 'John', id: 'C001'})
                CREATE (sarah:Customer {name: 'Sarah', id: 'C002'})
                CREATE (mike:Customer {name: 'Mike', id: 'C003'})
            """)
            
            # ๐Ÿ›๏ธ Create purchases
            session.run("""
                MATCH (john:Customer {name: 'John'}), (laptop:Product {name: 'Gaming Laptop'})
                CREATE (john)-[:PURCHASED {date: '2024-01-15', rating: 5}]->(laptop)
            """)
            
            session.run("""
                MATCH (john:Customer {name: 'John'}), (mouse:Product {name: 'Gaming Mouse'})
                CREATE (john)-[:PURCHASED {date: '2024-01-16', rating: 4}]->(mouse)
            """)
            
            session.run("""
                MATCH (sarah:Customer {name: 'Sarah'}), (laptop:Product {name: 'Gaming Laptop'})
                CREATE (sarah)-[:PURCHASED {date: '2024-02-01', rating: 5}]->(laptop)
            """)
            
            session.run("""
                MATCH (sarah:Customer {name: 'Sarah'}), (keyboard:Product {name: 'Mechanical Keyboard'})
                CREATE (sarah)-[:PURCHASED {date: '2024-02-02', rating: 5}]->(keyboard)
            """)
    
    def get_recommendations(self, customer_name):
        with self.driver.session() as session:
            # ๐ŸŽฏ Find products bought by similar customers
            result = session.run("""
                MATCH (c:Customer {name: $customer_name})-[:PURCHASED]->(p:Product)
                <-[:PURCHASED]-(other:Customer)-[:PURCHASED]->(rec:Product)
                WHERE NOT (c)-[:PURCHASED]->(rec)
                RETURN rec.name AS product, rec.emoji AS emoji, 
                       COUNT(DISTINCT other) AS popularity
                ORDER BY popularity DESC
                LIMIT 3
            """, customer_name=customer_name)
            
            recommendations = []
            for record in result:
                recommendations.append({
                    'product': record['product'],
                    'emoji': record['emoji'],
                    'popularity': record['popularity']
                })
            
            return recommendations

# ๐ŸŽฎ Let's use it!
ecommerce = EcommerceGraph(neo4j_conn.driver)
ecommerce.create_shopping_data()

# ๐ŸŽฏ Get recommendations for John
recommendations = ecommerce.get_recommendations("John")
print("\n๐ŸŽ Recommendations for John:")
for rec in recommendations:
    print(f"  {rec['emoji']} {rec['product']} (bought by {rec['popularity']} similar customers)")

๐ŸŽฎ Example 2: Knowledge Graph Explorer

Letโ€™s create a knowledge graph for exploring topics:

# ๐Ÿง  Knowledge Graph System
class KnowledgeGraph:
    def __init__(self, driver):
        self.driver = driver
    
    def create_tech_knowledge_graph(self):
        with self.driver.session() as session:
            # ๐Ÿ“š Create technology topics
            session.run("""
                CREATE (python:Topic {name: 'Python', emoji: '๐Ÿ', level: 'Beginner'})
                CREATE (neo4j:Topic {name: 'Neo4j', emoji: '๐Ÿ”ท', level: 'Intermediate'})
                CREATE (ml:Topic {name: 'Machine Learning', emoji: '๐Ÿค–', level: 'Advanced'})
                CREATE (web:Topic {name: 'Web Development', emoji: '๐ŸŒ', level: 'Beginner'})
                CREATE (api:Topic {name: 'REST APIs', emoji: '๐Ÿ”Œ', level: 'Intermediate'})
                CREATE (docker:Topic {name: 'Docker', emoji: '๐Ÿณ', level: 'Intermediate'})
                CREATE (k8s:Topic {name: 'Kubernetes', emoji: 'โ˜ธ๏ธ', level: 'Advanced'})
            """)
            
            # ๐Ÿ”— Create relationships
            session.run("""
                MATCH (python:Topic {name: 'Python'}), (ml:Topic {name: 'Machine Learning'})
                CREATE (python)-[:PREREQUISITE_FOR]->(ml)
            """)
            
            session.run("""
                MATCH (python:Topic {name: 'Python'}), (web:Topic {name: 'Web Development'})
                CREATE (python)-[:USEFUL_FOR]->(web)
            """)
            
            session.run("""
                MATCH (web:Topic {name: 'Web Development'}), (api:Topic {name: 'REST APIs'})
                CREATE (web)-[:LEADS_TO]->(api)
            """)
            
            session.run("""
                MATCH (docker:Topic {name: 'Docker'}), (k8s:Topic {name: 'Kubernetes'})
                CREATE (docker)-[:PREREQUISITE_FOR]->(k8s)
            """)
    
    def find_learning_path(self, start_topic, end_topic):
        with self.driver.session() as session:
            # ๐Ÿ›ค๏ธ Find shortest learning path
            result = session.run("""
                MATCH path = shortestPath(
                    (start:Topic {name: $start})-[*]->(end:Topic {name: $end})
                )
                RETURN [node IN nodes(path) | node.name + ' ' + node.emoji] AS learning_path
            """, start=start_topic, end=end_topic)
            
            record = result.single()
            if record:
                return record['learning_path']
            return None
    
    def get_related_topics(self, topic_name):
        with self.driver.session() as session:
            # ๐Ÿ” Find all related topics
            result = session.run("""
                MATCH (t:Topic {name: $topic})-[r]-(related:Topic)
                RETURN type(r) AS relationship, 
                       related.name AS topic, 
                       related.emoji AS emoji,
                       related.level AS level
            """, topic=topic_name)
            
            related = []
            for record in result:
                related.append({
                    'relationship': record['relationship'],
                    'topic': record['topic'],
                    'emoji': record['emoji'],
                    'level': record['level']
                })
            
            return related

# ๐Ÿš€ Create and explore the knowledge graph
knowledge = KnowledgeGraph(neo4j_conn.driver)
knowledge.create_tech_knowledge_graph()

# ๐Ÿ›ค๏ธ Find learning path
path = knowledge.find_learning_path("Python", "Machine Learning")
if path:
    print("\n๐ŸŽ“ Learning path from Python to Machine Learning:")
    print(" โ†’ ".join(path))

# ๐Ÿ” Explore related topics
related = knowledge.get_related_topics("Python")
print("\n๐ŸŒŸ Topics related to Python:")
for rel in related:
    print(f"  {rel['emoji']} {rel['topic']} ({rel['level']}) - {rel['relationship']}")

๐Ÿš€ Advanced Concepts

๐Ÿง™โ€โ™‚๏ธ Advanced Cypher Queries

When youโ€™re ready to level up, try these advanced patterns:

# ๐ŸŽฏ Advanced query patterns
class AdvancedQueries:
    def __init__(self, driver):
        self.driver = driver
    
    def pattern_matching_with_collections(self):
        with self.driver.session() as session:
            # ๐ŸŽจ Complex pattern matching
            result = session.run("""
                // Find people who share multiple interests
                MATCH (p1:Person)-[:LIKES]->(interest:Interest)<-[:LIKES]-(p2:Person)
                WHERE p1 <> p2
                WITH p1, p2, COLLECT(interest.name) AS shared_interests
                WHERE SIZE(shared_interests) >= 2
                RETURN p1.name AS person1, p2.name AS person2, 
                       shared_interests, SIZE(shared_interests) AS count
                ORDER BY count DESC
            """)
            
            return list(result)
    
    def graph_algorithms(self):
        with self.driver.session() as session:
            # ๐Ÿš€ PageRank-style influence scoring
            session.run("""
                // Calculate influence scores
                MATCH (p:Person)
                SET p.influence = 0.0
            """)
            
            # ๐Ÿ”„ Iterative influence calculation
            for _ in range(5):  # 5 iterations
                session.run("""
                    MATCH (follower:Person)-[:FOLLOWS]->(influencer:Person)
                    WITH influencer, COUNT(follower) AS follower_count
                    SET influencer.influence = influencer.influence + follower_count * 0.1
                """)
    
    def temporal_queries(self):
        with self.driver.session() as session:
            # โฐ Time-based analysis
            result = session.run("""
                // Find trending topics in the last 7 days
                MATCH (u:User)-[p:POSTED]->(post:Post)-[:ABOUT]->(topic:Topic)
                WHERE p.timestamp > datetime() - duration('P7D')
                RETURN topic.name AS topic, topic.emoji AS emoji,
                       COUNT(DISTINCT post) AS post_count,
                       COUNT(DISTINCT u) AS user_count
                ORDER BY post_count DESC
                LIMIT 5
            """)
            
            return list(result)

๐Ÿ—๏ธ Graph Data Modeling Best Practices

For enterprise-grade graph applications:

# ๐Ÿ—๏ธ Advanced data modeling
class GraphDataModeling:
    def __init__(self, driver):
        self.driver = driver
    
    def create_versioned_nodes(self):
        with self.driver.session() as session:
            # ๐Ÿ“… Versioned data pattern
            session.run("""
                // Create versioned product catalog
                CREATE (p:Product {id: 'PROD001'})
                CREATE (v1:ProductVersion {
                    version: 1,
                    name: 'Laptop Pro',
                    price: 999,
                    valid_from: datetime('2024-01-01'),
                    valid_to: datetime('2024-06-30')
                })
                CREATE (v2:ProductVersion {
                    version: 2,
                    name: 'Laptop Pro',
                    price: 1099,
                    valid_from: datetime('2024-07-01'),
                    valid_to: datetime('9999-12-31')
                })
                CREATE (p)-[:HAS_VERSION]->(v1)
                CREATE (p)-[:HAS_VERSION]->(v2)
                CREATE (v1)-[:NEXT_VERSION]->(v2)
            """)
    
    def create_meta_graph(self):
        with self.driver.session() as session:
            # ๐ŸŽฏ Meta-graph pattern for dynamic schemas
            session.run("""
                // Define entity types and their relationships
                CREATE (person:EntityType {name: 'Person', emoji: '๐Ÿ‘ค'})
                CREATE (company:EntityType {name: 'Company', emoji: '๐Ÿข'})
                CREATE (project:EntityType {name: 'Project', emoji: '๐Ÿ“'})
                
                CREATE (works_for:RelationshipType {name: 'WORKS_FOR'})
                CREATE (manages:RelationshipType {name: 'MANAGES'})
                CREATE (assigned_to:RelationshipType {name: 'ASSIGNED_TO'})
                
                // Define allowed relationships
                CREATE (person)-[:CAN_HAVE]->(works_for)-[:WITH]->(company)
                CREATE (person)-[:CAN_HAVE]->(manages)-[:WITH]->(project)
                CREATE (person)-[:CAN_HAVE]->(assigned_to)-[:WITH]->(project)
            """)

โš ๏ธ Common Pitfalls and Solutions

๐Ÿ˜ฑ Pitfall 1: The Cartesian Product Trap

# โŒ Wrong way - creates cartesian product!
def bad_query():
    with neo4j_conn.driver.session() as session:
        result = session.run("""
            MATCH (a:Person), (b:Person)
            WHERE a.age > 25 AND b.age > 25
            RETURN a, b
        """)
        # ๐Ÿ’ฅ This will return nยฒ results!

# โœ… Correct way - use pattern matching!
def good_query():
    with neo4j_conn.driver.session() as session:
        result = session.run("""
            MATCH (a:Person)-[:FRIENDS_WITH]-(b:Person)
            WHERE a.age > 25 AND b.age > 25
            RETURN a, b
        """)
        # โœ… Only returns connected people!

๐Ÿคฏ Pitfall 2: Missing Indexes

# โŒ Slow queries without indexes
def slow_lookups():
    with neo4j_conn.driver.session() as session:
        # ๐ŸŒ This will be slow on large datasets
        result = session.run("""
            MATCH (p:Person {email: '[email protected]'})
            RETURN p
        """)

# โœ… Create indexes for better performance!
def create_indexes():
    with neo4j_conn.driver.session() as session:
        # ๐Ÿš€ Create index for fast lookups
        session.run("CREATE INDEX person_email IF NOT EXISTS FOR (p:Person) ON (p.email)")
        session.run("CREATE INDEX product_name IF NOT EXISTS FOR (p:Product) ON (p.name)")
        print("Indexes created! ๐ŸŽฏ")

๐Ÿ› ๏ธ Best Practices

  1. ๐ŸŽฏ Model for Queries: Design your graph based on how youโ€™ll query it
  2. ๐Ÿ“ Use Meaningful Relationships: FRIENDS_WITH not just RELATED_TO
  3. ๐Ÿ›ก๏ธ Add Constraints: Ensure data integrity with uniqueness constraints
  4. ๐ŸŽจ Keep It Simple: Start simple, evolve as needed
  5. โœจ Use Parameters: Always parameterize queries to prevent injection
# ๐Ÿ† Best practices in action
class Neo4jBestPractices:
    def __init__(self, driver):
        self.driver = driver
    
    def setup_constraints(self):
        with self.driver.session() as session:
            # ๐Ÿ”’ Ensure data integrity
            session.run("CREATE CONSTRAINT person_id IF NOT EXISTS FOR (p:Person) REQUIRE p.id IS UNIQUE")
            session.run("CREATE CONSTRAINT product_sku IF NOT EXISTS FOR (p:Product) REQUIRE p.sku IS UNIQUE")
    
    def parameterized_query(self, name, min_age):
        with self.driver.session() as session:
            # โœ… Always use parameters!
            result = session.run("""
                MATCH (p:Person)
                WHERE p.name = $name AND p.age >= $min_age
                RETURN p
            """, name=name, min_age=min_age)
            return list(result)

๐Ÿงช Hands-On Exercise

๐ŸŽฏ Challenge: Build a Movie Recommendation System

Create a movie recommendation system with the following features:

๐Ÿ“‹ Requirements:

  • โœ… Movies with title, genre, year, and rating
  • ๐ŸŽฌ Directors and actors connected to movies
  • ๐Ÿ‘ค Users who rate and watch movies
  • ๐ŸŽฏ Recommendation algorithm based on similar users
  • ๐ŸŽจ Each movie needs an emoji based on genre!

๐Ÿš€ Bonus Points:

  • Add genre-based filtering
  • Implement collaborative filtering
  • Create a โ€œSix Degrees of Kevin Baconโ€ finder

๐Ÿ’ก Solution

๐Ÿ” Click to see solution
# ๐ŸŽฌ Movie Recommendation System
class MovieRecommendationSystem:
    def __init__(self, driver):
        self.driver = driver
        self.genre_emojis = {
            'Action': '๐Ÿ’ฅ', 'Comedy': '๐Ÿ˜‚', 'Drama': '๐ŸŽญ',
            'Horror': '๐Ÿ‘ป', 'Sci-Fi': '๐Ÿš€', 'Romance': '๐Ÿ’•'
        }
    
    def create_movie_database(self):
        with self.driver.session() as session:
            # ๐ŸŽฌ Create movies
            session.run("""
                CREATE (matrix:Movie {
                    title: 'The Matrix',
                    year: 1999,
                    genre: 'Sci-Fi',
                    emoji: '๐Ÿš€',
                    rating: 8.7
                })
                CREATE (inception:Movie {
                    title: 'Inception',
                    year: 2010,
                    genre: 'Sci-Fi',
                    emoji: '๐Ÿš€',
                    rating: 8.8
                })
                CREATE (godfather:Movie {
                    title: 'The Godfather',
                    year: 1972,
                    genre: 'Drama',
                    emoji: '๐ŸŽญ',
                    rating: 9.2
                })
            """)
            
            # ๐ŸŽฌ Create people
            session.run("""
                CREATE (keanu:Actor {name: 'Keanu Reeves', emoji: '๐ŸŽญ'})
                CREATE (leo:Actor {name: 'Leonardo DiCaprio', emoji: '๐ŸŽญ'})
                CREATE (nolan:Director {name: 'Christopher Nolan', emoji: '๐ŸŽฌ'})
                CREATE (wachowski:Director {name: 'The Wachowskis', emoji: '๐ŸŽฌ'})
            """)
            
            # ๐Ÿ‘ฅ Create users
            session.run("""
                CREATE (alice:User {name: 'Alice', id: 'U001'})
                CREATE (bob:User {name: 'Bob', id: 'U002'})
                CREATE (charlie:User {name: 'Charlie', id: 'U003'})
            """)
            
            # ๐Ÿ”— Connect movies to people
            session.run("""
                MATCH (matrix:Movie {title: 'The Matrix'}), 
                      (keanu:Actor {name: 'Keanu Reeves'}),
                      (wachowski:Director {name: 'The Wachowskis'})
                CREATE (keanu)-[:ACTED_IN {role: 'Neo'}]->(matrix)
                CREATE (wachowski)-[:DIRECTED]->(matrix)
            """)
            
            # โญ Create ratings
            session.run("""
                MATCH (alice:User {name: 'Alice'}), (matrix:Movie {title: 'The Matrix'})
                CREATE (alice)-[:RATED {score: 5, timestamp: datetime()}]->(matrix)
            """)
    
    def get_recommendations(self, user_id):
        with self.driver.session() as session:
            # ๐ŸŽฏ Collaborative filtering
            result = session.run("""
                // Find similar users based on shared movie ratings
                MATCH (u:User {id: $user_id})-[r1:RATED]->(m:Movie)<-[r2:RATED]-(other:User)
                WHERE abs(r1.score - r2.score) <= 1
                WITH other, COUNT(DISTINCT m) AS shared_movies
                WHERE shared_movies >= 2
                
                // Find movies they liked that our user hasn't seen
                MATCH (other)-[r:RATED]->(rec:Movie)
                WHERE r.score >= 4 AND NOT EXISTS {
                    MATCH (u)-[:RATED]->(rec)
                }
                
                RETURN rec.title AS title, rec.emoji AS emoji,
                       rec.genre AS genre, rec.rating AS rating,
                       AVG(r.score) AS avg_user_score,
                       COUNT(DISTINCT other) AS recommended_by
                ORDER BY recommended_by DESC, avg_user_score DESC
                LIMIT 5
            """, user_id=user_id)
            
            return list(result)
    
    def find_bacon_number(self, actor_name):
        with self.driver.session() as session:
            # ๐Ÿฅ“ Six Degrees of Kevin Bacon!
            result = session.run("""
                MATCH path = shortestPath(
                    (actor:Actor {name: $actor_name})-[:ACTED_IN*]-(bacon:Actor {name: 'Kevin Bacon'})
                )
                RETURN length(path)/2 AS bacon_number,
                       [node IN nodes(path) WHERE node:Movie | node.title] AS movies
            """, actor_name=actor_name)
            
            record = result.single()
            if record:
                return {
                    'bacon_number': record['bacon_number'],
                    'movies': record['movies']
                }
            return None

# ๐ŸŽฎ Test the system!
movie_system = MovieRecommendationSystem(neo4j_conn.driver)
movie_system.create_movie_database()

# ๐ŸŽฏ Get recommendations
recommendations = movie_system.get_recommendations("U001")
print("\n๐ŸŽฌ Movie Recommendations:")
for movie in recommendations:
    print(f"  {movie['emoji']} {movie['title']} ({movie['genre']}) - โญ {movie['rating']}")

๐ŸŽ“ Key Takeaways

Youโ€™ve learned so much! Hereโ€™s what you can now do:

  • โœ… Create graph databases with nodes and relationships ๐Ÿ’ช
  • โœ… Write Cypher queries to find patterns and connections ๐Ÿ›ก๏ธ
  • โœ… Build recommendation systems using graph algorithms ๐ŸŽฏ
  • โœ… Model complex relationships naturally and efficiently ๐Ÿ›
  • โœ… Optimize graph queries for lightning-fast performance! ๐Ÿš€

Remember: Neo4j transforms connected data from a challenge into an opportunity! Itโ€™s your secret weapon for building intelligent, relationship-aware applications. ๐Ÿค

๐Ÿค Next Steps

Congratulations! ๐ŸŽ‰ Youโ€™ve mastered Neo4j and graph databases!

Hereโ€™s what to do next:

  1. ๐Ÿ’ป Practice with the movie recommendation exercise above
  2. ๐Ÿ—๏ธ Build a social network or knowledge graph using Neo4j
  3. ๐Ÿ“š Explore Neo4jโ€™s graph algorithms library for advanced analytics
  4. ๐ŸŒŸ Move on to our next tutorial on MongoDB for document databases!

Remember: Every data relationship tells a story. With Neo4j, youโ€™re now equipped to discover and leverage those stories in your applications. Keep exploring, keep connecting, and most importantly, have fun with graphs! ๐Ÿš€


Happy graphing! ๐ŸŽ‰๐Ÿš€โœจ