故障排除
这是 GraphQL 库版本 6 的文档。有关长期支持 (LTS) 版本 5,请参阅 GraphQL 库版本 5 LTS. |
本章包含常见的故障排除步骤。此外,还有一个关于 常见问题解答 的部分,您可能在其中找到问题的答案。
调试日志
对于 @neo4j/graphql
@neo4j/graphql
使用 debug
库进行调试级日志记录。您可以通过运行时将环境变量 DEBUG
设置为 @neo4j/graphql:*
来打开所有调试日志记录。例如
命令行
DEBUG=@neo4j/graphql:* node src/index.js
或者,如果您正在调试特定功能,您可以指定多个命名空间来隔离某些日志行
-
@neo4j/graphql:*
- 记录所有内容 -
@neo4j/graphql:auth
- 记录授权标头和令牌提取的状态,以及 JWT 的解码 -
@neo4j/graphql:graphql
- 记录 GraphQL 查询和变量 -
@neo4j/graphql:execution
- 在执行之前记录 Cypher 和 Cypher 参数,以及执行摘要
构造函数
您还可以通过在构造函数中将 debug
参数设置为 true
来在库中启用所有调试日志记录。
const { Neo4jGraphQL } = require("@neo4j/graphql");
const neo4j = require("neo4j-driver");
const { ApolloServer } = require("apollo-server");
const typeDefs = `
type Movie @node {
title: String!
}
`;
const driver = neo4j.driver(
"bolt://localhost:7687",
neo4j.auth.basic("username", "password")
);
const neoSchema = new Neo4jGraphQL({
typeDefs,
driver,
debug: true,
});
对于 @neo4j/introspector
@neo4j/introspector
具有自己的调试日志命名空间,您可以使用以下命令打开它的日志记录
DEBUG=@neo4j/introspector node src/index.js
了解有关 内省器 的更多信息。
查询调整
希望您不需要执行任何查询调整,但如果您确实需要,Neo4j GraphQL 库允许您在请求上下文中设置完整的查询选项数组。
您可以在 Cypher 手册 → 查询选项 中详细了解可用的查询选项。
请仅在您知道自己在做什么的情况下设置这些选项。
例如,要将“runtime”选项设置为“interpreted”
const { Neo4jGraphQL } = require("@neo4j/graphql");
const neo4j = require("neo4j-driver");
const { ApolloServer } = require("apollo-server");
const typeDefs = `
type Movie @node {
title: String!
}
`;
const driver = neo4j.driver(
"bolt://localhost:7687",
neo4j.auth.basic("username", "password")
);
const neoSchema = new Neo4jGraphQL({
typeDefs,
driver,
});
neoSchema.getSchema().then((schema) => {
const server = new ApolloServer({
schema,
context: ({ req }) => ({
req,
cypherQueryOptions: {
runtime: "interpreted",
},
}),
});
server.listen().then(({ url }) => {
console.log(`Server ready at ${url}`);
});
});
常见问题解答
本章包含常见问题及其解决方案。
我已从 <1.1.0 升级,但我的 DateTime
字段排序不符合预期
由于 1.1.0 之前的版本中存在错误,您的 DateTime
字段有可能存储在数据库中,作为字符串而不是时间值。您应该使用 Cypher 查询在数据库中对这些属性进行重写。对于受影响的节点具有“Movie”标签且受影响的属性为“timestamp”的示例,您可以使用以下 Cypher 执行此操作
MATCH (m:Movie)
WHERE apoc.meta.type(m.timestamp) = "STRING"
SET m.timestamp = datetime(m.timestamp)
RETURN m
我的更新和创建输入中的 _emptyInput
是什么?
如果您定义的类型仅包含自动生成的和/或关系属性,则 _emptyInput
将出现在您的更新和创建输入中。它是一个占位符属性,因此在更新或创建中都为其赋值,都不会在节点上为其赋值。如果您添加用户提供的属性,_emptyInput
将被删除。
以下示例将创建具有 _emptyInput
的输入
type Cookie @node {
id: ID! @id
owner: Owner! @relationship(type: "HAS_OWNER", direction: OUT)
# f: String # If you don't want _emptyInput, uncomment this line.
}
我的图中未强制执行关系可空性
目前,鉴于下面的 typeDefs,Neo4j GraphQL 将在创建和更新一对一关系(例如下面的电影导演字段)时强制执行基数
type Movie @node {
title: String!
director: Person! @relationship(type: "DIRECTED", direction: IN)
actors: [Person!]! @relationship(type: "ACTED_IN", direction: IN)
}
type Person @node {
name: String!
}
但是,目前,尚无机制来支持验证演员关系。此外,如果您在一个突变中创建电影和导演,则存在已知的限制
mutation {
createMovies(
input: [
{
title: "Forrest Gump"
director: { create: { node: { name: "Robert Zemeckis" } } }
}
]
) {
movies {
title
director {
name
}
}
}
}
然后删除导演节点
mutation {
deletePeople(where: { name_EQ: "Robert Zemeckis" }) {
nodesDeleted
}
}
即使模式规定所有电影都必须有导演,从而在技术上使电影节点无效,也不会抛出任何错误。
最后,我们不会在联合或接口关系上强制执行关系基数。
安全
本节介绍安全注意事项和已知问题。
空匹配未触发授权
如果查询没有产生结果,则 授权 过程将不会触发。这意味着结果将为空,而不是抛出身份验证错误。即使无法访问数据本身,未经授权的用户也可以判断数据库中是否存在特定类型。