Neo4j Cypher - 有条件地写入比赛
Neo4j Cypher - Conditional writes on matches
我有一个数据库,其中包含用户 (u:User {id: 1})
、用户状态 (us:UserStatus {status: 'pending'})
以及它们之间的关系 (u)-[hs:HAS_STATUS {from: 1541030400, to: 4102444800}]->(us)
。
其中用户状态可以是 "pending"
、"active"
或 "suspended"
。
2100-01-01
是未来的某个日期,这意味着用户仍然具有此状态。
我正在尝试 运行 一个查询,该查询通过创建与新状态的新关系来更新用户状态,并通过设置 to
属性 到当前日期。
这是我试过的:
MERGE (u:User { id: 1 })
WITH u
MATCH (u)-[hs1:HAS_STATUS]->(us1:UserStatus)
WHERE us1.status <> 'active' AND hs1.to > 1544400000
SET hs1.to = 1544400000
MERGE (us2:UserStatus {status: 'active'})
MERGE (u)-[hs2:HAS_STATUS {from: 1544400000, to: 4102444800}]->(us2)
如果用户已经具有满足 WHERE
子句的状态,则将其存档并创建新的状态关系。但是,如果用户还没有状态,则会跳过 SET
子句(如预期的那样),但是也会跳过两行 MERGE
。如何确保无论合并如何执行它们?
编辑:
原始查询有一些拼写错误。
编辑:如您所说,您在查询中使用的 "dates" 实际上是纪元秒的替身。
如果没有行发生变化,则发生了以下两种情况之一。
您的 MATCH(与关联的 WHERE)找不到任何匹配模式。您应该尝试 运行 那个 MATCH 和 WHERE 看看它是否 returns 任何行。
您要 MERGE 的关系已经存在。您可能想尝试匹配这两个节点之间的关系(具有那些属性),看看它是否已经存在。
[这回答了您更新后的问题]
如果匹配失败,MATCH
(没有 OPTIONAL
限定符)将中止查询的其余部分。
此查询显示了一种匹配模式的方法,如果匹配成功则可选择执行写入操作,如果匹配失败则不会中止查询的其余部分:
MERGE (u:User { id: 1 })
FOREACH(hs IN
[(u)-[hs1:HAS_STATUS]->(us1:UserStatus)
WHERE us1.status <> 'active' AND hs1.to > 1544400000 | hs1] |
SET hs.to = 1544400000)
MERGE (us2:UserStatus {status: 'active'})
MERGE (u)-[hs2:HAS_STATUS {from: 1544400000, to: 4102444800}]->(us2);
此查询使用 FOREACH clause to iterate through a list (of size 0 or 1, in this case) of matching hs1
values, setting the to
value of each one to 1544400000
. The list is generated by a pattern comprehension。即使列表为空,查询的其余部分仍会执行。
我有一个数据库,其中包含用户 (u:User {id: 1})
、用户状态 (us:UserStatus {status: 'pending'})
以及它们之间的关系 (u)-[hs:HAS_STATUS {from: 1541030400, to: 4102444800}]->(us)
。
其中用户状态可以是 "pending"
、"active"
或 "suspended"
。
2100-01-01
是未来的某个日期,这意味着用户仍然具有此状态。
我正在尝试 运行 一个查询,该查询通过创建与新状态的新关系来更新用户状态,并通过设置 to
属性 到当前日期。
这是我试过的:
MERGE (u:User { id: 1 })
WITH u
MATCH (u)-[hs1:HAS_STATUS]->(us1:UserStatus)
WHERE us1.status <> 'active' AND hs1.to > 1544400000
SET hs1.to = 1544400000
MERGE (us2:UserStatus {status: 'active'})
MERGE (u)-[hs2:HAS_STATUS {from: 1544400000, to: 4102444800}]->(us2)
如果用户已经具有满足 WHERE
子句的状态,则将其存档并创建新的状态关系。但是,如果用户还没有状态,则会跳过 SET
子句(如预期的那样),但是也会跳过两行 MERGE
。如何确保无论合并如何执行它们?
编辑: 原始查询有一些拼写错误。
编辑:如您所说,您在查询中使用的 "dates" 实际上是纪元秒的替身。
如果没有行发生变化,则发生了以下两种情况之一。
您的 MATCH(与关联的 WHERE)找不到任何匹配模式。您应该尝试 运行 那个 MATCH 和 WHERE 看看它是否 returns 任何行。
您要 MERGE 的关系已经存在。您可能想尝试匹配这两个节点之间的关系(具有那些属性),看看它是否已经存在。
[这回答了您更新后的问题]
如果匹配失败,MATCH
(没有 OPTIONAL
限定符)将中止查询的其余部分。
此查询显示了一种匹配模式的方法,如果匹配成功则可选择执行写入操作,如果匹配失败则不会中止查询的其余部分:
MERGE (u:User { id: 1 })
FOREACH(hs IN
[(u)-[hs1:HAS_STATUS]->(us1:UserStatus)
WHERE us1.status <> 'active' AND hs1.to > 1544400000 | hs1] |
SET hs.to = 1544400000)
MERGE (us2:UserStatus {status: 'active'})
MERGE (u)-[hs2:HAS_STATUS {from: 1544400000, to: 4102444800}]->(us2);
此查询使用 FOREACH clause to iterate through a list (of size 0 or 1, in this case) of matching hs1
values, setting the to
value of each one to 1544400000
. The list is generated by a pattern comprehension。即使列表为空,查询的其余部分仍会执行。