【发布时间】:2021-02-25 17:44:40
【问题描述】:
首先,我使用带有 Flutter 的 GRANDstack 作为我的前端。不是超级相关,但对于上下文。我有一个 CreatePost 突变:
mutation CreatePost(\$body: String!, \$userId: ID!, \$imageReference: CreateImageReference!, \$mentions: [String!]) {
CreatePost(body: \$body, userId: \$userId, imageReference: \$imageReference, mentions: \$mentions) {
id,
body,
createdAt {
formatted
},
updatedAt {
formatted
},
user {
username
},
imageReference {
downloadURL
}
}
}
这成功地将我的CreateImageReference 输入作为带有name 和downloadURL 属性的JSON 发送。自定义输入类型:
input CreateImageReference {
name: String!
downloadURL: String!
}
在我的架构文件中很简单,并且被 apollo/graphql 接受就好了。我正在记录“graphqlResponse”以监控所有内容,到目前为止似乎没有问题。
我正在尝试根据$imageReference 参数是否为空来“选择性地创建”这个ImageReference 节点以及与Post 节点的关系。我的自定义突变与密码查询没有添加 ImageReference 逻辑:
CreatePost(body: String!, userId: ID!, imageReference: CreateImageReference!, mentions: [String!]): Post
@cypher(
statement: """
MATCH (u:User {id: $userId})-[:MEMBER_OF]->(g:Group)
OPTIONAL MATCH (g)-[rel:NEWEST_POST]->(prevNewest:Post)
CREATE (u)-[:WROTE]->(p:Post {id: apoc.create.uuid(), body: $body, createdAt: datetime(), updatedAt: datetime()})<-[:NEWEST_POST]-(g)
MERGE (u)-[hp:HAS_PARTICIPATED]->(g)
ON MATCH SET hp.updatedAt = p.createdAt
ON CREATE SET hp.createdAt = p.createdAt, hp.updatedAt = p.createdAt
FOREACH(i in CASE WHEN NOT rel IS NULL THEN [1] ELSE [] END |
DELETE rel CREATE (p)-[:NEXT_POST]->(prevNewest))
WITH p
OPTIONAL MATCH (allMentionedUsers:User)
WHERE allMentionedUsers.id in $mentions
UNWIND allMentionedUsers as mentionedUser
MERGE (p)-[:MENTIONS]->(mentionedUser)
// Add CREATE ImageReference and
// Add CREATE relationship (HAS_ATTACHMENT) between ImageReference and Post here
RETURN p
""")
检查变量 $imageReference IS NULL 是否是最有效的方法是什么,如果是则什么都不做,而不是在 NOT IS NULL 时运行 CREATE 节点/关系语句:
CREATE (i:ImageReference {id: apoc.create.uuid(), name: $imageReference['name'], downloadURL: $imageReference['downloadURL']}
WITH i
CREATE (p)-[:HAS_ATTACHMENT]-(i)
这是一个 CASE 的尝试:
CASE $imageReference
WHEN null []
ELSE CREATE (i:ImageReference {
id: apoc.create.uuid(),
name: $imageReference['name'],
downloadURL: $imageReference['downloadURL'],
createdAt: datetime(),
updatedAt: datetime(),
deletedAt: null
})
CREATE (p)-[:HAS_ATTACHMENT]->(i)
WITH i END
这是在抛出一个"Neo4jError: Failed to invoke procedure apoc.cypher.doIt: Caused by: org.neo4j.exceptions.SyntaxException: Invalid input 'S': expected 'l/L' (line 10, column 3 (offset: 678))",。
这是一个成功创建 Post 的 FOREACH 尝试,但不是 ImageReference,没有错误说明原因:
FOREACH (i in CASE WHEN NOT $imageReference IS NULL THEN [1] ELSE [] END |
CREATE (ir:ImageReference {
id: apoc.create.uuid(),
name: $imageReference['name'],
downloadURL: $imageReference['downloadURL'],
createdAt: datetime(),
updatedAt: datetime(),
deletedAt: null
})
CREATE (p)-[:HAS_ATTACHMENT]->(ir))
如果我执行这部分:
CREATE (ir:ImageReference {
id: apoc.create.uuid(),
name: $imageReference['name'],
downloadURL: $imageReference['downloadURL'],
createdAt: datetime(),
updatedAt: datetime(),
deletedAt: null
})
CREATE (p)-[:HAS_ATTACHMENT]->(ir))
没有 CASE 或 FOREACH,它会按预期成功创建节点和关系,这很好,直到我想创建没有 ImageReference 的帖子。也许解决方案是只创建两个不同的查询?
【问题讨论】:
-
谢谢。我正在尝试使用 FOREACH,它成功创建了 Post,但不是 ImageReference(关于原因没有错误)。如果您有机会达到顶峰,我将其添加到问题中。欣赏!
标签: neo4j graphql cypher apollo grandstack