学术科研
在装有 GDS 插件的 Neo4j 上做图算法分析时,用…
对 Aura Pro / 自管 / 本地 / 离线且安装了 GDS 插件的 Neo4j,通过 Python 客户端或 Cypher 做图投影、中心性/社区/相似度/嵌入算法与 ML 流水线。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
在装有 GDS 插件的 Neo4j 上做特定
解决思路
- 安装并用 2.0 客户端连接:`pip install graphdatascience`(可选 `pip install "graphdatascience[rust-ext]"` 加速序列化);`gds = GraphDataScience("neo4j+s://xxx.databases.neo4j.io", auth=("neo4j", "pw"))`(AuraDS 会自动推导 aura_ds),本地用 `GraphDataScience("bolt://localhost:7687", auth=("neo4j","password"))`。
- 先验证插件可用:`print(gds.server_version())` 或 Cypher `RETURN gds.version() AS gds_version`;若构造时报 `GdsNotFound` 或 Cypher 报 `Unknown function 'gds.version'`,说明目标库没装/没启用 GDS 插件(自管或本地需安装启用);AuraDB serverless analytics 不属于本流程。
- 核对版本兼容性:graphdatascience 2.0 要求 GDS >= 2.13 且 < 2.28 / < 2026.9、Python >= 3.10 且 < 3.15、Neo4j Python driver >= 5.26 且 < 7.0、pandas 2–3、pyarrow 21–25;GDS 插件版本要与服务器版本对齐(如插件 `2026.08.1` 对应 Neo4j `2026.08`),升级任何一侧前先查 GDS 兼容表。
- GDS server < 2.13 时改用 1.x 客户端(`pip install "graphdatascience<2"`,即 1.22),并按映射表改写调用:`gds.v2.page_rank`/`gds.v2.louvain`(2.0 无 v2 前缀)、`gds.v2.graph.project(...)`、`gds.graph.cypher.project(query, database=...)`、`GraphV2`/`ModelV2`、`Graph.drop(failIfMissing=)`、`run_cypher(..., retryable=...)`(2.0 总是重试)。
- 遵守 2.0 客户端规则:端点不加 `v2` 前缀;参数一律 snake_case(`page_rank`、`fast_rp`、`mutate_property`、`write_property`);结果用类型化属性 `result.write_millis` 而不是 `result["writeMillis"]`(`stream` 仍返回 DataFrame);客户端没有 `gds.version()`,用 `gds.server_version()`;过程别名 `gds.betweenness` ≡ `gds.betweenness_centrality`,另有 `gds.closeness`、`gds.degree`、`gds.eigenvector`、`gds.harmonic`、`gds.kcore`;ML 流水线仅 `gds.pipeline.node_classification` / `link_prediction` / `node_regression`;插件面没有异步/job-handle API(`compute()`、`*_async`、`gds.jobs` 仅 AGA Sessions 有)。
- 原生投影:Cypher `CALL gds.graph.project('myGraph', ['Person','City'], { KNOWS: { orientation: 'UNDIRECTED' }, LIVES_IN: {} }) YIELD graphName, nodeCount, relationshipCount`;Python `G, result = gds.graph.project.native("myGraph", "Person", "KNOWS")`,支持按标签给属性、按类型给方向/属性,重投影加 `overwrite=True`。
- Cypher 投影用于过滤、转换和新 Cypher 工作流:`G, result = gds.graph.project.cypher("""... RETURN gds.graph.project($graph_name, source, target, { sourceNodeProperties: source { .score }, relationshipType: 'KNOWS' })""", graph_name="activeGraph")`;查询必须恰好以一个 `RETURN gds.graph.project(...)` 结尾;`gds.graph.project.cypher(query)` 不接受 `database=`,需在 `GraphDataScience(..., database=...)` 构造时或 `gds.set_database(...)` 指定;校验失败时先用 `gds.run_cypher(...)` 再 `gds.graph.get("graphName")`。
- 无向投影:原生投影对每个关系类型设 `orientation: 'UNDIRECTED'`;插件 Cypher 投影在第五个 `gds.graph.project(...)` 配置参数里设 `undirectedRelationshipTypes: ['*']`;当社区结构天然对称时投影无向关系(Leiden 对有向/无向图都有定义)。
- 检查与释放图:`G.node_count()`、`G.relationship_count()`、`G.node_properties()`、`G.relationship_properties()`、`G.size_in_bytes()`;用 `G = gds.graph.get("myGraph")` 重新附着已有投影;`gds.graph.list()` 列图;`gds.graph.drop(G)` 释放 JVM 堆(2.0 返回 `list[GraphInfo]`)。
- 大图投影和算法前做内存估算:Cypher `CALL gds.graph.project.estimate(['Person'], 'KNOWS') YIELD requiredMemory, bytesMin, bytesMax, nodeCount, relationshipCount`;Python `gds.graph.project.estimate(node_projection=["Person"], relationship_projection=["KNOWS"]).required_memory`,以及算法侧 `gds.page_rank.estimate(G, damping_factor=0.85).required_memory`。
- 按目的选执行模式并遵循 `stream` 验证 → `mutate` 串接 → `write` 持久化的顺序:`stream` 无副作用、逐行返回(查看/top-N);`stats` 返回单行聚合(摘要/收敛检查);`mutate` 只把节点属性或关系类型/属性加到内存图(用于串联算法);`write` 落库到 Neo4j(最终步骤,使结果可查询)。
- mutate 相关约束:`mutate_property` 不能已存在于内存图中;KNN 等关系算法还需提供 `mutate_relationship_type`;执行 `write` 之后必须重新投影,后续 GDS 调用才能用到刚写入的属性(内存图看不到 DB 写入)。
- 在 Cypher `stream` 结果里用 `gds.util.asNode(nodeId)` 把内部 nodeId 还原为 DB 节点以读取属性:单属性 `RETURN gds.util.asNode(nodeId).name AS name, score ORDER BY score DESC LIMIT 10`;多属性用 `WITH gds.util.asNode(nodeId) AS node, score` 只转换一次;`write`/`mutate`/`stats` 模式不需要。
- PageRank:`CALL gds.pageRank.stream('myGraph', { dampingFactor: 0.85, maxIterations: 20 })` 排序取 top;score 是相对影响力、只能在同一次运行内比较;`didConverge=false` 时增大 `maxIterations`;持久化用 `gds.pageRank.write('myGraph', { writeProperty: 'pagerank', dampingFactor: 0.85 })`;Python 对应 `gds.page_rank.stream/mutate/write(G, damping_factor=0.85, ...)`。
- Louvain 社区检测:`CALL gds.louvain.stream('myGraph', { relationshipWeightProperty: 'weight' }) YIELD nodeId, communityId`;`gds.louvain.write('myGraph', { writeProperty: 'community' }) YIELD communityCount, modularity`;modularity 范围 -0.5~1.0,> 0.3 通常表示有意义的社区结构,> 0.7 很强;需要更高质量(避免连通性差的社区)时改用 Leiden。
- WCC 先跑:`CALL gds.wcc.stream('myGraph', { minComponentSize: 10 })` / `gds.wcc.write('myGraph', { writeProperty: 'componentId' })`(Python `gds.wcc.stream/write(G, write_property="componentId")`);用它先了解图结构,把不连通的图分区后再跑昂贵算法。
- Betweenness Centrality 找瓶颈/桥接节点:`gds.betweenness.stream(G)`(`betweenness_centrality` 的别名)、`gds.betweenness.write(G, write_property="betweenness")`。
- Node Similarity(基于共同邻居的 Jaccard,不需要节点属性):`gds.node_similarity.stream(G, similarity_cutoff=0.1, top_k=10)`;`gds.node_similarity.write(G, write_relationship_type="SIMILAR", write_property="score", similarity_cutoff=0.1, top_k=10)`。
- FastRP 节点嵌入:`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 nodePropertiesWritten`;Python `gds.fast_rp.mutate/write(G, embedding_dimension=256, iteration_weights=[0.0,1.0,1.0], random_seed=42, mutate_property="embedding")`;设 `randomSeed` 保证可复现。
- KNN 基于节点属性(通常是嵌入)找每个节点的 k 个最相似节点:`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' })`;Python `gds.knn.stream/write(G, node_properties=["embedding"], top_k=10, ...)`。
- FastRP → KNN 推荐流水线:① `gds.graph.project.native("myGraph", "Product", {"BOUGHT_TOGETHER": {"orientation": "UNDIRECTED"}})`;② `gds.fast_rp.estimate(G, embedding_dimension=128).required_memory` 估内存;③ `gds.fast_rp.mutate(G, embedding_dimension=128, random_seed=42, mutate_property="emb")`;④ `gds.knn.write(G, node_properties=["emb"], top_k=10, write_relationship_type="SIMILAR", write_property="score")`;⑤ `gds.graph.drop(G)`。
- 若要对写出的结构嵌入做 ANN 检索:`write` 之后在写出的属性上创建 Neo4j 向量索引(交给 neo4j-vector-index-skill)。
- 按目标选算法:网络影响力 → PageRank / ArticleRank;瓶颈/桥节点 → Betweenness Centrality;直接连接 → Degree Centrality;社区(通用快)→ Louvain;社区(更高质量)→ Leiden;是否连通 → WCC(先跑);基于嵌入的相似 → KNN;基于邻居的相似 → Node Similarity;正权最短路径 → Dijkstra / A*;k 条备选路径 → Yen's;快速可扩展嵌入 → FastRP;特征丰富节点 → GraphSAGE(客户端 `gds.graph_sage`,Cypher `gds.beta.graphSage`)。
- 常见错误按表修复:`Unknown function 'gds.version'` → 插件不可用;构造时 `GdsNotFound` → 目标库未装 GDS 插件;`AttributeError: ... no attribute 'version'` → 用 `gds.server_version()`;构造时 `DeprecationWarning` → GDS server < 2.13(升级或锁 `graphdatascience<2`);`Insufficient heap memory`/OOM → 先 `gds.graph.project.estimate` 并调大 `dbms.memory.heap.max_size`;`Procedure not found: gds.leiden` → 查 `CALL gds.list()`,升级 GDS 或改用 Louvain;mutate 后 `Node property 'X' not found` → 检查 `G.node_properties()` 与 `mutate_property` 拼写;`Graph 'myGraph' already exists` → 用 `overwrite=True` 或先 `CALL gds.graph.drop('myGraph')`/`gds.graph.drop(G)`;`mutate_property already exists` → 重投影或换名;`No algorithm results` → 源/目标节点不在投影里,核对标签/关系类型与 `G.node_count()`;`gds.graph.drop(...)` 返回 list 上的 `AttributeError` → 索引取值(1.x 返回单个 `GraphInfo`)。
- 按完整工作流串起来:① 创建 `GraphDataScience(...)`;② 验证插件(`gds.server_version()` 或 `RETURN gds.version()`);③ 估算内存(`gds.graph.project.estimate(...)` 与算法 `.estimate(...)`);④ 用 `gds.graph.project.native(...)` 或 `gds.graph.project.cypher(query)` 投影命名图;⑤ 先 `stream`,再 `mutate`,满意后才 `write`;⑥ `gds.graph.drop(G)`;⑦ GDS < 2.13 时用 1.22 客户端并按映射表改写。
- 用内置测试数据集验证:`gds.graph.datasets.load_cora()`、`gds.graph.datasets.load_karate_club()`、`gds.graph.datasets.load_imdb()`。
- GDS 插件 `2026.07.0` 起移除了 `CALL gds.userLog()`:改从 driver 结果 summary 的通知或 Neo4j debug log 读取提示与警告,用 `CALL gds.listProgress()` 跟踪任务进度。
- 如通过 MCP 调用:只读操作(`RETURN gds.version()`、`gds.pageRank.stream(...)`、`CALL gds.list()`)走 `read-cypher`;`gds.pageRank.write(...)`、`gds.graph.drop(...)` 走 `write-cypher`;执行任何 `write-cypher` 前展示确切 Cypher、预计影响的节点/关系数并请求确认,算法 `write` 模式尽量先 estimate 或跑 `stats`。
- 交付前过一遍清单:确认插件(`gds.server_version()` 或 `RETURN gds.version()`);大操作前估算内存;Python 示例用 2.0 端点(无 v2 前缀)、snake_case 参数、类型化结果属性;client 1.x 只配 GDS server < 2.13 并走映射表;投影只用 native 或插件 Cypher 投影、不用 `gds.graph.project.remote(...)`;用完 drop 命名图;明确执行模式 stream → mutate → write;检查 `write_property`/`mutate_property` 是否与已有属性冲突;重投影用 `overwrite=True`;嵌入设 `randomSeed`;可能不连通的图先跑 WCC。
适用边界 · 注意事项
- Aura Graph Analytics Sessions / AGA / `GdsSessions` / `AuraGraphDataScience`,以及带 `{ memory: ... }` 或 `{ sessionId: ... }` 的 AuraDB Cypher API、`gds.graph.project.remote`、非 Neo4j 数据源 —— 改用 neo4j-aura-graph-analytics-skill。
- Cypher 查询编写 → neo4j-cypher-skill;driver/连接设置 → neo4j-driver-python-skill;GraphRAG 检索 → neo4j-graphrag-skill;在写出的嵌入上创建/查询向量索引 → neo4j-vector-index-skill。
- 目标库没有安装或启用 GDS 插件时不可用(会报 `GdsNotFound` / `Unknown function 'gds.version'`),必须先在自管或本地 Neo4j 上安装/启用插件。