首先,我使用带有 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
的 JSON发送。自定义输入类型:name
downloadURL
input CreateImageReference {
name: String!
downloadURL: String!
}
在我的模式文件中很简单,并且被 apollo/graphql 接受就好了。我正在记录“graphqlResponse”以监控所有内容,到目前为止似乎没有问题。
我正在尝试根据参数是否为空来“选择性地创建”该ImageReference
节点以及与该节点的关系。我的自定义突变与密码查询没有添加逻辑:Post
$imageReference
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
什么,如果是,则什么都不做,而不是在以下情况下运行 CREATE 节点/关系语句NOT IS NULL
:
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))",
。
这是成功创建帖子的 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 的帖子。也许解决方案只是创建两个不同的查询?