mcpField
N
neo4j-cypher-skill

neo4j-cypher-skill

github.com/neo4j-contrib数据与数据库1181.5k 次安装1 周前更新
代码仓库

关于 neo4j-cypher-skill

neo4j-cypher-skill 是面向 Neo4j 用户的 Cypher 编写、优化与调试技能,涵盖查询模式和语法注意事项。它强调先依据真实 Schema 构造和校验查询,避免猜测标签、关系类型或属性。

主要功能

  1. 01编写与调试 Cypher 查询
  2. 02依据 Schema 检查标签和属性
  3. 03提供路径匹配与子查询模式
  4. 04指导批量写入和查询优化
  5. 05涵盖向量与全文搜索语法

适用场景

  1. 01构造图模式匹配查询
  2. 02排查 Cypher 查询错误
  3. 03编写路径遍历或子查询
  4. 04准备 CSV 批量写入操作

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/neo4j-contrib/neo4j-skills --skill neo4j-cypher-skill

安装后在 Claude Code 中输入/neo4j-cypher-skill确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
references/
advanced-patterns.md
apoc.md
cypher-syntax.md
graph-type.md
indexes.md
performance.md
schema-guardrail.md
syntax-traps.md
scripts/
define_schema.py
generate_schema.py
import_neo4j_schema.py

详细介绍

适用场景

  • 编写、优化或调试 Cypher 查询
  • 图模式匹配、QPE、可变长度路径
  • 向量/全文搜索、子查询、批量写入、LOAD CSV

不适用场景

  • 驱动迁移/API 变更 → neo4j-migration-skill
  • 数据库管理(用户、配置、备份)→ neo4j-cli-tools-skill
  • 结合向量、全文搜索或其他排序来源的混合搜索 → neo4j-vector-index-skill

GQL 一致性说明:LET、FINISH、FILTER 和 INSERT 是有效的 Cypher 25 子句(通过 GQL 一致性引入,大多在 Neo4j 2025.06 中)。在较旧版本中,改用 WITH /(省略 RETURN)/ WHERE / CREATE。INSERT 要求多个标签之间以 & 分隔,且不支持动态标签/类型。


执行前检查

?已知未知
在项目中找到 <db-name>-schema.json直接使用 — 跳过实时检查—
Schema(来自上下文或实时数据库)直接使用运行 Schema-First Protocol
Neo4j 版本使用对应版本的功能默认使用 2025.01 安全功能集
是否要执行(而非生成)?使用 EXPLAIN + 写入门控说明查询尚未验证

Schema 未知且没有工具 → 在代码块外生成不可执行的草案:

(<SOURCE_LABEL> {<KEY>: $value})-[:<REL_TYPE>]->(<TARGET_LABEL>)

绝不填入猜测的名称 — 看似合理的猜测很容易被直接照搬。


默认规则 — 每个查询均适用

  1. CYPHER 25 — 必须是第一个令牌;在 UNION 之后或子查询内绝不重复
  2. Schema 优先 — 编写前先检查;如果提示词中提供了 Schema,直接使用
  3. 只对有约束的键使用 MERGE;关系的 MERGE 只能用于已绑定的端点
  4. 禁止使用无标签的 MATCH (n),除非 n 已绑定,或后面跟有 WHERE n:$($label)
  5. 所有探索性读取默认使用 LIMIT 25;在高基数操作(可变长度遍历、扇出 MATCH、笛卡尔积)之前使用 WITH n LIMIT
  6. 注释:只能使用 // — -- 是 SQL 语法,无效
  7. REPEATABLE ELEMENTS / DIFFERENT RELATIONSHIPS 放在 MATCH 后,而不是模式末尾
  8. SHOW 命令:WHERE 前必须有 YIELD;可与通用 Cypher 子句组合,包括 UNION/RETURN [2026.05] — SHOW DATABASES 仍要求使用 system 数据库(使用 USE system)。在 system 数据库上使用 CALL:先 YIELD,再 WHERE [2026.07]
  9. 内联节点谓词 (:Label WHERE p=x) — 仅在 MATCH 中有效
  10. 裸 UNWIND 后不能跟 WHERE — 使用 WITH x WHERE
  11. (a)-[:R]-(b) — 无向匹配会覆盖两个方向,造成重复计数;除非方向未知,否则使用有向匹配
  12. DETACH DELETE — 如果节点有关联关系,普通 DELETE 会报错

风格

元素约定
节点标签PascalCase :Person
关系类型SCREAMING_SNAKE_CASE :KNOWS
属性/变量camelCase firstName
子句大写 MATCH
布尔值/空值小写 true false null
字符串使用单引号;仅在包含 ' 时使用双引号

Schema 才是准则。示例中的 :Person、:KNOWS、name 仅用于说明 — 请替换为 Schema 中的实际名称。


协议优先使用 Schema

优先级顺序:

  1. 项目中任意位置存在 <db-name>-schema.json → 直接读取,注明文件名和 schema_retrieved_at,跳过实时检查。如果文件已明显过时且数据库可连接,则提出重新获取。完整规则见:references/schema-guardrail.md。

    • 是否存在 — 标签/关系类型/属性必须在 schema 中;提问前先尝试解析同义词
    • 属性类型 — 先判断意图(例如,string 与 INTEGER 的差异可能是空值检查);只有不明确时才提问
    • 关系方向 — 方向错误时,静默纠正并注明
    • 同义词映射 — 映射明确时,静默解析;有歧义时,选择最可能的映射并注明;无法解析时再提问

    脚本:generate_schema.py(实时数据库 + APOC)、define_schema.py(无数据库)、import_neo4j_schema.py(转换 neo4j-graphrag-python、graph-schema-introspector、graph-schema-json-js-utils、mcp-neo4j-data-modeling)。

  2. 上下文中已有 Schema → 使用该 Schema,跳过检查。

  3. 缺少 Schema → 运行:

CALL db.schema.visualization() YIELD nodes, relationships RETURN nodes, relationships;
SHOW INDEXES YIELD name, type, labelsOrTypes, properties, state WHERE state = 'ONLINE';
SHOW CONSTRAINTS YIELD name, type, labelsOrTypes, properties;
SHOW PROCEDURES YIELD name RETURN split(name,'.')[0] AS namespace, count(*) AS procedures;

按标签检查属性类型 — 优先检查 APOC:

// If APOC available (preferred — use this):
CALL apoc.meta.schema() YIELD value RETURN value;

// No APOC AND database ≤ 100k nodes/rels only (expensive on large graphs):
CALL db.schema.nodeTypeProperties() YIELD nodeType, propertyName, propertyTypes, mandatory;
CALL db.schema.relTypeProperties() YIELD relType, propertyName, propertyTypes, mandatory;

返回任何查询前都要验证:标签存在 · 关系类型和方向正确 · 属性属于该标签 · 索引状态为 ONLINE。


关键模式

MERGE
// MERGE on constrained key; set extras in ON CREATE/ON MATCH
CYPHER 25
MATCH (a:Person {id: $a}) MATCH (b:Person {id: $b})
MERGE (a)-[r:KNOWS]->(b)
  ON CREATE SET r.since = date()
  ON MATCH  SET r.lastSeen = date()

SET n = {} 会替换所有属性。SET n += {} 会合并属性(安全的部分更新)。更新时使用 +=。

WITH 作用域
CYPHER 25
MATCH (a:Person)-[:KNOWS]->(b:Person)
WITH a, count(*) AS friends   // b dropped here
WHERE friends > 5
RETURN a.name, friends ORDER BY friends DESC

未列入 WITH 的所有变量都会被丢弃。WITH * 会将所有变量传递下去。

子查询 — 速查表
EXISTS { (a)-[:R]->(b) }                           // boolean check
COUNT  { (a)-[:R]->(b) WHERE a.x > 0 }             // count
COLLECT { MATCH (a)-[:R]->(b) RETURN b.name }       // collect list (full MATCH+RETURN required)
CALL (p) { MATCH (p)-[:ACTED_IN]->(m) RETURN m }    // correlated subquery (explicit import)
OPTIONAL CALL (p) { ... }                           // nullable subquery

CALL { WITH x ... } 已弃用 → 使用 CALL (x) { ... }。COLLECT {} 恰好返回一列。

CALL IN TRANSACTIONS(批量写入)
CYPHER 25
LOAD CSV WITH HEADERS FROM 'file:///data.csv' AS row
CALL (row) {
  MERGE (p:Person {id: row.id}) SET p += row
} IN TRANSACTIONS OF 1000 ROWS ON ERROR CONTINUE REPORT STATUS AS s

输入流必须位于子查询之外。仅支持自动提交 — 绝不要将其封装在 beginTransaction() 中。PERIODIC COMMIT 已弃用。

在 IN CONCURRENT TRANSACTIONS 上使用 DISJOINT BY [2026.06, Cypher 25],通过按顺序调度共享易引发锁冲突的资源的批次来避免死锁 — 导入关系时使用:

CYPHER 25
LOAD CSV WITH HEADERS FROM 'file:///rels.csv' AS line
CALL (line) {
  MATCH (a:Movie {id: line.movieId}), (b:Person {id: line.personId})
  MERGE (b)-[:ACTED_IN]->(a)
} IN CONCURRENT TRANSACTIONS OF 1000 ROWS DISJOINT BY (line.movieId, line.personId)

DISJOINT BY (expr,...) 声明锁定键(仅限外层查询变量);DISJOINT BY AUTO 通过静态分析推断锁定键;DISJOINT BY NONE 则禁用该功能。此设置会覆盖 dbms.cypher.transactions.default_subquery_batch_strategy。EXPLAIN/PROFILE 会在 TransactionForeach 上显示 DISJOINT BY (...) 中的键。

QPE 基础知识
CYPHER 25
MATCH SHORTEST 1 (a:Person {name:'Alice'})(()-[:KNOWS]->()){1,}(b:Person {name:'Bob'})
RETURN b.name

// ACYCLIC [2026.03] — no repeated nodes within a path (prevents cycles)
CYPHER 25
MATCH p = ACYCLIC (start:Router {name: $from})-[:LINK]-+(end:Router {name: $to})
RETURN [n IN nodes(p) | n.name] AS route
ORDER BY length(p) LIMIT 5

量词放在分组之外:(pattern){N,M}。分组必须以节点开始并以节点结束。REPEATABLE ELEMENTS 需要有界的 {m,n}。ACYCLIC 表示路径中的节点不可重复(比默认的 DIFFERENT RELATIONSHIPS 更严格)。

匹配模式 — 添加在 MATCH 之后:

  • DIFFERENT RELATIONSHIPS(默认)— 每条路径中每个关系仅遍历一次
  • REPEATABLE ELEMENTS [2025.x] — 节点/关系可以重复访问;用于环形路线、权重优化路径、带约束的回溯;需要有界的 {m,n}
条件 CALL 子查询 [2025.06]
CYPHER 25
MATCH (move:Item {id: $id})
OPTIONAL MATCH (insertBefore:Item {id: $before})
OPTIONAL MATCH (insertAfter:Item  {id: $after})
CALL (move, insertBefore, insertAfter) {
  WHEN insertBefore IS NULL THEN {
    MATCH (last:Item) WHERE NOT (last)-[:NEXT]->() AND last <> move
    CREATE (last)-[:NEXT]->(move)
  }
  WHEN insertAfter IS NULL THEN {
    CREATE (move)-[:NEXT]->(insertBefore)
  }
  ELSE {
    CREATE (insertAfter)-[:NEXT]->(move)
    CREATE (move)-[:NEXT]->(insertBefore)
  }
}

写入逻辑中的 if-else-if 使用 WHEN…THEN…ELSE;各分支互斥(首个匹配项生效)。2025.06 之前的版本不支持。

动态关系类型 [2025.x]
// Create/match/merge with dynamic rel type (must resolve to exactly one STRING)
CYPHER 25 CREATE (a:Node)-[:$($relType)]->(b:Node)
CYPHER 25 MATCH  (a:Node)-[:$($relType)]->(b:Node) RETURN a.name, b.name
字符串插值 [2026.08, Cypher 25]
CYPHER 25
MATCH (p:Person {id: $id})
RETURN s"Hello, {p.name}, age {p.age}" AS greeting   // S"..." and s'...' equivalent
  • 每个 {expr} 都会通过 toString() 转换
  • 不支持 MAP、LIST、NODE、PATH、RELATIONSHIP
  • 使用 \{ 和 \} 转义字面大括号
  • 插值字符串可以嵌套
  • 绝不要将不受信任的值插入传递给 apoc.cypher.run*() 的 Cypher 文本;请改用 $parameters
UUID 类型 [2026.08, Cypher 25]
CYPHER 25
CREATE (sess:Session {sessionId: uuid()});            // random UUID value

CYPHER 25
MATCH (sess:Session {sessionId: uuid($uuidString)})   // STRING 8-4-4-4-12 → UUID
RETURN toString(sess.sessionId) AS sessionId, uuid.mostSignificantBits(sess.sessionId) AS msb

UUID 属性需要 Neo4j 2026.08 或更高版本。较旧的驱动程序可能会返回占位 MAP,并附带警告 03N95 Neo.ClientNotification.UnknownType — 请查看对应驱动程序的技能文档,确认具体支持情况(neo4j-driver-python-skill 需要 >= 6.3);否则请继续使用 randomUUID() 生成 STRING ID。

空间/Point
// WGS84 geographic point
SET n.coords = point({longitude: $lon, latitude: $lat})

// Distance in metres; requires POINT index for performance
MATCH (a:Place {name: $origin}) MATCH (b:Place)
RETURN b.name, point.distance(a.coords, b.coords) AS distM
ORDER BY distM LIMIT 10

// Bounding-box pre-filter (uses POINT index) then distance
MATCH (b:Place)
WHERE point.withinBBox(b.coords,
        point({longitude: $west, latitude: $south}),
        point({longitude: $east, latitude: $north}))
RETURN b.name, point.distance(b.coords, $origin) AS distM

创建 POINT 索引:CREATE POINT INDEX name IF NOT EXISTS FOR (n:Place) ON (n.coords)

聚合分组键

RETURN/WITH 中的非聚合表达式是隐式分组键——GROUP BY 是可选的:

// actor + director are grouping keys; count(*) is the aggregate
MATCH (a:Person)-[:ACTED_IN]->(m:Movie)<-[:DIRECTED]-(d:Person)
RETURN a.name, d.name, count(*) AS collaborations
ORDER BY collaborations DESC

WITH/RETURN 上的显式 GROUP BY 子句 [2026.07,Cypher 25] 可明确指定分组键——这是与 GQL 对齐的隐式分组替代方案;隐式分组仍然有效:

MATCH (a:Person)-[:ACTED_IN]->(m:Movie)<-[:DIRECTED]-(d:Person)
RETURN a.name, d.name, count(*) AS collaborations GROUP BY a.name, d.name
ORDER BY collaborations DESC

GROUP BY () = 无分组键(一行);GROUP BY ALL = 每个非聚合返回项都是一个键。未包含在投影中的分组键不会返回。规则 → references/cypher-syntax.md。

count(n) 统计非空值;count(*) 统计行数,包括空值。collect(DISTINCT expr) 会去重。 count() 比 size(collect()) 快——count() 读取内部存储;collect() 会先构建列表。

引用比变量或 var.prop 更复杂的投影项的 ORDER BY/WHERE 子句表达式已弃用 [2026.07]——请在投影中为表达式指定别名,并按别名排序。对遮蔽传入变量的名称也同样如此。现在,如果投影子句已执行聚合,ORDER BY/WHERE 可以调用投影列表中不存在的聚合函数。


常见语法陷阱(查询出错的主要原因)

错误正确
ORDER BY n.prop AS x DESCORDER BY n.prop DESC
聚合后的 RETURN 中使用 ORDER BY preAggVar使用 RETURN 别名
count(r WHERE r.x=5)sum(CASE WHEN r.x=5 THEN 1 ELSE 0 END)
UNWIND list AS x WHERE x>5UNWIND list AS x WITH x WHERE x>5
least(a,b) / greatest(a,b)CASE WHEN a<b THEN a ELSE b END
-- comment// comment
shortestPath((a)-[*]->(b))(仍有效)优先使用 SHORTEST 1 (a)(()-[]->()){1,}(b)
id(n)elementId(n)
[:REL*1..5](仍有效)优先使用 (()-[:REL]->()){1,5}
CALL { WITH x ... }CALL (x) { ... }
COLLECT { (a)-[:R]->(b) }COLLECT { MATCH ... RETURN b }
SET n = {k:v} 部分更新SET n += {k:v}
对存在关系的节点使用 DELETE nDETACH DELETE n
WHERE n.x = nullWHERE n.x IS NULL
toInteger(null) 会抛出错误toIntegerOrNull(null)
n.$key 动态属性n[$key]
SET n:$labelSET n:$($label)
ZONED DATETIME >= date(...) → 0 行使用 datetime(...) 或 .year 访问器
带 Z 后缀的 ISO 字符串以 UTC 格式存储/比较Neo4j 中 Z ≠ UTC——Z 会被解析为偏移量,而非 UTC 时区;规划器和范围索引对二者的处理不同。请显式转换:datetime({datetime: datetime('2025-09-10T03:43:00Z'), timezone: 'UTC'})(neo4j#13519)
FOREACH ... RETURNUNWIND ... RETURN

完整的陷阱表 → references/syntax-traps.md


输出模式与写入门禁

默认使用参数化查询。返回命名属性,而不是完整节点或 RETURN *。

// RIGHT: agent gets named fields it can reason over
CYPHER 25 MATCH (n:Organization {name: $name}) RETURN n.name, n.founded, n.industry LIMIT 10

// WRONG: full node object wastes tokens, leaks all properties, agent can't extract fields cleanly
CYPHER 25 MATCH (n:Organization {name: $name}) RETURN n LIMIT 10

例外:模式/诊断查询(CALL db.schema.visualization()、SHOW INDEXES YIELD *、EXPLAIN),这类查询的重点就是对象本身。

验证工作流:

  1. 任何写入操作前先运行 EXPLAIN——捕获语法错误和缺失的索引
  2. 新的读取查询:先使用 LIMIT 1 测试
  3. 写入:先将读取部分作为 RETURN 验证,再替换为 SET/CREATE/DELETE
  4. 使用 PROFILE 测量数据库访问次数;检查是否有 AllNodesScan、CartesianProduct、Eager

Query API v2(无需驱动——可用于模式检查、EXPLAIN、读取和写入):

curl -X POST https://<instance>.databases.neo4j.io/db/<database>/query/v2 \
  -u <user>:<password> -H "Content-Type: application/json" \
  -d '{"statement": "EXPLAIN MATCH (n:Person {name: $name}) RETURN n", "parameters": {"name": "Alice"}}'
# Local: http://localhost:7474/db/<database>/query/v2
# Response: {"data": {"fields": [...], "values": [...]}}  — prefix EXPLAIN to plan without executing

写入执行门禁——仅在 Agent 执行时适用(MCP/cypher-shell/HTTP),不适用于生成供代码/脚本/用户运行的内容:

  1. 运行 EXPLAIN → 报告预计受影响的行数
  2. 等待用户确认后再执行

版本门槛

版本未知时,默认使用兼容 2025.01 的功能。

功能最低版本回退方案
CYPHER 25、QPE、CALL (x) {}2025.01要求使用 2025+
匹配模式(DIFFERENT RELATIONSHIPS、REPEATABLE ELEMENTS)2025.01要求使用 2025+
动态标签 $($expr)、coll.sort()2025.01使用 APOC 或在应用端处理
CONCURRENT TRANSACTIONS、REPORT STATUS2025.01删除/省略
SEARCH 子句 — VECTOR INDEX2026.01使用 CALL db.index.vector.queryNodes(...)(已于 2026.04 弃用)
SEARCH 子句 — FULLTEXT INDEX(WITH ANALYZER、SKIP/OFFSET)2026.09使用 CALL db.index.fulltext.queryNodes(...)/queryRelationships(...)
ACYCLIC 路径模式(路径中不重复节点)2026.03使用 size(nodes(p)) = size(apoc.coll.toSet(nodes(p))) 进行后置筛选
string.indexOf()、string.join()、string.regexReplace()2026.05使用 apoc.text.* 或在应用端处理
GQL 别名:FOR=UNWIND、PROPERTY_EXISTS=IS NOT NULL、IS [NOT] LABELED=n:Label;函数别名(local_time、zoned_datetime、duration_between、collect_list 等)2026.02–04仅用于符合 GQL 标准的场景——使用 Cypher 等效写法;完整列表 → 参考/cypher-syntax.md
GRAPH TYPE 架构 DDL(ALTER CURRENT GRAPH TYPE SET/ADD/ALTER/DROP、SHOW CURRENT GRAPH TYPE)2026.02(预览版),2026.06 正式发布使用单独的 CREATE CONSTRAINT/CREATE INDEX
WITH/RETURN 上的 GROUP BY 子句(显式分组键,符合 GQL 标准)2026.07使用隐式分组——在投影中列出非聚合表达式
cardinality() — MAP 中的键、LIST 中的元素、PATH 中的节点和关系2026.07对 LIST/MAP 键使用 size(),对 PATH 使用 length()
ORDER BY/WHERE 中不属于投影项的聚合函数(仅聚合投影)2026.07将聚合结果作为别名投影,然后按该别名排序/筛选
对 system 数据库的过程调用中,YIELD 后的 WHERE2026.07使用 YIELD + RETURN,在客户端筛选
字符串插值 s"...{expr}..."/S"…"2026.08使用 + 与 toString() 拼接,或使用 string.join()
UUID 类型;uuid()、uuid(name)、uuid(mostSigBits, leastSigBits)、uuid.mostSignificantBits()、uuid.leastSignificantBits()2026.08使用 randomUUID() 字符串属性
null / 0 返回 null,而不是引发除零错误2026.08使用 CASE WHEN d = 0 THEN null ELSE n / d END
Map 推导 {k: v IN map | keyExpr: valueExpr}2026.09使用 apoc.map.fromPairs([k IN keys(m) | [k, m[k]]])
对 LIST、MAP、NODE、RELATIONSHIP、PATH 使用 toString()、toStringList()、toStringOrNull()2026.09分别转换标量组件,然后使用 string.join()
Map 相加 map1 + map2(合并 Map)2026.10(Aura 2026 年 10 月)使用 apoc.map.merge(map1, map2)

性能

EXPLAIN/PROFILE 红旗:AllNodesScan CartesianProduct NodeByLabelScan Eager

修复 Eager — 三种方法(选择最简单且有效的方法):

  1. 为节点添加特定标签,消除读写歧义: 写入 :City 节点时,使用 MATCH (x:CallingPoint),而不是不带标签的 MATCH (x)
  2. 先收集,再写入:WITH collect(u) AS users UNWIND users AS u ...
  3. CALL IN TRANSACTIONS:将每个批次隔离在各自的事务中

标签推断 — 当规划器低估多标签查询的选择性时:[Neo4j 5]

CYPHER inferSchemaParts = most_selective_label
MATCH (admin:Administrator {name: $name}), (resource:Resource {name: $res})
MATCH p=(admin)-[:MEMBER_OF]->()-[:ALLOWED_INHERIT]->(company)
RETURN count(p)

索引要点:每个对属性执行的 MATCH/MERGE/WHERE,都需要在查找属性上建立索引,否则 Neo4j 会扫描所有节点。只有节点带有标签时,索引才会生效 — MATCH (n {prop: $v}) 永远不会使用索引;MATCH (n:Label {prop: $v}) 则会使用。没有约束的 MERGE 不保证原子性(两个并发的 MERGE 可能创建重复项)。CONTAINS/ENDS WITH → TEXT 索引(RANGE 不支持这些操作)。当 EXPLAIN 显示扫描时,使用 USING INDEX n:Label(prop) 强制指定执行计划。 对嵌套数据使用链式 OPTIONAL MATCH → 替换为 COLLECT { MATCH ... RETURN }。 动态标签($($label))→ AllNodesScan+Filter;尽可能使用静态标签。

完整反模式 → references/performance.md


故障恢复

  • 结果为 0:检查参数类型,逐个移除 WHERE 谓词,并通过 EXPLAIN 检查是否使用索引
  • TypeErrors:使用 toIntegerOrNull()/toFloatOrNull();通过 IS NOT NULL 进行保护
  • 变量超出作用域:未列在 WITH 中 → 使用 count(*),而不是 count(droppedVar)
  • 超时:修复 AllNodesScan → 提前添加 LIMIT → CALL IN TRANSACTIONS OF 1000 ROWS
  • 长时间运行的查询进度 [2026.03]:SHOW TRANSACTIONS YIELD currentQuery, status, currentQueryProgress
  • DateTime 不匹配:ZONED DATETIME >= date(...) → 0 行;使用 datetime() 或 .year
  • Z 后缀 ≠ UTC 时区:带 Z 的 ISO 字符串会存储为 UTC 偏移量,而不是 UTC 时区 — 对存储值中混用 Z 和 UTC 的范围查询会返回 0 行。写入时进行转换:datetime({datetime: datetime($isoStr), timezone: 'UTC'})
  • Duration:duration.between(d1,d2).days = 天数分量(1 月 1 日 → 3 月 15 日:14),而非总天数。总天数:duration.inDays(d1,d2).days(73);inMonths、inSeconds 同理。.inDays 不是 duration 值的访问器
  • Cannot merge node using null property value:MERGE 键解析为 null — 先验证参数
  • IndexNotFoundError:SHOW INDEXES YIELD name, state WHERE state <> 'ONLINE'

参考资料

按需加载:

  • references/indexes.md — 索引类型(RANGE/TEXT/FULLTEXT/POINT/COMPOSITE/LOOKUP)、约束、MERGE 锁语义、全文 Lucene 语法、导入前检查
  • references/cypher-syntax.md — 完整语法参考:WITH、DELETE、ORDER BY、CASE、null、列表、字符串、日期、空间/点、LOAD CSV、子查询、QPE、动态标签、SEARCH(向量 [2026.01]、全文 [2026.09]);条件 CALL(WHEN/THEN/ELSE);标签模式表达式;allReduce;NEXT 子句;紧凑型 CASE WHEN;normalize();字符串插值;UUID 类型和 uuid() 函数 [2026.08];映射推导式 [2026.09];索引/约束类型表;附带引入版本的函数
  • references/syntax-traps.md — 40 多种语法陷阱一览表
  • references/performance.md — 反模式、文本索引与全文索引、Eager(3 种修复策略)、标签推断、批处理最佳实践、并行运行时
  • references/advanced-patterns.md — REPEATABLE ELEMENTS 模式、allReduce 有状态遍历、多站点 QPE、路线规划模拟、DAG 关键路径、时序欺诈检测组件图、环检测、OPTIONAL CALL
  • references/apoc.md — APOC Core:重构、虚拟图、合并辅助工具、路径扩展器、触发器、集合、条件执行
  • references/graph-type.md — GRAPH TYPE DDL(GA 2026.06):ALTER CURRENT GRAPH TYPE SET/ADD/ALTER/DROP、SHOW CURRENT GRAPH TYPE [AS GRAPH]、元素类型语法、属性类型、约束、标签蕴含、关系类型强制、所需权限

WebFetch

需求URL
子句语义https://neo4j.com/docs/cypher-manual/25/clauses/{clause}/
函数签名https://neo4j.com/docs/cypher-manual/25/functions/{type}/
QPE / 路径https://neo4j.com/docs/cypher-manual/25/patterns/
空间/点函数https://neo4j.com/docs/cypher-manual/25/functions/spatial/
索引/约束参考https://neo4j.com/docs/cypher-manual/25/indexes/
完整速查表https://neo4j.com/docs/cypher-cheat-sheet/25/all/

检查清单

  • 已检查 Schema,或已确认上下文中的 Schema
  • 每个顶层查询都带有 CYPHER 25 前缀
  • 使用 $parameters(而非字面量)
  • 对探索性读取使用 LIMIT(默认值为 25)
  • 已运行 EXPLAIN;已解决警示项
  • 写入部分已先以 RETURN 验证,再执行
  • 如果 Agent 正在执行(而非生成),已启用写入执行门控
  • MERGE 仅用于受约束的键
  • 不使用无标签的 MATCH (n)
  • Schema 操作不在显式事务中执行

评论

支持 Markdown