neo4j-spark-skill

Use when reading from or writing to Neo4j with Apache Spark or Databricks using the Neo4j Connector for Apache Spark 6.0 (org.neo4j.connectors:spark) or 5.x (org.neo4j:neo4j-connector-apache-spark). Covers SparkSession setup, DataFrame reads via labels/Cypher/relationship scan, DataFrame writes with

By neo4j-contrib · 501 installs

npx skills add neo4j-contrib/neo4j-skills --skill neo4j-spark-skill

Source repository · Upstream listing

Neo4j Connector for Apache Spark When to Use Reading Neo4j nodes/relationships into Spark DataFrames Writing Spark DataFrames to Neo4j as nodes or relationships Databricks notebooks connecting to Neo4j Delta Lake → Neo4j ingestion pipelines Partitioned parallel reads from large Neo4j graphs When NOT to Use Python bolt driver / execute query → neo4j driver python skill Cypher query writing → neo4j cypher skill GDS graph algorithms → neo4j gds skill Spring Boot + Neo4j → neo4j spring data skill Version Matrix Connector Spark Scala Java Databricks Runtime Neo4j Maven coordinate 6.0.x 4.0, 4.1 2.13 17+ 17.3 LTS 5.x, 2025.x, 2026.x org.neo4j.connectors:spark:6.0.0 s 2.13 5.5.x / 5.4.x 3.4, 3.5 2.12, 2.13 8+ 14.3–16.4 LTS 4.4, 5.x, 2025.x, 2026.x org.neo4j:neo4j connector apache spark 2.13:5.5.0 for spark 3 Group ID changed in 6.0 — org.neo4j:neo4j connector apache spark <scala is now a relocation POM pointing at org.neo4j.connectors:spark . On Spark 3.x stay on 5.5.x. 6.0 breaking changes Change Migration Spark baseline 3.5 → 4.0/4.1; Scala 2.12 and Java 8–11 dropped Upgrade to 5.5.0 first, then Spark 4.x + Scala 2.13 + Java 17 Maven coordinate org.neo4j.connectors:spark:<version s 2.13 Replace old for spark 3 coordinate schema.optimization.type removed schema.optimization.node.keys , schema.optimization.relationship.keys , schema.optimization $stream.offset in partitioned reads removed Use partitions + query.count ; separated multi statement script removed script.1 , script.2 , … script.N — executed in numbered order relationship.save.strategy default native → keys Set .option("relationship.save.strategy", "native") explicitly to keep old behaviour query option rewritten for Data Source V2 predicate push down No action; verify plans on upgrade Setup Standalone Spark (PySpark) Standalone Spark (Scala) Databricks — Cluster Installation 1. Cluster → Libraries → Install New → Maven 2. Coordinate org.neo4j.connectors:spark:6.0.0 s 2.13 on DBR 17.3 LTS; org.neo4j:neo4j connector apache spark 2.13:5.5.0 for spark 3 on DBR 14.3–16.4 LTS 3. Cluster → Advanced Options → Spark tab — add config: 4. Use Single user access mode (Unity Catalog shared mode not supported) Databricks — Secrets (preferred over plaintext) Key Configuration Options Option Description Default neo4j.url Bolt/Neo4j URI — (required) neo4j.authentication.type none , basic , kerberos , bearer basic neo4j.authentication.basic.username Username driver default neo4j.authentication.basic.password Password driver default neo4j.authentication.bearer.token Bearer token — neo4j.database Target database driver default neo4j.access.mode read or write read neo4j.encryption.enabled TLS (ignored with +s / +ssc URI) false neo4j.db.transaction.timeout Transaction timeout (ms) driver default neo4j.db.transaction.metadata.<key Custom transaction metadata surfaced in query log [6.0] empty neo4j.authentication.type = supplier name Custom AuthenticationTokenSupplierFactory (e.g. keycloak via org.neo4j.connectors:commons authn keycloak ) for expiring OAuth/OIDC tokens — Cypher version and query tuning [6.0] Option Effect cypher.version Cypher language version — 5 (default) or 25 cypher.tuning.<param Emits CYPHER <param =<value preamble on every generated query Valid with labels , relationship , query on reads and writes; rejected with gds . Reading from Neo4j Three mutually exclusive read modes — use exactly one per .read() call. Label scan (nodes) Multi label filter (AND): .option("labels", ":Person:Employee") Result includes <id (internal Neo4j id) and <labels columns. Cypher query read Use explicit RETURN aliases — they become DataFrame column names. No SKIP / LIMIT in query (connector handles pagination). Relationship scan Result columns: <rel.id , <rel.type , <source. , <target. , plus relationship properties. Read partition tuning Full read options reference: [references/read patterns.md](references/read patterns.md) Writing to Neo4j SaveMode SaveMode Cypher Requires Append CREATE nothing extra Overwrite MERGE node.keys (nodes) or .node.keys (rels) ErrorIfExists CREATE + error if exists — Always create uniqueness constraints on node.keys properties before writing in Overwrite mode. Write nodes — Append (CREATE) Write nodes — Overwrite (MERGE) node.keys with rename: .option("node.keys", "df col:node property,id:personId") Write nodes — Scala Write relationships Use coalesce(1) before relationship writes to avoid deadlocks. relationship.source.save.mode / relationship.target.save.mode : Match — find existing nodes (fail if missing) Append — always CREATE new nodes Overwrite — MERGE nodes Pre write scripts [6.0] script.N runs Cypher once before write operations, in numbered order. Required for index/constraint setup when using query mode ( schema.optimization. rejected there). script (single statement) and script.N are mutually exclusive. Semicolon separated statements inside one script fail on 6.0. Full write options reference: [references/write patterns.md](references/write patterns.md) Databricks — Delta Lake → Neo4j Pipeline Pipeline pattern for relationships — load both node sets first, then write edges: Write Performance Tuning Scenario Recommendation Node writes (no lock contention) repartition(N) where N ≤ Neo4j CPU cores Relationship writes (lock risk) coalesce(1) — single partition Large datasets batch.size 10000–20000 (adjust to heap) MERGE heavy loads Add uniqueness constraint on node.keys properties first Common Errors Error Cause Fix ClassNotFoundException: org.neo4j.spark.DataSource JAR not on classpath Add spark.jars.packages or attach library Deadlock on relationship write Multiple partitions locking nodes coalesce(1) before write Duplicate nodes on Overwrite No uniqueness constraint on keys CREATE CONSTRAINT ON (n:Label) ASSERT n.prop IS UNIQUE OOM on Neo4j side batch.size too large Reduce to 5000–10000; check heap Schema all string columns No APOC, schema not sampled Set schema.flatten.limit higher; or use query mode with explicit types Access mode is read error on write Session opened in read mode Remove neo4j.access.mode or set to write Databricks Shared cluster fails Unity Catalog shared mode unsupported Switch to Single User access mode NoSuchMethodError / IncompatibleClassChangeError on Spark 4 5.x connector on a Spark 4 runtime Use org.neo4j.connectors:spark:6.0.0 s 2.13 Relationship write ignores rel. / source. columns after upgrade 6.0 default strategy is keys , not native .option("relationship.save.strategy", "native") script option rejected with multiple statements 6.0 removed ; separated scripts Split into script.1 , script.2 , … Checklist [ ] Connector coordinate matches Spark line — org.neo4j.connectors:spark: s 2.13 for Spark 4.x, org.neo4j:neo4j connector apache spark <scala : for spark 3 for Spark 3.x [ ] Scala version in artifact matches cluster runtime (2.13 only on 6.x) [ ] Credentials in Databricks secrets or env vars — not hardcoded [ ] node.keys set when using Overwrite mode [ ] Uniqueness constraint created on node.keys properties before MERGE writes [ ] coalesce(1) applied before relationship writes [ ] batch.size sized to Neo4j heap (start 5000, tune up) [ ] Delta Lake → Neo4j: nodes written before relationships [ ] query mode: no SKIP / LIMIT in Cypher (connector paginates internally) [ ] Databricks: Single User access mode (not Shared)