关于 neo4j-cypher-skill
neo4j-cypher-skill 是面向 Neo4j 用户的 Cypher 编写、优化与调试技能,涵盖查询模式和语法注意事项。它强调先依据真实 Schema 构造和校验查询,避免猜测标签、关系类型或属性。
主要功能
- 01编写与调试 Cypher 查询
- 02依据 Schema 检查标签和属性
- 03提供路径匹配与子查询模式
- 04指导批量写入和查询优化
- 05涵盖向量与全文搜索语法
适用场景
- 01构造图模式匹配查询
- 02排查 Cypher 查询错误
- 03编写路径遍历或子查询
- 04准备 CSV 批量写入操作
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ neo4j-contrib/ neo4j-skills --skill neo4j-cypher-skill安装后在 Claude Code 中输入/neo4j-cypher-skill确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdreferences/advanced-patterns.mdapoc.mdcypher-syntax.mdgraph-type.mdindexes.mdperformance.mdschema-guardrail.mdsyntax-traps.mdscripts/define_schema.pygenerate_schema.pyimport_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>)
绝不填入猜测的名称 — 看似合理的猜测很容易被直接照搬。
默认规则 — 每个查询均适用
CYPHER 25— 必须是第一个令牌;在UNION之后或子查询内绝不重复- Schema 优先 — 编写前先检查;如果提示词中提供了 Schema,直接使用
- 只对有约束的键使用
MERGE;关系的MERGE只能用于已绑定的端点 - 禁止使用无标签的
MATCH (n),除非n已绑定,或后面跟有WHERE n:$($label) - 所有探索性读取默认使用
LIMIT 25;在高基数操作(可变长度遍历、扇出 MATCH、笛卡尔积)之前使用WITH n LIMIT - 注释:只能使用
//—--是 SQL 语法,无效 REPEATABLE ELEMENTS/DIFFERENT RELATIONSHIPS放在MATCH后,而不是模式末尾SHOW命令:WHERE前必须有YIELD;可与通用 Cypher 子句组合,包括UNION/RETURN[2026.05] —SHOW DATABASES仍要求使用 system 数据库(使用USE system)。在system数据库上使用CALL:先YIELD,再WHERE[2026.07]- 内联节点谓词
(:Label WHERE p=x)— 仅在MATCH中有效 - 裸
UNWIND后不能跟WHERE— 使用WITH x WHERE (a)-[:R]-(b)— 无向匹配会覆盖两个方向,造成重复计数;除非方向未知,否则使用有向匹配DETACH DELETE— 如果节点有关联关系,普通DELETE会报错
风格
| 元素 | 约定 |
|---|---|
| 节点标签 | PascalCase :Person |
| 关系类型 | SCREAMING_SNAKE_CASE :KNOWS |
| 属性/变量 | camelCase firstName |
| 子句 | 大写 MATCH |
| 布尔值/空值 | 小写 true false null |
| 字符串 | 使用单引号;仅在包含 ' 时使用双引号 |
Schema 才是准则。示例中的
:Person、:KNOWS、name仅用于说明 — 请替换为 Schema 中的实际名称。
协议优先使用 Schema
优先级顺序:
-
项目中任意位置存在
<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)。 -
上下文中已有 Schema → 使用该 Schema,跳过检查。
-
缺少 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 DESC | ORDER 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>5 | UNWIND 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 n | DETACH DELETE n |
WHERE n.x = null | WHERE n.x IS NULL |
toInteger(null) 会抛出错误 | toIntegerOrNull(null) |
n.$key 动态属性 | n[$key] |
SET n:$label | SET 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 ... RETURN | UNWIND ... 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),这类查询的重点就是对象本身。
验证工作流:
- 任何写入操作前先运行
EXPLAIN——捕获语法错误和缺失的索引 - 新的读取查询:先使用
LIMIT 1测试 - 写入:先将读取部分作为
RETURN验证,再替换为SET/CREATE/DELETE - 使用
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),不适用于生成供代码/脚本/用户运行的内容:
- 运行
EXPLAIN→ 报告预计受影响的行数 - 等待用户确认后再执行
版本门槛
版本未知时,默认使用兼容 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 STATUS | 2025.01 | 删除/省略 |
SEARCH 子句 — VECTOR INDEX | 2026.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 后的 WHERE | 2026.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 — 三种方法(选择最简单且有效的方法):
- 为节点添加特定标签,消除读写歧义:
写入
:City节点时,使用MATCH (x:CallingPoint),而不是不带标签的MATCH (x) - 先收集,再写入:
WITH collect(u) AS users UNWIND users AS u ... - 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 操作不在显式事务中执行