Neo4j/Cypher正在尝试解开用户ID列表,创建一个通知并与所有匹配的用户建立关系

Neo4j/Cypher正在尝试解开用户ID列表,创建一个通知并与所有匹配的用户建立关系,neo4j,cypher,graph-databases,neo4j-apoc,Neo4j,Cypher,Graph Databases,Neo4j Apoc,我有一个密码查询: OPTIONAL MATCH (allMentionedUsers:User) WHERE allMentionedUsers.id in $mentions UNWIND allMentionedUsers as mentionedUser CREATE (n:Notification { id: apoc.create.uuid(), notificationType: 'MENTION', notifierName: u.username,

我有一个密码查询:

OPTIONAL MATCH (allMentionedUsers:User)
WHERE allMentionedUsers.id in $mentions
UNWIND allMentionedUsers as mentionedUser
CREATE (n:Notification {
    id: apoc.create.uuid(),
    notificationType: 'MENTION',
    notifierName: u.username,
    body: 'mentioned you',
    createdAt: datetime(),
    updatedAt: datetime()
})
CREATE (p)-[:HAS_NOTIFICATION]->(n)-[:NOTIFIES]->(mentionedUser)
这将检查变量
$references
(字符串ID列表)是否存在可能的用户匹配,然后展开所有匹配的用户以创建通知和后续关系
p
是另一个父节点,对于这个问题来说并不太重要<代码>u在这里也不重要,按预期工作

本质上,我希望有一个通知与一个或多个用户节点具有
通知关系

目前,上述语句为每个用户创建单独的通知。有人看到我如何修改它来创建一个通知节点,该节点具有与匹配用户相同数量的
通知关系吗


它正在创建多个通知节点,因为创建在展开中。

使用合并功能而不是创建。Merge不会创建重复项,因为如果它看到存在相同的节点/关系,则会跳过该节点/关系,而不会创建另一个节点/关系。它就像一个匹配,如果找不到就创建。同时,CREATE不会检查是否存在相同的节点/关系

OPTIONAL MATCH (allMentionedUsers:User)
WHERE allMentionedUsers.id in $mentions
UNWIND allMentionedUsers as mentionedUser
MERGE (p)-[:HAS_NOTIFICATION]->(n:Notification {
    id: apoc.create.uuid(),
    notificationType: 'MENTION',
    notifierName: u.username,
    body: 'mentioned you',
    createdAt: datetime(),
    updatedAt: datetime()
})-[:NOTIFIES]->(mentionedUser)

你的放松实际上并没有什么作用,这是一个不可操作的过程。“展开”可以在列表上工作,但是
AllReferenceUsers
不是列表(最好使用单数而不是复数作为变量名)

您可以先合并通知,然后再创建模式的其余部分

...
MERGE (n:Notification {
    id: apoc.create.uuid(),
    notificationType: 'MENTION',
    notifierName: u.username,
    body: 'mentioned you',
    createdAt: datetime(),
    updatedAt: datetime()
})
WITH u, p, n
OPTIONAL MATCH (mentionedUser:User)
WHERE mentionedUser.id in $mentions
MERGE (p)-[:HAS_NOTIFICATION]->(n)
MERGE (n)-[:NOTIFIES]->(mentionedUser)
或者,您可以将用户收集到一个列表中,并执行相同的操作,这可能会更好一些,因为合并操作只会发生一次,而不是针对每一行:

...
OPTIONAL MATCH (mentionedUser:User)
WHERE mentionedUser.id in $mentions
WITH u, p, collect(mentionedUser) as allMentionedUsers
MERGE (n:Notification {
    id: apoc.create.uuid(),
    notificationType: 'MENTION',
    notifierName: u.username,
    body: 'mentioned you',
    createdAt: datetime(),
    updatedAt: datetime()
})
MERGE (p)-[:HAS_NOTIFICATION]->(n)
FOREACH (mentionedUser IN allMentionedUsers | 
  MERGE (n)-[:NOTIFIES]->(mentionedUser) )
我使用FOREACH来处理每个提到的用户的通知,因为它会降低基数,如果您没有任何其他操作要对每个提到的用户执行,这一点很重要

最后一种选择是将所有提及的用户从头到尾保留在列表中,但这需要使用列表理解和模式理解,以及使用奇怪的替代模式语法来捕获多部分模式中单个节点的模式(因为CyfER似乎不考虑单个节点作为模式理解的有效模式)。
我已经尝试过了,但它仍然在创建多个通知节点。
...
WITH u, p, [id in $mentions | [(user:User {id:id})-[*0]-() | user][0]] as allMentionedUsers
MERGE (n:Notification {
    id: apoc.create.uuid(),
    notificationType: 'MENTION',
    notifierName: u.username,
    body: 'mentioned you',
    createdAt: datetime(),
    updatedAt: datetime()
})
MERGE (p)-[:HAS_NOTIFICATION]->(n)
FOREACH (mentionedUser IN allMentionedUsers | 
  MERGE (n)-[:NOTIFIES]->(mentionedUser) )