密码的总体目标是为项目分配状态并将以前的状态保存为存档。
我有一个列表,如果项目作为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关系。没有错误。
知道我在这里缺少什么吗?
答案 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
已经为您设置了该属性。