
Neo4j Gds Skill
- 391 installs
- 101 repo stars
- Updated August 3, 2026
- neo4j-contrib/neo4j-skills
neo4j-gds-skill is a Claude Code skill that runs Neo4j Graph Data Science projections and core algorithms from Python or Cypher with memory estimation and embedding write-back patterns for developers building graph analy
About
neo4j-gds-skill is an agent skill from neo4j-contrib/neo4j-skills for Neo4j Graph Data Science on Aura Pro, self-managed, local, or offline DBMS instances with the GDS plugin installed. The skill covers native and Cypher graph projection, execution modes—stream, stats, mutate, and write—and seven core algorithms: PageRank, Louvain, WCC, Betweenness Centrality, Node Similarity, FastRP, and KNN. It documents the FastRP-to-KNN recommendation pipeline, writing node embeddings for Neo4j vector indexes, and memory estimation before large projections via the graphdatascience Python client. Developers reach for neo4j-gds-skill when shipping community detection, centrality scoring, or structural similarity search without guessing GDS mode semantics or blowing heap on unestimated projections.
- Native and Cypher graph projection with stream/stats/mutate/write execution modes
- Core algorithms: PageRank, Louvain, WCC, Betweenness, Node Similarity, FastRP, KNN
- FastRP → KNN recommendation pipeline with embeddings written for vector index follow-up
- Memory estimation before large projections and catalog ops: project, list, drop, subgraph filter
- GDS Python client v2 with v1 fallback; documents OOM and licensing error mitigations
Neo4j Gds Skill by the numbers
- 391 all-time installs (skills.sh)
- +30 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #151 of 911 Databases skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/neo4j-contrib/neo4j-skills --skill neo4j-gds-skillAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 391 |
|---|---|
| repo stars | ★ 101 |
| Security audit | 3 / 3 scanners passed |
| Last updated | August 3, 2026 |
| Repository | neo4j-contrib/neo4j-skills ↗ |
How do you run Neo4j GDS algorithms from Python?
Run Neo4j Graph Data Science projections and core algorithms from Python or Cypher with memory estimation and embedding write-back patterns.
Who is it for?
Backend engineers adding graph analytics, community detection, or embedding pipelines on Neo4j with the GDS plugin installed.
Skip if: Teams running vanilla Cypher CRUD without GDS installed or needing OLTP-only graph queries without algorithm projections.
When should I use this skill?
A task involves GDS projection, PageRank, Louvain, FastRP, KNN pipelines, or memory estimation for Neo4j graph algorithms.
What you get
GDS graph projections, algorithm results in stream/mutate/write modes, and node embeddings written for vector indexes.
- GDS projections
- Algorithm result sets
- Node embeddings for vector indexes
By the numbers
- Covers 7 core GDS algorithms: PageRank, Louvain, WCC, Betweenness Centrality, Node Similarity, FastRP, and KNN
- Documents 4 GDS execution modes: stream, stats, mutate, and write
Files
When to Use
- Running GDS algorithms against embedded GDS plugin through Python client (
graphdatascience) - Running GDS algorithms through
CALL gds.*Cypher procedures - Aura Pro, self-managed Neo4j, local Neo4j, or offline DBMS with GDS plugin installed
- Projecting named in-memory graphs, running centrality/community/similarity/path/embedding algorithms
- Chaining algorithms via
mutatemode; building FastRP → KNN pipelines - Writing node embeddings for Neo4j vector indexes / structural similarity search
- Memory estimation before large graph operations
When NOT to Use
- Aura Graph Analytics Sessions / AGA / `GdsSessions` / `AuraGraphDataScience` →
neo4j-aura-graph-analytics-skill - AuraDB Cypher API with `{ memory: ... }` or `{ sessionId: ... }` →
neo4j-aura-graph-analytics-skill - Cypher query authoring →
neo4j-cypher-skill - Driver/connection setup →
neo4j-driver-python-skill - GraphRAG retrieval →
neo4j-graphrag-skill - Creating/querying vector indexes over written embeddings →
neo4j-vector-index-skill
| Context | Use |
|---|---|
| Aura Pro with GDS plugin | This skill |
| Self-managed/local/offline Neo4j with GDS plugin | This skill |
| AuraDB serverless analytics session | neo4j-aura-graph-analytics-skill |
| Self-managed Neo4j attached to AGA session | neo4j-aura-graph-analytics-skill |
| Non-Neo4j data source | neo4j-aura-graph-analytics-skill |
---
Pre-flight
Use only with embedded GDS plugin.
from graphdatascience import GraphDataScience
gds = GraphDataScience("neo4j+s://xxx.databases.neo4j.io", auth=("neo4j", "pw"), aura_ds=True)
gds = GraphDataScience("bolt://localhost:7687", auth=("neo4j", "password"))
print(gds.server_version())RETURN gds.version() AS gds_versionIf Unknown function 'gds.version' → GDS plugin unavailable. AuraDB serverless analytics → neo4j-aura-graph-analytics-skill. Self-managed/local → install or enable GDS plugin.
pip install graphdatascience # Python client
pip install graphdatascience[rust_ext] # 3–10× faster serializationCompatibility: graphdatascience v1.22 — GDS >= 2.6 and < 2.28 / < 2026.6, Python >= 3.10 and < 3.15, Neo4j Driver >= 4.4.12 and < 7.0.
V2 rules:
- Prefer
gds.v2.*when endpoint exists. - Use snake_case endpoints and parameters:
page_rank,fast_rp,mutate_property,write_property. - Use typed result attributes:
result.write_millis, notresult["writeMillis"]. - Use v1 if v2 endpoint missing/incompatible; label fallback.
---
Graph Catalog Operations
Native Projection
CALL gds.graph.project(
'myGraph',
['Person', 'City'],
{ KNOWS: { orientation: 'UNDIRECTED' }, LIVES_IN: {} }
)
YIELD graphName, nodeCount, relationshipCountG, result = gds.v2.graph.project("myGraph", "Person", "KNOWS")
print(result.node_count, result.relationship_count)
G, result = gds.v2.graph.project(
"myGraph",
{"Person": {"properties": ["age", "score"]}, "City": {}},
{"KNOWS": {"orientation": "UNDIRECTED"}, "LIVES_IN": {"properties": ["since"]}}
)Native projection: plugin/simple Python-client workflow only. AGA Sessions → neo4j-aura-graph-analytics-skill. V1 fallback: gds.graph.project(...).
Cypher Projection (use for new Cypher workflows, filters, transforms)
G, result = gds.graph.cypher.project(
"""
MATCH (source:Person)-[r:KNOWS]->(target:Person)
WHERE source.active = true
RETURN gds.graph.project($graph_name, source, target,
{ sourceNodeProperties: source { .score }, relationshipType: 'KNOWS' })
""",
database="neo4j", graph_name="activeGraph"
)gds.graph.cypher.project must end with one RETURN gds.graph.project(...) clause. If validation fails: use gds.run_cypher(...), then gds.graph.get("graphName"). Use v1 gds.graph.cypher.project(...) if v2 graph projection cannot express required filter/transform.
AGA Sessions → neo4j-aura-graph-analytics-skill; never use plugin Cypher projection.
Undirected Projection
Native projection: set orientation: 'UNDIRECTED' per relationship type. Plugin Cypher projection: set undirectedRelationshipTypes: ['*'] in fifth gds.graph.project(...) config argument.
Leiden is defined for directed and undirected graphs. Project undirected relationships when community structure is naturally symmetric.
Inspect and Drop
G.node_count() # 12_043
G.relationship_count() # 87_211
G.node_properties() # projected + mutated properties by label
G.relationship_properties() # projected + mutated properties by type
G.size_in_bytes()
gds.v2.graph.drop(G) # frees JVM heap
G = gds.v2.graph.get("myGraph") # re-attach to existing projection
gds.v2.graph.list()Memory Estimation — run before large projections and algorithms
CALL gds.graph.project.estimate(['Person'], 'KNOWS')
YIELD requiredMemory, bytesMin, bytesMax, nodeCount, relationshipCountG, project_result = gds.v2.graph.project("myGraph", "Person", "KNOWS")
print(project_result.node_count)
# Algorithm estimation:
est = gds.v2.page_rank.estimate(G, damping_factor=0.85)
print(est.required_memory)Projection estimate fallback: use v1 gds.graph.project.estimate(...) if v2 estimate endpoint unavailable.
---
Execution Modes
| Mode | Side effect | Returns | Use when |
|---|---|---|---|
stream | None | Row per node/pair | Inspect results; top-N |
stats | None | Single aggregate row | Summary/convergence check |
mutate | Adds node property or relationship type/property to in-memory graph only | Stats row | Chain algorithms |
write | Persists node property or relationship to Neo4j DB | Stats row | Final step — make queryable |
Pattern: stream to verify → mutate to chain → write to persist.
mutate_property must not exist in the in-memory graph. Relationship algorithms such as KNN also require mutate_relationship_type. After write, re-project to use written properties in subsequent GDS calls (in-memory graph does not see DB writes).
---
gds.util.asNode() — Enrich Stream Results
stream mode yields nodeId (internal GDS integer). gds.util.asNode(nodeId) translates it back to the DB node so you can access properties.
// Single property
CALL gds.pageRank.stream('myGraph', {})
YIELD nodeId, score
RETURN gds.util.asNode(nodeId).name AS name, score
ORDER BY score DESC LIMIT 10
// Multiple properties — convert once with WITH
CALL gds.pageRank.stream('myGraph', {})
YIELD nodeId, score
WITH gds.util.asNode(nodeId) AS node, score
RETURN node.name AS name, node.born AS born, score
ORDER BY score DESC LIMIT 10Not needed for write, mutate, or stats modes — those don't return per-node data.
---
Core Algorithms
PageRank (centrality)
CALL gds.pageRank.stream('myGraph', { dampingFactor: 0.85, maxIterations: 20 })
YIELD nodeId, score
RETURN gds.util.asNode(nodeId).name AS name, score ORDER BY score DESC LIMIT 10
// score: relative influence — not absolute. Compare within same run only.
// didConverge: true means score stabilized; if false, increase maxIterations.
CALL gds.pageRank.write('myGraph', { writeProperty: 'pagerank', dampingFactor: 0.85 })
YIELD nodePropertiesWritten, ranIterations, didConvergepr_df = gds.v2.page_rank.stream(G, damping_factor=0.85)
mutate_result = gds.v2.page_rank.mutate(G, mutate_property="pagerank", damping_factor=0.85)
write_result = gds.v2.page_rank.write(G, write_property="pagerank", damping_factor=0.85)
print(write_result.write_millis)Louvain (community detection)
CALL gds.louvain.stream('myGraph', { relationshipWeightProperty: 'weight' })
YIELD nodeId, communityId
CALL gds.louvain.write('myGraph', { writeProperty: 'community' })
YIELD communityCount, modularitylouvain_df = gds.v2.louvain.stream(G)
write_result = gds.v2.louvain.write(G, write_property="community")
print(write_result.community_count)Leiden is a refinement of Louvain avoiding poorly connected communities — use when community quality > raw speed. modularity in stats result: range -0.5 to 1.0. [field] Values > 0.3 often indicate meaningful community structure; > 0.7 is strong. Leiden is defined for directed and undirected graphs. Project undirected relationships when community structure is naturally symmetric.
WCC — Weakly Connected Components
Run WCC first to understand graph structure; partition disconnected graphs before expensive algorithms.
CALL gds.wcc.stream('myGraph', { minComponentSize: 10 })
YIELD nodeId, componentId
CALL gds.wcc.write('myGraph', { writeProperty: 'componentId' })
YIELD nodePropertiesWritten, componentCountwcc_df = gds.v2.wcc.stream(G)
write_result = gds.v2.wcc.write(G, write_property="componentId")
print(write_result.node_properties_written)Betweenness Centrality
gds.v2.betweenness_centrality.stream(G) # identifies bottleneck/bridge nodes
gds.v2.betweenness_centrality.write(G, write_property="betweenness")Node Similarity
Jaccard similarity from common neighbors — no node properties required.
gds.v2.node_similarity.stream(G, similarity_cutoff=0.1, top_k=10)
gds.v2.node_similarity.write(G, write_relationship_type="SIMILAR", write_property="score",
similarity_cutoff=0.1, top_k=10)FastRP (node embeddings)
Fast, scalable, production ML pipelines. Set randomSeed for reproducibility.
CALL gds.fastRP.mutate('myGraph', {
embeddingDimension: 256,
iterationWeights: [0.0, 1.0, 1.0],
featureProperties: ['score'],
propertyRatio: 0.5,
normalizationStrength: -0.5,
randomSeed: 42,
mutateProperty: 'embedding'
})
YIELD nodePropertiesWrittengds.v2.fast_rp.mutate(G, embedding_dimension=256, iteration_weights=[0.0, 1.0, 1.0],
random_seed=42, mutate_property="embedding")
write_result = gds.v2.fast_rp.write(G, embedding_dimension=256, write_property="embedding",
random_seed=42)
print(write_result.write_millis)For ANN search over structural embeddings, after write, create a Neo4j vector index over the written property. Use neo4j-vector-index-skill.
KNN — K-Nearest Neighbors
Finds k most similar nodes per node based on node properties (typically embeddings).
CALL gds.knn.stream('myGraph', {
nodeProperties: ['embedding'], topK: 10,
sampleRate: 0.5, similarityCutoff: 0.7
})
YIELD node1, node2, similarity
CALL gds.knn.write('myGraph', {
nodeProperties: ['embedding'], topK: 10,
writeRelationshipType: 'SIMILAR', writeProperty: 'score'
})
YIELD relationshipsWrittenknn_df = gds.v2.knn.stream(G, node_properties=["embedding"], top_k=10)
gds.v2.knn.write(G, node_properties=["embedding"], top_k=10,
write_relationship_type="SIMILAR", write_property="score")---
FastRP → KNN Pipeline (recommendation)
# 1. Project
G, _ = gds.v2.graph.project("myGraph", "Product",
{"BOUGHT_TOGETHER": {"orientation": "UNDIRECTED"}})
# 2. Estimate memory
print(gds.v2.fast_rp.estimate(G, embedding_dimension=128).required_memory)
# 3. Embed
gds.v2.fast_rp.mutate(G, embedding_dimension=128, random_seed=42, mutate_property="emb")
# 4. Similarity
gds.v2.knn.write(G, node_properties=["emb"], top_k=10,
write_relationship_type="SIMILAR", write_property="score")
# 5. Cleanup
gds.v2.graph.drop(G)---
Algorithm Selection
| Goal | Algorithm |
|---|---|
| Influence via network links | PageRank / ArticleRank |
| Bottleneck / bridge nodes | Betweenness Centrality |
| Direct connections | Degree Centrality |
| Community (general, fast) | Louvain |
| Community (higher quality) | Leiden |
| Is graph connected? | WCC (run first) |
| Similarity from embeddings | KNN |
| Similarity from neighbors | Node Similarity |
| Shortest path (positive weights) | Dijkstra / A* |
| k alternative paths | Yen's |
| Fast scalable embeddings | FastRP |
| Feature-rich nodes | GraphSAGE (gds.beta.graphSage) |
Full algorithm catalog → references/algorithms.md
---
Common Errors
| Error | Cause | Fix |
|---|---|---|
Unknown function 'gds.version' | Embedded GDS plugin unavailable | AGA → neo4j-aura-graph-analytics-skill; self-managed/local → install plugin |
Insufficient heap memory / OOM | Graph too large for available JVM heap | Run gds.graph.project.estimate; increase dbms.memory.heap.max_size |
Procedure not found: gds.leiden | Older or incompatible GDS | Check CALL gds.list() for available procedures; upgrade GDS or use Louvain |
Node property 'X' not found after mutate | Property not projected or wrong graph name | Verify G.node_properties() includes the property; check mutate_property spelling |
Graph 'myGraph' already exists | Leftover projection from failed run | CALL gds.graph.drop('myGraph') or gds.v2.graph.drop(G) |
mutate_property already exists | Re-running algorithm on same projection | Drop and re-project, or use different mutate_property name |
No algorithm results | Source/target node not in projection | Verify node labels/rel types match projection; check G.node_count() |
---
Full Workflow
1. Create gds with GraphDataScience(...). 2. Verify plugin: gds.server_version() or RETURN gds.version(). 3. Estimate memory: gds.graph.project.estimate(...) and algorithm .estimate(...). 4. Project named graph with gds.v2.graph.project(...). 5. Run gds.v2.*.stream first; switch to mutate; use write only when satisfied. 6. Drop graph with gds.v2.graph.drop(G). 7. Use v1 only for endpoints missing in v2, such as plugin Cypher projection.
Built-in test datasets: gds.v2.graph.datasets.load_cora(), gds.v2.graph.datasets.load_karate_club(), gds.v2.graph.datasets.load_imdb()
---
MCP Tool Mapping
| Operation | MCP tool |
|---|---|
RETURN gds.version() | read-cypher |
gds.pageRank.stream(...) | read-cypher |
gds.pageRank.write(...) | write-cypher |
gds.graph.drop(...) | write-cypher |
| List available procedures | read-cypher → CALL gds.list() |
Before any write-cypher: show exact Cypher, expected nodes/relationships affected, and ask for confirmation. For algorithm write mode, estimate or run stats first when available.
---
References
- references/algorithms.md — full algorithm catalog: all procedures, parameters, tiers, Cypher + Python examples
- references/graph-projection.md — projection deep-dive: filtering, heterogeneous graphs, relationship orientation, property types
- GDS Manual
- Python Client Docs
---
Checklist
- [ ] Embedded GDS plugin confirmed with
gds.version()orgds.server_version() - [ ] Graph/algorithm memory estimated before large work
- [ ] Python examples prefer
gds.v2.*, snake_case params, typed result attributes - [ ] v1 APIs used only as explicit fallback
- [ ] Projection uses native or plugin Cypher projection; no
gds.graph.project.remote(...) - [ ] Named graph dropped after use (
gds.v2.graph.drop(G)or v1 fallback) - [ ] Execution mode chosen:
stream(inspect) →mutate(chain) →write(persist) - [ ]
write_property/mutate_propertychecked for collision with existing properties - [ ]
randomSeedset for reproducible embeddings - [ ] WCC run first on graphs that may be disconnected
neo4j-gds-skill
Agent skill for Neo4j Graph Data Science (GDS) embedded plugin through the Python client or Cypher. Use for Aura Pro, self-managed, local, or offline Neo4j DBMS with the GDS plugin installed.
What this skill covers
- Graph projection: native projection and Cypher projection
- Execution modes: stream / stats / mutate / write and when to use each
- Core algorithms: PageRank, Louvain, WCC, Betweenness Centrality, Node Similarity, FastRP, KNN
- FastRP → KNN recommendation pipeline pattern
- Writing node embeddings for Neo4j vector indexes / structural similarity search
- Memory estimation before large projections and algorithm runs
- GDS Python client (
graphdatascience) — v2 connection, projection, algorithm calls; v1 fallback when needed - Graph catalog operations: project, list, drop, subgraph filter
- Common errors and mitigations (OOM, missing properties, unlicensed algorithms)
Compatibility
- GDS Python client v1.21: GDS >= 2.6 and < 2.28 / < 2026.4
- Embedded GDS plugin: Neo4j >= 5.x self-managed/local or Aura Pro plugin workflows
- Python >= 3.10 and < 3.15
- Neo4j Python Driver >= 4.4.12 and < 7.0
Not covered
- Cypher query authoring →
neo4j-cypher-skill - Driver/connection setup →
neo4j-driver-python-skill - Creating/querying vector indexes over written embeddings →
neo4j-vector-index-skill - Aura Graph Analytics Sessions / AGA →
neo4j-aura-graph-analytics-skill
Install
pip install graphdatasciencenpx skills add https://github.com/neo4j-contrib/neo4j-skills --skill neo4j-gds-skillGDS Algorithm Reference
Core catalog of commonly used GDS procedures. Mode availability varies by algorithm; check CALL gds.list() or the algorithm syntax page before assuming stream / stats / mutate / write.
Python client: prefer gds.v2.* endpoints and snake_case parameters. Procedure tables show Cypher procedure names.
Centrality
| Algorithm | Procedure | Best For |
|---|---|---|
| PageRank | gds.pageRank | Network influence via incoming links |
| Betweenness Centrality | gds.betweenness | Bottleneck/bridge nodes |
| Degree Centrality | gds.degree | Most-connected nodes (fast) |
| ArticleRank | gds.articleRank | PageRank variant dampening high-degree nodes |
| Eigenvector | gds.eigenvector | Influence via well-connected neighbors |
| Closeness | gds.closeness | Average distance to all other nodes |
| HITS | gds.hits | Authority/hub scores (web-like graphs) |
PageRank — key parameters
| V2 parameter | Cypher/v1 parameter | Default | Notes |
|---|---|---|---|
damping_factor | dampingFactor | 0.85 | Probability of following a link; lower = more teleportation |
max_iterations | maxIterations | 20 | |
tolerance | tolerance | 1e-7 | Convergence threshold |
relationship_weight_property | relationshipWeightProperty | — | Optional weight property |
Spider traps (closed groups, no outlinks) inflate scores — increase dampingFactor. Negative weights silently ignored.
---
Community Detection
| Algorithm | Procedure | Notes |
|---|---|---|
| Louvain | gds.louvain | Best general-purpose; modularity maximization |
| Leiden | gds.leiden | Refinement of Louvain; avoids poorly connected communities |
| WCC | gds.wcc | Weakly connected components; run first to partition graph |
| SCC | gds.scc | Strongly connected components (directed graphs only) |
| Label Propagation | gds.labelPropagation | Fast, large graphs; non-deterministic |
| K-Core Decomposition | gds.kcore | Dense subgraphs by degree threshold |
| Triangle Count | gds.triangleCount | Counts triangles per node; prerequisite for LCC |
| Local Clustering Coefficient | gds.localClusteringCoefficient | Ratio of closed triangles |
| K-Means | gds.kmeans | Requires node embedding properties as input |
| HDBSCAN | gds.hdbscan | Density-based; finds variable-density communities |
WCC parameters
| Parameter | Notes |
|---|---|
threshold | Only traverse rels with weight >= threshold |
min_component_size / minComponentSize | Only return nodes in components >= N nodes |
---
Similarity
| Algorithm | Procedure | Input | Notes |
|---|---|---|---|
| KNN | gds.knn | Node properties | Defaults metric by type; override with {embedding: 'COSINE'} |
| Node Similarity | gds.nodeSimilarity | Bipartite graph topology | Jaccard / Overlap / Cosine from common neighbors; no node properties needed |
| Filtered Node Similarity | gds.nodeSimilarity | Bipartite graph topology | With sourceNodeFilter/targetNodeFilter |
KNN — key parameters
| V2 parameter | Cypher/v1 parameter | Default | Notes |
|---|---|---|---|
node_properties | nodeProperties | required | String, map, or list of strings/maps |
top_k | topK | 10 | Neighbors per node |
sample_rate | sampleRate | 0.5 | Accuracy vs speed; 1.0 = exact |
similarity_cutoff | similarityCutoff | 0.0 | Only return pairs above threshold |
write_relationship_type | writeRelationshipType | required for write | Relationship type to create |
write_property | writeProperty | required for write | Property name for similarity score |
mutate_relationship_type | mutateRelationshipType | required for mutate | Relationship type to add to in-memory graph |
mutate_property | mutateProperty | required for mutate | Relationship property for similarity score |
Available metrics by property type: Float[] → COSINE, EUCLIDEAN, PEARSON; Integer[] → JACCARD, OVERLAP; scalar numbers → default inverse distance metric only.
---
Path Finding
| Algorithm | Procedure | Use Case |
|---|---|---|
| Dijkstra source-target | gds.shortestPath.dijkstra | Shortest path, positive weights |
| Dijkstra single-source | gds.allShortestPaths.dijkstra | All shortest paths from one source |
| A* | gds.shortestPath.astar | Spatial graphs with lat/lon heuristic |
| Yen's k-Shortest | gds.shortestPath.yens | k alternative shortest paths |
| Bellman-Ford | gds.bellmanFord | Graphs with negative weights |
| Random Walk | gds.randomWalk | Sample graph neighborhoods |
| BFS | gds.bfs | Breadth-first traversal order |
| DFS | gds.dfs | Depth-first traversal order |
MATCH (source:Location {name: 'A'}), (target:Location {name: 'B'})
CALL gds.shortestPath.dijkstra.stream('myGraph', {
sourceNode: source, targetNode: target,
relationshipWeightProperty: 'distance'
})
YIELD index, sourceNode, targetNode, totalCost, nodeIds, costs, path
RETURN totalCost, [nodeId IN nodeIds | gds.util.asNode(nodeId).name] AS nodes---
Node Embeddings
| Algorithm | Procedure | Inductive? | Best For |
|---|---|---|---|
| FastRP | gds.fastRP | Yes (set randomSeed for reproducibility) | Fast, scalable, production ML |
| GraphSAGE | gds.beta.graphSage | Yes | Feature-rich nodes; generalizes to unseen nodes |
| Node2Vec | gds.node2vec | No (transductive) | Structural similarity; same graph train+predict |
| HashGNN | gds.hashgnn | Yes | GNN-style, limited compute, fast |
FastRP — key parameters
| V2 parameter | Cypher/v1 parameter | Default | Notes |
|---|---|---|---|
embedding_dimension | embeddingDimension | required | 128–512 typical |
iteration_weights | iterationWeights | [0.0, 1.0, 1.0] | [self, 1-hop, 2-hop] neighborhood weights |
feature_properties | featureProperties | [] | Node properties to incorporate |
property_ratio | propertyRatio | 0.0 | Fraction of dims for node properties (requires feature_properties) |
normalization_strength | normalizationStrength | 0.0 | Negative = downplay high-degree hubs |
random_seed | randomSeed | — | Set for reproducibility |
Node2Vec — key parameters
| V2 parameter | Cypher/v1 parameter | Default | Notes |
|---|---|---|---|
embedding_dimension | embeddingDimension | 128 | |
walk_length | walkLength | 80 | Steps per random walk |
walks_per_node | walksPerNode | 10 | Random walks per node |
in_out_factor | inOutFactor | 1.0 | DFS bias (>1) vs BFS bias (<1) |
return_factor | returnFactor | 1.0 | Probability of returning to previous node |
---
ML Pipelines
Pipeline APIs may lag v2 coverage. Prefer v2 pipeline endpoints when available; otherwise use v1 fallback and keep camelCase parameters.
Node Classification
pipe, _ = gds.nc_pipe("myPipeline")
pipe.addNodeProperty("fastRP", mutateProperty="emb", embeddingDimension=128, randomSeed=42)
pipe.selectFeatures("emb")
pipe.addLogisticRegression(maxEpochs=100)
model, train_result = pipe.train(G, targetProperty="label", metrics=["ACCURACY"])
predictions = model.predict_stream(G)
model.predict_write(G, writeProperty="predicted_label")Link Prediction
pipe, _ = gds.lp_pipe("lpPipeline")
pipe.addNodeProperty("fastRP", mutateProperty="emb", embeddingDimension=128, randomSeed=42)
pipe.addFeature("hadamard", nodeProperties=["emb"])
pipe.addLogisticRegression(maxEpochs=100)
model, result = pipe.train(G, sourceNodeLabel="Person", targetNodeLabel="Person",
targetRelationshipType="KNOWS", metrics=["AUCPR"])
model.predict_stream(G, topN=10, threshold=0.5)---
Built-in Test Datasets
G = gds.v2.graph.datasets.load_cora() # 2,708 Paper nodes, 5,429 CITES edges
G = gds.v2.graph.datasets.load_karate_club() # 34 Person nodes, 78 KNOWS edges
G = gds.v2.graph.datasets.load_imdb() # 12,772 nodes, heterogeneous
G = gds.v2.graph.datasets.load_lastfm() # 19,914 nodes, user-artist graph---
Listing Available Procedures
CALL gds.list() YIELD name, description
RETURN name ORDER BY nameVerify which algorithms are available on the current GDS installation and license tier.
GDS Graph Projection Reference
Projection Types — When to Use Each
| Type | Procedure | When |
|---|---|---|
| Cypher | Python: gds.graph.cypher.project(...) with RETURN gds.graph.project clause inside | Current GDS-doc default; filtering, transformation, computed properties, heterogeneous |
| Native | Python: gds.v2.graph.project(...) | Simple labels + relationship types; shortest Python-client path |
Prefer v2 native projection. Use v1 gds.graph.cypher.project(...) only for filtering, transformations, computed properties, or heterogeneous projections that v2 native projection cannot express. Avoid legacy gds.graph.project.cypher(...) for new work. For Aura Graph Analytics sessions, use neo4j-aura-graph-analytics-skill.
---
Native Projection — Full Syntax
CALL gds.graph.project(
'graphName',
nodeProjection, -- '*', label string, list of labels, or map with properties
relationshipProjection -- '*', type string, list of types, or map with orientation/properties
)
YIELD graphName, nodeCount, relationshipCount, projectMillisNode projection variants
// All nodes
'*'
// Single label
'Person'
// Multiple labels (no properties)
['Person', 'City']
// With properties per label
{
Person: { properties: ['age', 'score'] },
City: { properties: { population: { defaultValue: 0 } } }
}VECTOR-type properties projectable as node properties [GDS 2026.05].
Relationship projection variants
// All relationships
'*'
// Single type
'KNOWS'
// Multiple types
['KNOWS', 'LIVES_IN']
// With orientation and properties
{
KNOWS: {
orientation: 'UNDIRECTED', -- NATURAL (default), UNDIRECTED, REVERSE
properties: ['weight']
},
LIVES_IN: {
properties: {
since: { defaultValue: 0 }
}
}
}Orientation options
| Orientation | Effect |
|---|---|
NATURAL | As stored in DB (default) |
UNDIRECTED | Adds reverse direction — doubles relationship count |
REVERSE | Flips direction |
Use UNDIRECTED for undirected algorithms: community detection, most similarity/embedding algorithms. Use NATURAL for directed algorithms: PageRank, Betweenness.
Default values
// Nodes with missing property get defaultValue 0.0 instead of null
{
Person: {
properties: {
score: { property: 'score', defaultValue: 0.0 }
}
}
}Null node properties in projection → algorithm errors. Set defaultValue for optional properties.
---
Python Client — Projection
from graphdatascience import GraphDataScience
gds = GraphDataScience("bolt://localhost:7687", auth=("neo4j", "pw"))
# Simple native projection — plugin/simple client only
G, result = gds.v2.graph.project("myGraph", "Person", "KNOWS")
print(result.node_count, result.relationship_count)
# Multi-label, multi-rel, properties
G, result = gds.v2.graph.project(
"myGraph",
{"Person": {"properties": ["age", "score"]},
"City": {"properties": {"population": {"defaultValue": 0}}}},
{"KNOWS": {"orientation": "UNDIRECTED", "properties": ["weight"]},
"LIVES_IN": {"properties": ["since"]}}
)
# V1 fallback:
G, result = gds.graph.project("myGraph", "Person", "KNOWS")---
Cypher Projection — Full Pattern
G, result = gds.graph.cypher.project(
"""
MATCH (source:Person)-[r:KNOWS]->(target:Person)
WHERE source.active = true AND target.active = true
RETURN gds.graph.project(
$graph_name, source, target,
{
sourceNodeLabels: labels(source),
targetNodeLabels: labels(target),
sourceNodeProperties: source { .score },
targetNodeProperties: target { .score },
relationshipType: 'KNOWS',
relationshipProperties: r { .weight }
}
)
""",
database="neo4j",
graph_name="filteredGraph"
)Use gds.graph.project($graph_name, source, target, {...}) in RETURN; $graph_name parameter injected automatically. Query must end with exactly one RETURN gds.graph.project(...). Else use gds.run_cypher(...), then gds.graph.get("filteredGraph"). Never use gds.graph.project.cypher(...) for new Cypher projections; legacy deprecated projection procedure. AGA Sessions → neo4j-aura-graph-analytics-skill.
---
Graph Object API
G.name() # "myGraph"
G.node_count() # 12_043
G.relationship_count() # 87_211
G.node_labels() # ["Person", "City"]
G.relationship_types() # ["KNOWS", "LIVES_IN"]
G.node_properties() # projected + mutated properties by label
G.relationship_properties()
G.size_in_bytes()
gds.v2.graph.drop(G)
# Re-attach to existing projection
G = gds.v2.graph.get("myGraph")
# List all projected graphs
gds.v2.graph.list()---
Memory Estimation
# Project estimation
G, project_result = gds.v2.graph.project("myGraph", "Person", "KNOWS")
print(project_result.node_count)
# Algorithm estimation (requires projected graph)
est = gds.v2.page_rank.estimate(G, damping_factor=0.85)
est = gds.v2.fast_rp.estimate(G, embedding_dimension=256)
print(est.required_memory)Projection estimate fallback: use v1 gds.graph.project.estimate(...) if v2 estimate endpoint unavailable.
If requiredMemory exceeds JVM heap (dbms.memory.heap.max_size), reduce graph or increase heap. Treat 80% heap as review threshold, not hard guarantee.
---
Catalog Management
// List all projected graphs
CALL gds.graph.list() YIELD graphName, nodeCount, relationshipCount, memoryUsage
// Drop by name
CALL gds.graph.drop('myGraph') YIELD graphName
// Drop if exists (no error if missing)
CALL gds.graph.drop('myGraph', false) YIELD graphNamegds.v2.graph.list() # list of typed graph metadata objects
gds.v2.graph.get("myGraph") # GraphV2
gds.v2.graph.drop("myGraph") # Drop by name
gds.v2.graph.drop(G) # Drop via objectDrop graphs after use. Catalog graphs persist until dropped, source database stops/drops, or DBMS stops.
---
Heterogeneous Graphs
Project multiple node labels/relationship types for algorithms that support them (e.g., gds.metaPath):
G, _ = gds.v2.graph.project(
"heteroGraph",
["Actor", "Movie", "Genre"],
["ACTED_IN", "HAS_GENRE"]
)
# Filter algorithms to specific labels/types
gds.v2.page_rank.stream(G,
node_labels=["Actor"],
relationship_types=["ACTED_IN"]
)Most algorithms accept v2 node_labels and relationship_types to scope execution within heterogeneous projection.
---
Subgraph Projection (filter an existing projection)
# Create subgraph from existing named graph
sub_G, result = gds.v2.graph.filter(
G, # source graph
"subGraph", # new graph name
"n.score > 0.5", # node filter (Cypher predicate)
"r.weight > 1.0" # relationship filter
)Project once; filter many times without re-reading database.
Related skills
How it compares
Pick neo4j-gds-skill over generic Cypher skills when graph algorithm projections, memory estimation, or embedding pipelines require the GDS plugin.
FAQ
Which Neo4j GDS algorithms does neo4j-gds-skill cover?
neo4j-gds-skill covers PageRank, Louvain, WCC, Betweenness Centrality, Node Similarity, FastRP, and KNN. The skill also documents the FastRP-to-KNN recommendation pipeline and embedding write-back for vector indexes.
Does neo4j-gds-skill support memory estimation?
neo4j-gds-skill includes memory estimation guidance before large native or Cypher graph projections and algorithm runs. Developers use the graphdatascience Python client to avoid heap failures on big graphs.
What GDS execution modes does neo4j-gds-skill explain?
neo4j-gds-skill explains stream, stats, mutate, and write execution modes and when to use each. The skill helps pick the right mode for analytics previews versus persisting results to the graph.
Is Neo4j Gds Skill safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.