数据类型和 Cypher 类型映射
本节中的表格显示了 Cypher 数据类型和 JavaScript 类型之间的映射。
核心类型
Cypher 类型 | JavaScript 类型 |
---|---|
|
|
LIST |
|
MAP |
|
BOOLEAN |
|
INTEGER |
|
FLOAT |
|
STRING |
|
ByteArray |
|
Integer 不是 JavaScript 的原生类型之一,而是一个自定义类型,用于适应 Cypher 的精度。在实例化驱动程序时,您可以通过 disableLosslessIntegers 配置项 禁用此功能,以便使用 JavaScript 的原生 Number 类型。请注意,这可能导致精度损失。 |
时间类型
时间数据类型符合 ISO-8601 标准。要将其序列化为字符串,请使用 .toString()
方法。时间对象是不可变的。
亚秒级值以纳秒精度测量。要转换驱动程序和原生类型,请使用 .fromStandardDate()
和 .toStandardDate()
方法(不适用于 Duration
)。由于 JavaScript 日期类型不支持纳秒,因此 .fromStandardDate()
允许使用纳秒参数(可选),而 .toStandardDate()
会删除纳秒。
有关时区缩写的列表,请参阅 时区数据库时区列表。
Cypher 类型 | JavaScript 类型 |
---|---|
DATE |
|
ZONED TIME |
|
LOCAL TIME |
|
ZONED DATETIME |
|
LOCAL DATETIME |
|
DURATION |
const neo4j = require('neo4j-driver');
const URI = '<URI for Neo4j database>';
const USER = '<Username>';
const PASSWORD = '<Password>';
(async () => {
const driver = neo4j.driver(URI, neo4j.auth.basic(USER, PASSWORD))
const friendsSince = new neo4j.types.DateTime(1999, 11, 23, 7, 47, 0, 4123, -4*3600, 'Europe/Berlin')
// JS native types work as well.
// They don't support the full feature-set of Neo4j's type though.
// let jsFriendsSince = new Date(1999, 11, 23, 7, 47, 0)
// jsFriendsSince = new neo4j.types.Date.fromStandardDate(jsFriendsSince)
// Create a friendship with the given DateTime, and return the DateTime
const result = await driver.executeQuery(`
MERGE (a:Person {name: $name})
MERGE (b:Person {name: $friend})
MERGE (a)-[friendship:KNOWS]->(b)
SET friendship.since = $friendsSince
RETURN friendship.since
`, {
name: 'Alice', friend: 'Bob',
friendsSince: friendsSince // or friendsSince: jsFriendsSince
}
)
const outDateTime = result.records[0].get('friendship.since')
console.log(outDateTime)
/*
DateTime {
year: Integer { low: 1999, high: 0 },
month: Integer { low: 11, high: 0 },
day: Integer { low: 23, high: 0 },
hour: Integer { low: 6, high: 0 },
minute: Integer { low: 47, high: 0 },
second: Integer { low: 0, high: 0 },
nanosecond: Integer { low: 4123, high: 0 },
timeZoneOffsetSeconds: Integer { low: -18000, high: -1 },
timeZoneId: 'Europe/Berlin'
}
*/
// Convert DateTime to JS native Date (lossy)
const jsOutDateTime = outDateTime.toStandardDate()
console.log(jsOutDateTime)
// 1999-11-23T11:47:00.000Z
await driver.close()
})()
Date
表示捕获日期的瞬间,但不捕获时间或时区。
d = new neo4j.Date(2021, 11, 2)
// Date { year: 2021, month: 11, day: 2 }
d.toString() // '2021-11-02'
有关完整文档,请参阅 API 文档 - Date。
Time
表示捕获时间和时区偏移量(以秒为单位)的瞬间,但不捕获日期。
d = new neo4j.Time(7, 47, 0, 4123, -4*3600)
/*
Time {
hour: 7,
minute: 47,
second: 0,
nanosecond: 4123,
timeZoneOffsetSeconds: -14400
}
*/
d.toString() // '07:47:00.000004123-04:00'
有关完整文档,请参阅 API 文档 - Time。
LocalTime
表示捕获一天中的时间的瞬间,但不捕获日期或时区。
d = new neo4j.LocalTime(7, 47, 0, 4123)
// LocalTime { hour: 7, minute: 47, second: 0, nanosecond: 4123 }
d.toString() // '07:47:00.000004123'
有关完整文档,请参阅 API 文档 - LocalTime。
DateTime
表示捕获日期、时间和时区标识符的瞬间。时区参数(偏移量和标识符)是可选的。
d = new neo4j.DateTime(2021, 11, 2, 7, 47, 0, 4123, -4*3600, 'Europe/Berlin')
/*
DateTime {
year: 2021,
month: 11,
day: 2,
hour: 7,
minute: 47,
second: 0,
nanosecond: 4123,
timeZoneOffsetSeconds: -14400,
timeZoneId: 'Europe/Berlin'
}
*/
d.toString() // '2021-11-02T07:47:00.000004123-04:00[US/Eastern]'
有关完整文档,请参阅 API 文档 - DateTime。
LocalDateTime
表示捕获日期和时间的瞬间,但不捕获时区。
d = new neo4j.LocalDateTime(2021, 11, 2, 7, 47, 0, 4123)
/*
LocalDateTime {
year: 2021,
month: 11,
day: 2,
hour: 7,
minute: 47,
second: 0,
nanosecond: 4123
}
*/
d.toString() // '2021-11-02T07:47:00.000004123'
有关完整文档,请参阅 API 文档 - LocalDateTime。
Duration
表示两个时间点之间的差异。
const d = new neo4j.Duration(1, 2, 3, 4)
/*
Duration {
months: 1,
days: 2,
seconds: Integer { low: 3, high: 0 },
nanoseconds: Integer { low: 4, high: 0 }
}
*/
d.toString() // 'P1M2DT3.000000004S'
有关完整文档,请参阅 API 文档 - Duration。
空间类型
Cypher 支持空间值(点),Neo4j 可以将这些点值存储为节点和关系上的属性。
驱动程序具有单个类型 neo4j.types.Point
,它可以充当 2D/3D 笛卡尔/WGS-84 点,具体取决于初始化它的 SRID
。SRID
(空间参考标识符的缩写)是识别要解释点的坐标系的数字。您可以将其视为每个空间类型的唯一标识符。
SRID | 描述 |
---|---|
|
笛卡尔空间中的 2D 点。 |
|
笛卡尔空间中的 3D 点。 |
|
WGS84 空间中的 2D 点。 |
|
WGS84 空间中的 3D 点。 |
// A 2D Point in cartesian space
const point2d = new neo4j.types.Point(
7203, // SRID
1, // x
5.1 // y
)
// Point { srid: 4979, x: 1, y: -2 }
// A 3D Point in cartesian space
const point3d = new neo4j.types.Point(
9157, // SRID
1, // x
-2, // y
3.1 // z
)
// Point { srid: 4979, x: 1, y: -2, z: 3.1 }
// A 2D point in WGS-84 space
const point2d = new neo4j.types.Point(
4326, // SRID
1, // x
-2, // y
3.1 // z
)
// Point { srid: 4979, x: 1, y: -2}
// A 3D point in WGS-84 space
const point3d = new neo4j.types.Point(
4979, // SRID
1, // x
-2, // y
3.1 // z
)
// Point { srid: 4979, x: 1, y: -2, z: 3.1 }
有关完整文档,请参阅 API 文档 - Point。
图类型
图类型仅作为结果传递,不能用作参数.
Cypher 类型 | JavaScript 类型 |
---|---|
NODE |
|
RELATIONSHIP |
|
PATH |
|
Node
表示图中的节点。
属性 elementId
提供实体的标识符。应谨慎使用此属性,因为不保证在单个事务范围之外的 id 值和元素之间的映射。换句话说,跨不同事务使用 elementId
来 MATCH
元素是有风险的。
const neo4j = require('neo4j-driver');
const URI = '<URI for Neo4j database>';
const USER = '<Username>';
const PASSWORD = '<Password>';
(async () => {
const driver = neo4j.driver(URI, neo4j.auth.basic(USER, PASSWORD))
const result = await driver.executeQuery(
'MERGE (p:Person {name: $name}) RETURN p AS person',
{ name: 'Alice' }
)
const node = result.records[0].get('person')
console.log(node)
/*
Node {
identity: Integer { low: 393, high: 0 }, // deprecated
labels: [ 'Person' ],
properties: { name: 'Alice' },
elementId: '4:d6154461-ff34-42a9-b7c3-d32673913419:393'
}
*/
await driver.close()
})()
有关完整文档,请参阅 API 文档 - Node。
Relationship
表示图中的关系。
属性 elementId
提供实体的标识符。应谨慎使用此属性,因为不保证在单个事务范围之外的 id 值和元素之间的映射。startNodeElementId
和 endNodeElementId
同样适用。
const neo4j = require('neo4j-driver');
const URI = '<URI for Neo4j database>';
const USER = '<Username>';
const PASSWORD = '<Password>';
(async () => {
const driver = neo4j.driver(URI, neo4j.auth.basic(USER, PASSWORD))
const result = await driver.executeQuery(`
MERGE (p:Person {name: $name})
MERGE (friend:Person {name: $friend_name})
MERGE (p)-[r:KNOWS]->(friend)
SET r.status = $status, r.since = date()
RETURN r AS friendship
`, {
name: 'Alice', status: 'BFF', friend_name: 'Bob'
}
)
const relationship = result.records[0].get('friendship')
console.log(relationship)
/*
Relationship {
identity: Integer { low: 388, high: 0 }, // deprecated
start: Integer { low: 393, high: 0 }, // deprecated
end: Integer { low: 394, high: 0 }, // deprecated
type: 'KNOWS',
properties: {
since: Date { year: [Integer], month: [Integer], day: [Integer] },
status: 'BFF'
},
elementId: '5:d6154461-ff34-42a9-b7c3-d32673913419:388',
startNodeElementId: '4:d6154461-ff34-42a9-b7c3-d32673913419:393',
endNodeElementId: '4:d6154461-ff34-42a9-b7c3-d32673913419:394'
}
*/
await driver.close()
})()
有关完整文档,请参阅 API 文档 - Relationship。
Path、PathSegment
Path
表示图中的路径,而 PathSegment
表示其各个链接。
const neo4j = require('neo4j-driver');
const URI = '<URI for Neo4j database>';
const USER = '<Username>';
const PASSWORD = '<Password>';
(async () => {
const driver = neo4j.driver(URI, neo4j.auth.basic(USER, PASSWORD))
// Create some :Person nodes linked by :KNOWS relationships
await addFriend(driver, 'Alice', 'BFF', 'Bob')
await addFriend(driver, 'Bob', 'Fiends', 'Sofia')
await addFriend(driver, 'Sofia', 'Acquaintances', 'Sara')
// Follow :KNOWS relationships outgoing from Alice three times, return as path
const result = await driver.executeQuery(`
MATCH p = (:Person {name: $name})-[:KNOWS*3]->(:Person)
RETURN p AS friendsChain
`, {
name: 'Alice'
}
)
const path = result.records[0].get('friendsChain')
console.log(path)
/*
Path {
start: Node {
identity: Integer { low: 393, high: 0 },
labels: [ 'Person' ],
properties: { name: 'Alice' },
elementId: '4:d6154461-ff34-42a9-b7c3-d32673913419:393'
},
end: Node {
identity: Integer { low: 396, high: 0 },
labels: [ 'Person' ],
properties: { name: 'Sara' },
elementId: '4:d6154461-ff34-42a9-b7c3-d32673913419:396'
},
segments: [
PathSegment {
start: [Node],
relationship: [Relationship],
end: [Node]
},
PathSegment {
start: [Node],
relationship: [Relationship],
end: [Node]
},
PathSegment {
start: [Node],
relationship: [Relationship],
end: [Node]
}
],
length: 3
}
*/
await driver.close()
})()
async function addFriend(driver, name, status, friendName) {
await driver.executeQuery(`
MERGE (p:Person {name: $name})
MERGE (friend:Person {name: $friendName})
MERGE (p)-[r:KNOWS]->(friend)
SET r.status = $status, r.since = date()
`, {
name: name, status: status, friendName: friendName
}
)
}
有关完整文档,请参阅 API 文档 - Path 和 PathSegment。
错误
驱动程序引发的所有错误都属于 Neo4jError
类型。有关服务器可以返回的错误列表,请参阅 状态码 页面。
某些服务器错误被标记为可以安全重试,无需更改原始请求。此类错误的示例包括死锁、内存问题或连接问题。所有驱动程序的异常类型都实现了 .isRetryable()
方法,该方法提供了有关进一步尝试是否可能成功的见解。这在 显式事务 中运行查询时特别有用,以便了解是否应再次运行失败的查询。
术语表
- LTS
-
长期支持版本是保证支持一定年限的版本。Neo4j 4.4 是 LTS 版本,Neo4j 5 也将有一个 LTS 版本。
- Aura
-
Aura 是 Neo4j 的完全托管云服务。它提供免费和付费计划。
- Cypher
-
Cypher 是 Neo4j 的图查询语言,可用于从数据库中检索数据。它类似于 SQL,但用于图。
- APOC
-
Awesome Procedures On Cypher (APOC) 是一个包含(许多)函数的库,这些函数在 Cypher 本身中难以表达。
- Bolt
-
Bolt 是 Neo4j 实例和驱动程序之间交互使用的协议。默认情况下,它监听端口 7687。
- ACID
-
原子性、一致性、隔离性和持久性 (ACID) 是保证数据库事务可靠处理的特性。符合 ACID 的 DBMS 确保数据库中的数据即使在出现故障时也能保持准确和一致。
- 最终一致性
-
如果数据库保证所有集群成员将在某个时间点存储数据的最新版本,则称该数据库最终一致。
- 因果一致性
-
如果每个集群成员都以相同的顺序查看读写查询,则数据库具有因果一致性。这比最终一致性更强。
- NULL
-
空标记不是一种类型,而是值不存在的占位符。有关更多信息,请参阅 Cypher → 使用
null
。 - 事务
-
事务是工作单元,要么完全提交,要么在失败时回滚。例如银行转账:它涉及多个步骤,但这些步骤必须全部成功或回退,以避免从一个账户中扣款但没有添加到另一个账户中。
- 背压
-
背压是一种对抗数据流动的力。它确保客户端不会被超出其处理能力的数据淹没。
- 事务函数
-
事务函数是由
executeRead
或executeWrite
调用执行的回调函数。如果服务器发生故障,驱动程序会自动重新执行回调函数。 - 驱动程序
-
一个
Driver
对象包含建立与 Neo4j 数据库连接所需的详细信息。