如果密码不存在,请创建密码关系

时间:2016-05-19 18:47:04

标签: neo4j cypher

密码的总体目标是为项目分配状态并将以前的状态保存为存档。

我有一个列表,如果项目作为neo4j 3.0中的节点。每个项目可以具有以下状态之一:Live,Dead,Missing或我定义的任何其他状态。

首先,我创建一个状态为live的节点。

Merge (n:Item {itemID: '123'}
  ON CREATE set n.itemID = '123, ...
  ON MATCH  set n.DTS = ...
WITH n
MATCH (st:Status {name:'Live'})
MERGE (n)-[CURRENT_STATUS {DTS: ...}]->(st)

这很好用。

现在,当用户想要更改状态时,我想制作CURRENT_STATUS的副本,然后将其删除,并创建一个具有新状态的新副本。我只有在新状态与当前状态不同时才需要这样做。这是我尝试过的(在'Missing'下面是应该分配给该项目的新状态):

Merge (n:Item {itemID: '123'}
  ON CREATE set n.itemID = '123, ...
  ON MATCH  set n.modifiedDTS = ...
WITH n
MATCH (n)-[cs:CURRENT_STATUS]-(st:Status)
WITH n, st, CASE st.name WHEN 'Missing' THEN [] ELSE [n] END as array, cs
FOREACH (x in array | 
   CREATE (x)-[prevStatus:PREVIOUS_STATUS {DTS: cs.DTS}]->(st)
   DELETE cs
   CREATE (x)-[newStatus:CURRENT_STATUS {DTS: 123}]->(st2:Status {name:'Missing'})
)
return *;

不幸的是,这不起作用。循环正在删除现有状态,但从不创建PREVIOUS_STATUS或CURRENT_STATUS关系。没有错误。

知道我在这里缺少什么吗?

2 个答案:

答案 0 :(得分:0)

我想出了这个问题。问题是我在循环中使用x而不是n。因为我还是一个密码新手,所以其他人有一个更好的建议我会离开这个开放。

答案 1 :(得分:0)

旁白:在我看来,你原来的方法应该有效。也许您使用的是旧版本的neo4j?

您原来的Cypher可能导致n最终与多个:PREVIOUS_STATUS关系结束,您必须通过DTS订购它们才能找到最新的关系。{1}}我已经修改了你的Cypher,不仅要使用你的答案中的“n而不是x”解决方法,而且还要按照反向时间顺序将状态链接在一起(这样就不需要计算来获得排序)。

MERGE (n:Item {itemID: '123'}
  ON CREATE SET ...
  ON MATCH  SET n.modifiedDTS = ...
WITH n
MATCH (n)-[cs:CURRENT_STATUS]-(st:Status)
WITH n, st, cs, CASE st.name WHEN 'Missing' THEN [] ELSE [1] END as array
FOREACH (x in array |
   CREATE (n)-[newStatus:CURRENT_STATUS {DTS: 123}]->(st2:Status {name:'Missing'})
   CREATE (st2)-[prevStatus:PREVIOUS_STATUS {DTS: cs.DTS}]->(st)
   DELETE cs
)
return *;

使用相同的项目进行多次迭代后,此查询将创建如下链:

(:Item)-[:CURRENT_STATUS]->(:Status)-[:PREVIOUS_STATUS]->(:Status)-[:PREVIOUS_STATUS]->(:Status)-> ...

顺便说一句,在ON CREATE子句中,不需要SET n.itemID = '123',因为MERGE已经为您设置了该属性。