用途
本技能面向使用 Neo4j JavaScript/TypeScript Driver v6 编写代码的场景,包括在 Node.js 或浏览器中连接 Neo4j、设置 driver 与会话、执行查询与事务、调试 Integer 处理、结果消费、会话泄漏与异步错误,以及为驱动对象添加 TypeScript 类型标注。
当需要编写或优化 Cypher 时应使用 neo4j-cypher-skill;升级驱动版本应使用 neo4j-migration-skill;RxJS 会话 API 参见 references/rxjs-session.md。
安装与环境变量
安装命令:
npm install neo4j-driver # or: yarn add neo4j-driver
连接配置应从环境变量读取,不要硬编码凭据。示例 .env 文件需加入 .gitignore:
NEO4J_URI=neo4j+s://xxx.databases.neo4j.io
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=secret
NEO4J_DATABASE=neo4j
在 Node.js < 20 或关闭 .env 自动加载时需安装 dotenv;Node 20+ 可通过 --env-file .env 原生加载,Next.js / Vite 会自动加载 .env,无需 dotenv。
驱动生命周期
应在启动时创建一个 driver 实例并全局共享,切勿按请求创建。可使用 CommonJS 或 ESM/TypeScript 引入方式。驱动提供以下 URI 方案:neo4j+s://(TLS + 集群路由,用于 Aura 与生产集群)、neo4j://(明文 + 集群路由,本地开发集群)、bolt+s://(TLS 单实例)、bolt://(明文单实例)。
认证方式包括:neo4j.auth.basic(user, password)、neo4j.auth.bearer(token)(SSO / JWT)、neo4j.auth.kerberos(base64Ticket)、neo4j.auth.none()(仅开发)。
在 Web 框架中可使用单例:创建一次并到处导入。Serverless(Lambda/Vercel/Workers)环境下应保持 maxConnectionPoolSize: 5,且不保证 SIGTERM。
启动时应调用 await driver.verifyConnectivity() 快速失败;关闭时调用 await driver.close()。
选择合适的 API
- driver.executeQuery():多数查询的默认选择,自动重试,结果为 eager(全部记录)。
- session.executeRead/Write():适用于大结果、流式、多查询事务,自动重试,结果惰性流式。
- session.run():适用于 LOAD CSV、CALL IN TRANSACTIONS、脚本,不自动重试,惰性流式。
使用 executeQuery 时示例返回 { records, summary, keys },遍历记录须使用 record.get('name')。写入时 summary.counters.updates().nodesCreated 必须调用 .updates()。始终指定 database,否则会产生额外往返。禁止使用模板字符串拼接 Cypher,应使用 $param 参数化。
托管事务
托管事务(executeRead / executeWrite)在瞬时故障时自动重试。必须在回调内部消费记录,回调返回后流即关闭。await tx.run() 返回的是流句柄而非记录,需在回调内 await result.collect() 或使用 for-await 流式消费。回调可能执行多次(瞬时失败重试),因此不应有副作用;副作用应放在确认提交之后。
会话关闭
session.close() 必须放在 finally 中保证执行,避免 executeRead 拒绝时导致会话泄漏。promise 链中等价写法为 .then().catch().finally(() => session.close())。
Integer 处理
Neo4j 整数为 64 位,JS Number 为 IEEE 754(安全至 2^53−1)。驱动默认返回自定义 Integer 类型。三种模式:默认 Integer 类(对所有值安全,需转换);disableLosslessIntegers: true(原生 JS number,仅安全范围内);useBigInt: true(精确但破坏 JSON.stringify)。
使用 Integer 类时可通过 neo4j.isInt、neo4j.integer.inSafeRange 检查,调用 toNumber()(仅安全范围内)、toString()(始终安全)、toBigInt()。发送整数参数需使用 neo4j.int(30),否则普通 JS number 会作为 FLOAT 发送。JSON 序列化前需转换 Integer(toNumber)和 temporal 类型(toString),否则会得到 {low, high} 对象或空对象,BigInt 会抛出 TypeError。
记录访问与错误处理
记录不是普通对象,须使用 record.get('name') 或 record.get(0),record.name 与 record['name'] 均无效;record.keys、record.has、record.toObject() 可用,但 toObject 的值仍是驱动类型,非 JSON 安全。
错误处理可导入 Neo4jError、SERVICE_UNAVAILABLE、SESSION_EXPIRED,通过 err instanceof Neo4jError 判断,检查 err.code(如约束校验失败、服务不可用、会话过期)与 err.retriable。executeQuery 与 executeRead/Write 会自动重试可重试错误,session.run 不会。
TypeScript 与批量写入
可从 neo4j-driver 导入 Driver、Session、ManagedTransaction、Record、Node、Integer 等类型。Integer 泛型会随 disableLosslessIntegers 改变。批量写入应使用 UNWIND 在单个事务中完成,而非逐条事务;UNWIND 数组中的数字字段需为普通 JS number,不能使用 neo4j.int()。
常见错误与清单
常见错误包括:模板字符串拼接 Cypher、使用 record.name、对 Integer 直接 JSON.stringify、对 temporal 直接 JSON.stringify、summary.counters.nodesCreated、省略 database、从 tx 回调返回 result、.then(() => session.close())、在 tx 回调中产生副作用、按请求新建 driver、在浏览器使用 bolt:// 或 neo4j://、在 UNWIND 数组中使用 Integer、Serverless 中 maxConnectionPoolSize: 100。
清单要点:启动时创建单一 driver 实例并共享;每个查询/会话指定 database;启动时调用 verifyConnectivity;session.close() 置于 finally;使用 .get() 访问记录;JSON 序列化前转换 Integer 与 temporal;访问计数前调用 summary.counters.updates();使用 $param 而非拼接;tx 回调返回普通数据且副作用在回调外;写入整数参数使用 neo4j.int();读用 executeRead、写用 executeWrite;浏览器使用 neo4j+s://(WebSocket)。
参考文档
按需加载 references/data-types.md(类型映射、temporal、图类型、空间类型、neo4j.UUID [6.2+]、toNative())、references/advanced-patterns.md(显式事务、因果一致性/bookmarks、连接池调优、结果转换器、惰性流、仓储模式)、references/browser-usage.md(WebSocket URI、CORS、打包配置、安全指引)、references/rxjs-session.md(RxJS 会话 API)。