0

我有一个包含用户(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也跳过两行。无论合并如何,我如何确保它们被执行?

编辑: 原始查询有一些错别字。

4

2 回答 2

1

[这回答了您更新的问题]

如果匹配失败, A 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子句遍历匹配hs1值的列表(在本例中大小为 0 或 1),将to每个值设置为1544400000. 该列表由模式理解生成。即使列表为空,查询的其余部分仍会执行。

于 2018-12-11T19:35:30.430 回答
0

编辑:当您说您在查询中使用的“日期”实际上是纪元秒的替代时,先前的答案片段被删除。

如果没有更改任何行,则发生两件事之一。

  1. 您的 MATCH(与关联的 WHERE)未能找到任何匹配的模式。您应该尝试只运行 MATCH 和 WHERE 以查看它是否返回任何行。

  2. 您尝试合并的关系已经存在。您可能想尝试匹配这两个节点之间的关系(使用这些属性)并查看它是否已经存在。

于 2018-12-10T18:49:29.457 回答