Claude Code & Neo4j: Graphdatenbanken mit KI entwickeln

Relationale Datenbanken speichern Zeilen und Spalten. Neo4j speichert Beziehungen. Das klingt nach einem kleinen Unterschied — in der Praxis ist es ein fundamentaler Paradigmenwechsel: Wenn Verbindungen zwischen Datenpunkten genauso wichtig sind wie die Datenpunkte selbst, ist eine Graphdatenbank der natürlichste Weg, dieses Wissen abzubilden. Und Claude Code macht den Einstieg in Neo4j erheblich schneller.

Dieser Artikel zeigt, wie Neo4j funktioniert, wie Cypher-Queries aufgebaut sind — und wie du Claude Code konkret einsetzt, um Datenmodelle zu entwerfen, Queries zu generieren und Performance-Probleme zu lösen.

Claude Code Mastery — auch für Datenbanken und Agents

Neo4j ist nur ein Beispiel. Im Kurs lernst du Claude Code für den echten Entwickleralltag: Datenmodelle, Agents, MCP-Server, Hooks. Vollständig auf Deutsch, einmalig bezahlt.

Zum Kurs — Jetzt starten → Einmalzahlung · Kein Abo · 14 Tage Rückgaberecht

1. Was ist Neo4j? Das Graphmodell verstehen

Neo4j ist eine native Graphdatenbank: die gesamte Speicher- und Abfragelogik ist von Grund auf für Graphstrukturen gebaut, nicht nachträglich auf ein relationales System aufgesetzt. Das Datenmodell besteht aus vier Grundelementen:

Der entscheidende Vorteil gegenüber SQL: Beziehungen werden zur Schreibzeit gespeichert, nicht zur Lesezeit berechnet. Ein JOIN über drei Tabellen wird in Neo4j zu einem Traversierungsschritt über direkte Zeiger — der bei großen Graphen um Größenordnungen schneller ist als ein relationaler JOIN.

Wann Neo4j wählen: Empfehlungssysteme, Betrugserkennung, Wissensgraphen, soziale Netzwerke, Supply-Chain-Analysen — überall dort, wo die Frage lautet: "Welche Verbindung besteht zwischen A und B, und über wie viele Zwischenschritte?"

2. Cypher: Die Abfragesprache für Graphen

Cypher ist die deklarative Abfragesprache von Neo4j — SQL für Graphen, aber visuell orientiert. Die Grundidee: Muster werden so aufgeschrieben, wie sie aussehen.

Nodes und Relationships schreiben

// Node anlegen
CREATE (p:Person {name: "Anna Müller", age: 34})

// Relationship zwischen zwei Nodes anlegen
MATCH (a:Person {name: "Anna Müller"})
MATCH (b:Company {name: "Acme GmbH"})
CREATE (a)-[:WORKS_AT {since: 2021}]->(b)

// MERGE: anlegen, falls noch nicht vorhanden
MERGE (c:City {name: "Berlin"})
ON CREATE SET c.founded = 1237
ON MATCH SET c.lastSeen = date()

Die ASCII-Art-Notation (a)-[:REL]->(b) ist kein Zufall: sie zeigt genau, was im Graphen gespeichert wird. Nodes sind runde Klammern, Relationships eckige Klammern mit einem Pfeil für die Richtung.

Abfragen mit MATCH und WHERE

// Alle Personen die bei Acme arbeiten
MATCH (p:Person)-[:WORKS_AT]->(c:Company {name: "Acme GmbH"})
RETURN p.name, p.age
ORDER BY p.age DESC

// Mit Filterbedingung
MATCH (p:Person)-[:WORKS_AT]->(c:Company)
WHERE p.age > 30 AND c.city = "Berlin"
RETURN p.name, c.name

// Variable-length path: alle Verbindungen bis Tiefe 3
MATCH path = (a:Person {name: "Anna"})-[:KNOWS*1..3]->(b:Person)
RETURN b.name, length(path) AS abstand

Variable-length Paths — [:KNOWS*1..3] — sind einer der mächtigsten Cypher-Operators: sie traversieren den Graphen bis zu einer bestimmten Tiefe, ohne dass du explizite JOINs schreiben musst. In SQL wäre dasselbe eine rekursive CTE mit deutlich mehr Code.

Pfadmuster und Aggregation

// Kürzester Pfad zwischen zwei Knoten
MATCH (a:Person {name: "Anna"}), (b:Person {name: "Ben"})
MATCH path = shortestPath((a)-[:KNOWS*]-(b))
RETURN [node IN nodes(path) | node.name] AS verbindungskette

// Aggregation: wer kennt wie viele Personen?
MATCH (p:Person)-[:KNOWS]->(bekannt:Person)
RETURN p.name, count(bekannt) AS netzwerkgroesse
ORDER BY netzwerkgroesse DESC
LIMIT 10

3. Indizes, Constraints und Performance

Wie in jeder Datenbank sind Indizes entscheidend für Performance bei großen Datensätzen. In Neo4j werden Indizes auf Label-Property-Kombinationen gelegt:

// Index anlegen
CREATE INDEX person_name FOR (p:Person) ON (p.name)

// Eindeutigkeit erzwingen
CREATE CONSTRAINT person_email_unique
FOR (p:Person) REQUIRE p.email IS UNIQUE

// Query-Plan analysieren
EXPLAIN MATCH (p:Person {name: "Anna"}) RETURN p

// Mit tatsächlicher Ausführungsstatistik
PROFILE MATCH (p:Person)-[:WORKS_AT]->(c:Company)
WHERE c.city = "Berlin"
RETURN p.name

EXPLAIN zeigt den geplanten Ausführungsweg ohne die Query tatsächlich auszuführen. PROFILE führt die Query aus und zeigt für jeden Schritt, wie viele Datenbankzugriffe tatsächlich stattgefunden haben — der wichtigste Hinweis auf fehlende Indizes oder ineffiziente Traversierungsmuster.

Häufiger Performance-Fehler: Queries die ohne Label-Filter starten (MATCH (n) WHERE n.name = "Anna") scannen alle Nodes. Immer mit dem spezifischsten Label beginnen: MATCH (p:Person {name: "Anna"}). Claude Code erkennt dieses Muster zuverlässig, wenn du einen PROFILE-Output übergibst.

4. Python-Integration mit dem Neo4j-Driver

Der offizielle Python-Treiber unterstützt sowohl synchrone als auch asynchrone Verwendung und arbeitet mit dem Bolt-Protokoll direkt gegen Neo4j:

from neo4j import GraphDatabase

# Verbindung herstellen
driver = GraphDatabase.driver(
    "bolt://localhost:7687",
    auth=("neo4j", "passwort")
)

# Session und Transaktion
def create_person(tx, name, age):
    result = tx.run(
        "MERGE (p:Person {name: $name}) "
        "SET p.age = $age "
        "RETURN p.name",
        name=name, age=age
    )
    return result.single()["p.name"]

with driver.session(database="neo4j") as session:
    name = session.execute_write(create_person, "Anna Müller", 34)
    print(f"Erstellt: {name}")

driver.close()

Wichtig: Queries werden immer innerhalb einer Transaktion ausgeführt — entweder explizit über execute_write / execute_read oder implizit über eine Auto-Commit-Transaktion. Für lesende Operationen ist execute_read sinnvoll, weil Neo4j diese auf Read-Replicas routen kann.

# Lesende Abfrage mit Parametern
def get_connections(tx, person_name, max_depth):
    result = tx.run(
        "MATCH (p:Person {name: $name})-[:KNOWS*1..$depth]->(connected) "
        "RETURN connected.name AS name, "
        "       labels(connected) AS labels",
        name=person_name, depth=max_depth
    )
    return [{"name": r["name"], "labels": r["labels"]} for r in result]

with driver.session() as session:
    verbindungen = session.execute_read(
        get_connections, "Anna Müller", 3
    )
    for v in verbindungen:
        print(v["name"], v["labels"])

5. Claude Code Neo4j: So arbeitest du konkret

Claude Code und Neo4j ergänzen sich besonders gut, weil Graphmodelle konzeptuell anspruchsvoll sind: ein gutes Datenmodell zu entwerfen erfordert Überlegung, eine Cypher-Query zu optimieren erfordert Verständnis des Ausführungsplans. Genau hier hilft Claude Code am meisten.

Datenmodell entwerfen

Beschreibe deine Domäne in natürlicher Sprache — Claude Code schlägt das passende Graphmodell vor:

claude "Ich baue ein Empfehlungssystem für einen Online-Shop.
Nutzer kaufen Produkte, Produkte gehören zu Kategorien,
Nutzer können sich gegenseitig folgen. Entwirf das Neo4j-Datenmodell
mit Nodes, Labels, Relationships und wichtigen Properties.
Zeig auch die ersten MERGE-Statements zum Befüllen."

Claude Code gibt dir nicht nur das Modell, sondern erklärt auch die Entscheidungen: warum eine bestimmte Relationship in diese Richtung zeigt, welche Properties an der Relationship selbst sinnvoll sind (z.B. PURCHASED {at: datetime, quantity: 1}) und welche Indizes du von Anfang an brauchen wirst.

Cypher-Queries generieren

claude "Schreib eine Cypher-Query die mir alle Produkte empfiehlt,
die Nutzer gekauft haben, denen ich folge — sortiert nach
Kaufhäufigkeit, ohne Produkte die ich selbst schon gekauft habe."

Diese Art Query — kollaboratives Filtern über Graph-Traversierung — ist in SQL eine komplexe Subquery-Konstruktion. In Cypher ist sie kompakt, aber nicht trivial zu schreiben. Claude Code generiert sie korrekt inklusive der NOT EXISTS-Bedingung für bereits gekaufte Produkte.

Langsame Queries mit PROFILE optimieren

Das ist einer der wertvollsten Anwendungsfälle: PROFILE-Output direkt übergeben und nach dem Engpass fragen:

claude "Diese Query ist zu langsam. Hier ist der PROFILE-Output:
[PROFILE-Ausgabe einfügen]
Welche Schritte verursachen die meisten DB-Hits und wie optimiere ich?"

Claude Code liest den PROFILE-Baum, identifiziert die Schritte mit den höchsten db hits, erklärt warum — fehlender Index, ungünstiger Traversierungsstart, kartesisches Produkt — und schlägt den konkreten Fix vor: welchen Index anzulegen, wo ein Label-Filter fehlt, oder ob ein Query-Rewrite sinnvoller ist als ein Index.

Graph-Muster erklären lassen

"Erkläre mir was diese Cypher-Query macht und ob es einen einfacheren Weg gibt, dasselbe Ergebnis zu erzielen."

Für komplexe Queries aus Fremdsystemen oder Legacy-Code ist das besonders hilfreich: Claude Code liest die Query, erklärt Schritt für Schritt was sie traversiert, und schlägt oft eine vereinfachte Version vor — beispielsweise durch Verwendung von OPTIONAL MATCH statt mehrerer MATCH-Zweige, oder durch WITH-Klauseln um Zwischenergebnisse zu filtern bevor weitere Traversierungen stattfinden.


Weiterführende Artikel die auf diesem Thema aufbauen:


Claude Code Mastery — vom Datenmodell zum produktiven Agenten

Nicht nur Datenbanken: der Kurs zeigt, wie du Claude Code in echten Entwicklungsworkflows einsetzt — Agents, MCP-Server, Hooks, Multi-Agent-Systeme. Auf Deutsch, einmalig bezahlt.

Jetzt starten → Einmalzahlung · Kein Abo · 14 Tage Rückgaberecht

Kurs · Claude Code Mastery

Von der Graphdatenbank zum produktiven AI-Agenten

Datenbanken. Agents. MCP. Hooks. Multi-Agent-Workflows. Alles auf Deutsch, einmalig bezahlt — kein Abo, keine Plattformabhängigkeit.

Jetzt einsteigen → Kursübersicht ansehen →

Einmalzahlung · Kein Abo · 14 Tage Rückgaberecht