迁移到 7.0.0
这是 GraphQL Library 版本 7 的文档。有关长期支持 (LTS) 版本 5,请参阅GraphQL Library 版本 5 LTS。 |
此页面列出了 Neo4j GraphQL Library 从 6.x 版本到 7.x 版本的所有重大变更以及如何更新。
重大变更
以下是 6.0.0 版到 7.0.0 版的所有重大变更列表。
移除隐式过滤字段
隐式相等过滤字段已移除。请改用专用的 eq
字段
之前 | 之后 |
---|---|
|
|
excludeDeprecatedFields
的 implicitEqualFilters
选项已移除。
必需的 @node
指令
现在 @node
指令是必需的。没有 @node
指令的 GraphQL 对象类型不再被视为 Neo4j 节点表示。查询和变异只为带有 @node
指令的类型生成。
之前 | 之后 |
---|---|
|
|
移除已弃用的 options
参数
已移除已弃用的 options
参数。
考虑以下类型定义
type Movie @node {
title: String!
}
以下显示了选项的区别
之前 | 之后 |
---|---|
|
|
excludeDeprecatedFields
的 deprecatedOptionsArgument
选项已移除。
移除已弃用的 directed
参数
已从查询中移除已弃用的 directed
参数。此参数以前允许您在查询时指定关系是有向的还是无向的。请改用 @relationship
指令的 queryDirection
参数。
excludeDeprecatedFields
的 directedArgument
选项已移除。
变更 @relationship
的 queryDirection
参数接受的值
在移除 directed
参数后,@relationship
指令的 queryDirection
参数现在只接受两个可能的值
-
DIRECTED
(默认) -
UNDIRECTED
不再支持以下值
-
DEFAULT_DIRECTED
-
DEFAULT_UNDIRECTED
-
DIRECTED_ONLY
-
UNDIRECTED_ONLY
移除已弃用的 typename_IN
过滤器
已移除已弃用的 typename_IN
过滤器。请改用 typename
。
之前 | 之后 |
---|---|
|
|
excludeDeprecatedFields
的 typename_IN
选项已移除。
移除单元素关系
已移除单元素关系,改用列表关系
之前 | 之后 |
---|---|
|
|
单元素关系无法可靠地强制执行,可能导致数据与模式不一致。如果 GraphQL 模型需要一对一关系(例如在联邦中),现在可以使用 @cypher
指令来创建。
type Movie @node {
director: Person
@cypher(
statement: """
MATCH (this)-[:ACTED_IN]->(p:Person)
RETURN p
"""
columnName: "p"
)
}
移除 connect overwrite
参数
已在连接操作中移除 overwrite
参数。
在 7.0.0 版中,连接操作已简化为始终在节点之间创建新关系,无论关系是否已存在。请参阅连接操作现在支持相同节点之间的多个关系。
如果您必须更新现有关系而不是创建新关系,请使用 update
操作
mutation {
updateMovies(
update: {
actors: [
{
where: { node: { name: { eq: "Keanu" } } }
update: { edge: { role: { set: "Neo" } } }
}
]
}
) {
movies {
title
}
}
}
移除连接字段外部的聚合字段
已从模式中移除已弃用的聚合字段。请改用连接选择集内的聚合字段。
之前 | 之后 |
---|---|
|
|
已从 excludeDeprecatedFields
设置中移除 deprecatedAggregateOperations
选项。
订阅现在是选择加入的
不再为所有 @node
类型自动生成订阅。在 7.x 版本中,需要 @subscription
指令才能启用此功能。您现在必须通过以下两种方式之一明确启用订阅,使用 @subscription
指令
-
在模式级别启用所有类型的订阅
extend schema @subscription
-
在类型级别只为特定类型启用订阅
type Movie @node @subscription {
title: String!
}
从 Neo4jGraphQLSubscriptionsEngine
中移除 publish
方法
已从 Neo4jGraphQLSubscriptionsEngine
接口中移除 publish
方法,因为它不再用于基于变更数据捕获 (CDC) 的订阅。在自定义引擎上实现此方法将不再生效,并且无法再直接在 Neo4jGraphQLSubscriptionsCDCEngine
上调用 publish
。
连接操作现在支持相同节点之间的多个关系
连接操作已增强,支持在同一对节点之间创建多个关系。在两个节点之间执行连接操作时,即使这些节点之间已存在一个或多个相同类型的关系,也始终会创建一个新关系。这使得可以建模在相同节点之间需要多个相同类型不同关系的场景。例如,一个演员在同一部电影中扮演多个角色。
变更节点之间多重关系的行为
相同两个节点之间处理多重关系的方式已变更
-
在实体查询字段(如
movies
)中,重复节点将被移除,只返回不同的结果,无论节点之间存在多少关系。 -
在连接查询字段(如
moviesConnection
)中,所有关系都单独表示。这允许为两个节点之间的每个连接投影关系属性。
例如,考虑一个场景,艾迪·墨菲在同一部电影中扮演了多个角色
CREATE (eddie:Person {name: "Eddie Murphy"})
CREATE (nuttyProfessor:Movie { title: "The Nutty Professor" })
CREATE (eddie)-[:ACTED_IN { role: "Professor"}]->(nuttyProfessor)
CREATE (eddie)-[:ACTED_IN { role: "Buddy Love"}]->(nuttyProfessor)
使用标准实体查询
{
actors(where: {name: {eq: "Eddie Murphy"}}) {
name
movies {
title
}
}
}
结果只显示“肥佬教授”一次(节点已去重)
{
"actors": [
{
"name": "Eddie Murphy",
"movies": [
{
"title": "The Nutty Professor"
}
]
}
]
}
然而,使用连接查询
{
actors(where: { name: { eq: "Eddie Murphy" } }) {
name
moviesConnection {
edges {
properties {
role
}
node {
title
}
}
}
}
}
结果保留了两个关系及其不同的属性
{
"actors": [
{
"name": "Eddie Murphy",
"moviesConnection": {
"edges": [
{
"properties": {
"role": "Professor"
},
"node": {
"title": "The Nutty Professor"
}
},
{
"properties": {
"role": "Buddy Love"
},
"node": {
"title": "The Nutty Professor"
}
}
]
}
}
]
}
模式生成避免冲突的复数名称
模式生成现在会检测类型中冲突的复数名称并有意失败。例如,以下模式将因模糊的 Techs
复数而失败
type Tech @node(plural: "Techs") {
name: String
}
type Techs @node {
value: String
}
全文搜索变更
@fulltext
指令已显著变更,现在需要索引名称、查询名称和要索引的字段
"""
Informs @neo4j/graphql that there should be a fulltext index in the database, allowing users to search by the index in the generated schema.
"""
directive @fulltext(
indexes: [FulltextInput!]!
) on OBJECT
input FulltextInput {
indexName: String!
queryName: String!
fields: [String!]!
}
以下是使用示例
type Movie @node @fulltext(
indexes: [
{
indexName: "movieTitleIndex"
queryName: "moviesByTitle"
fields: ["title"]
}
]
) {
title: String!
}
全文搜索以前在两个不同的位置可用。以下形式已完全移除
# No longer supported
{
movies(fulltext: { movieTitleIndex: { phrase: "The Matrix" } }) {
title
}
}
根级别查询已变更以使用 Relay 光标连接规范
之前 | 之后 |
---|---|
|
|
新形式使用 Relay 光标连接规范,该规范允许使用光标进行分页并访问 pageInfo
字段。
移除隐式设置操作
已移除更新变异中的隐式设置操作,迁移路径涉及两个步骤
之前 | 之后 |
---|---|
|
|
excludeDeprecatedFields
的 implicitSet
选项已移除。
@coalesce
指令影响投影字段值
在 7.0.0 版中,@coalesce
指令现在适用于过滤操作和字段投影。以前,@coalesce
指令中指定的 fallback 值仅在这些字段用于过滤器时使用,而不用于返回的字段。现在,当您选择带有 @coalesce
注释的字段时,查询结果中的 null 值将替换为指定的 fallback 值。
考虑此模式
type Movie @node {
title: String!
rating: Float @coalesce(value: 5.0)
}
以前,请求一个评分为 null 的电影会返回
query {
movies {
title
rating # Would return null if the rating wasn't set
}
}
{
"movies": [
{
"title": "The Matrix",
"rating": null
}
]
}
现在,相同的查询返回聚合值
{
"movies": [
{
"title": "The Matrix",
"rating": 5.0 # Returns the fallback value specified in @coalesce
}
]
}
这确保了使用 @coalesce
指令过滤和投影字段之间的一致行为。
默认将 addVersionPrefix
设置为 true
在 7.0.0 版中,addVersionPrefix
选项默认设置为 true
。这意味着所有生成的 Cypher 查询都会自动添加 Cypher 版本前缀
CYPHER 5
MATCH(this:Movie)
这确保了在 Neo4j 中执行查询时使用正确的 Cypher 版本。然而,此变更可能与旧版 Neo4j 不兼容。
将 cypherQueryOptions.addVersionPrefix
设置为 false
以禁用此行为
{
cypherQueryOptions: {
addVersionPrefix: false,
},
}
例如,使用 Apollo Server 时
await startStandaloneServer(server, {
context: async ({ req }) => ({
req,
cypherQueryOptions: {
addVersionPrefix: false,
},
}),
listen: { port: 4000 },
});
变更 DateTime
和 Time
值转换行为
在 7.0.0 版中,DateTime
和 Time
值直接在生成的 Cypher 查询中从字符串转换为时间类型,而不是在使用 Neo4j 驱动程序的服务器代码中转换。
例如,如果您的 GraphQL 查询中包含日期字符串
query {
movies(where: { releaseDate: { gt: "2023-01-15T12:30:00Z" } }) {
title
releaseDate
}
}
字符串值“2023-01-15T12:30:00Z”现在直接在 Cypher 查询中转换为时间类型
MATCH (this:Movie)
WHERE this.releaseDate > datetime($param0)
RETURN this { .title, .releaseDate } as this
变异操作遵循关系方向
变异操作现在在匹配现有关系时遵守 @relationship
指令中定义的 queryDirection
值。这确保了查询和变异之间在如何遍历关系方面的一致行为。
When creating new relationships, the physical direction stored in the database is still determined by the `direction` argument. The change affects only how existing relationships are matched during mutation operations. |
例如,考虑以下模式
type Movie @node {
title: String!
actors: [Person!]! @relationship(type: "ACTED_IN", direction: IN, queryDirection: UNDIRECTED)
}
type Person @node {
name: String!
movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT, queryDirection: UNDIRECTED)
}
当 queryDirection: UNDIRECTED
时,变异现在在匹配节点时沿两个方向遍历现有关系,无论基础 direction
值如何。这与查询在相同指令配置下的工作方式一致。以前,变异在匹配现有关系时总是遵循显式的 direction
值,这可能导致查询和变异之间行为不一致。
嵌套更新操作中 where
字段的位置变更
嵌套更新操作的 where
字段已被移除,取而代之的是嵌套更新输入中的 where
。
之前 | 之后 |
---|---|
|
|
变更针对联合关系上的 single
和 some
过滤器的行为
与联合类型关系一起使用 single
和 some
过滤器的行为已修复,这代表了与之前不正确实现的一个重大变更。
考虑此模式,其中包含一个联合类型和与之相关的关系
union Production = Movie | Series
type Actor @node {
name: String!
actedIn: [Production!]! @relationship(type: "ACTED_IN", direction: OUT)
}
以前,在使用 single
或 some
过滤器与联合类型时,这些过滤器中的条件会针对联合中的每个具体类型单独评估,要求所有类型都匹配。此行为是不正确的。
query {
actors(
where: {
actedIn: { single: { Movie: { title: { contains: "The Office" } }, Series: { title: { endsWith: "Office" } } } }
}
) {
name
}
}
7.0.0 版中的修复行为
-
single
:现在正确返回在整个联合中恰好有一个相关节点的演员,而不是按类型返回。 -
some
:现在正确返回在联合中至少有一个匹配的任何类型相关节点的演员。
此变更提供了更逻辑和一致的结果,但可能会影响依赖先前行为的现有查询。此修复适用于新过滤器语法和已弃用过滤器(例如 actedIn_SINGLE
和 actedIn_SOME
)。
不再支持可为空元素的列表
不再支持在带有 @node
指令注释的类型中使用可为空元素的列表,例如以下类型定义中
type Actor @node {
name: String
pseudonyms: [String]!
}
这是因为 Neo4j 不支持将 null 值作为列表的一部分存储。要创建类似但受支持的类型定义,请将 pseudonyms
字段的值更改为非空列表:[String!]!
。
弃用
弃用专用输入外部的变异运算符
以下运算符现已弃用
-
_SET
-
_POP
-
_PUSH
-
_INCREMENT
-
_ADD
-
_DECREMENT
-
_SUBTRACT
-
_MULTIPLY
-
_DIVIDE
请改用专用输入对象版本
之前 | 之后 |
---|---|
|
|
excludeDeprecatedFields
选项现在包含 mutationOperations
选项,用于移除这些已弃用的运算符
const neoSchema = new Neo4jGraphQL({
typeDefs,
excludeDeprecatedFields: {
mutationOperations: true
}
});
弃用 _EQ 过滤器语法
_EQ
过滤器语法现已弃用。请改用专用输入对象版本
之前 | 之后 |
---|---|
|
|
excludeDeprecatedFields
选项现在包含 attributeFilters
选项,用于移除这些已弃用的过滤器
const neoSchema = new Neo4jGraphQL({
typeDefs,
excludeDeprecatedFields: {
attributeFilters: true
}
});
弃用连接字段外部的聚合过滤器
连接字段外部的聚合过滤器现已弃用。请改用连接输入字段内的聚合过滤器
之前 | 之后 |
---|---|
|
|
excludeDeprecatedFields
选项现在包含 aggregationFiltersOutsideConnection
选项,用于移除这些已弃用的过滤器
const neoSchema = new Neo4jGraphQL({
typeDefs,
excludeDeprecatedFields: {
aggregationFiltersOutsideConnection: true
}
});
弃用专用输入外部的聚合过滤器
专用输入外部的聚合过滤器(如 _AVERAGE_GT
)现已弃用。请改用专用输入对象版本
之前 | 之后 |
---|---|
|
|
excludeDeprecatedFields
选项现在包含 aggregationFilters
选项,用于移除这些已弃用的过滤器
const neoSchema = new Neo4jGraphQL({
typeDefs,
excludeDeprecatedFields: {
aggregationFilters: true
}
});
弃用专用输入外部的关系过滤器
专用输入外部的关系过滤语法(如 _SOME
、_ALL
和 _NONE
)现已弃用。请改用专用输入对象版本
之前 | 之后 |
---|---|
|
|
excludeDeprecatedFields
选项现在包含 relationshipFilters
选项,用于移除这些已弃用的过滤器
const neoSchema = new Neo4jGraphQL({
typeDefs,
excludeDeprecatedFields: {
relationshipFilters: true
}
});