检索列表中的最后一个节点以进行进一步处理

时间:2018-05-04 15:39:24

标签: neo4j cypher

我尝试为网络点击设置一个方案,其中每个节点都是(:Click),它链接到[:PREV]边缘前面的点击和(:Session)它由[:GEN]边缘拥有它。最后,这应该是程序性的,当进行新的点击时,新的事务/插入。虽然生成相关对象没有问题,但我无法弄清楚如何动态选择上一个(:Click)并将其链接到当前创建的对象。

通过2次点击生成会话:

CREATE (s:Session {name:'S0'})
CREATE (c1:Click {name:'C1', click:1}), (c1)<-[:GEN]-(s)
CREATE (c2:Click {name:'C2', click:2}), (c2)<-[:GEN]-(s), (c1)<-[:PREV]-(c2);

在分离的交易中生成另一个点击:

MERGE (s:Session {name:'S0'})
CREATE (c3:Click {name:'C3', click:3}),
(c3)<-[:GEN]-(s) //(c2)<-[:PREV]-(c3);

对于注释掉的链接,我不能使用c2 - 变量,因为它是前一个事务的范围本地。

现在我想尝试这样的事情来动态地在同一个会话中找到最后生成的节点并将其链接

MERGE (s:Session {name:'S0'})
CREATE (c3:Click {name:'C3', click:3}), (c3)<-[:GEN]-(s)

MATCH (s)-[:GEN]->(c_prevs:Click) 
WITH c_prevs
ORDER BY c_prevs.click DESC LIMIT 1
CREATE (head(c_prevs))<-[:PREV]-(c3)

不幸的是,到目前为止,我想出的任何Cypher构造都不会对我有所帮助。

2 个答案:

答案 0 :(得分:0)

如果我理解你可以通过这种方式获得同一会话中的最后一个:Click节点:

match (:Session {name:'S0'})-[:GEN]->(c:Click)
where not (:Click)-[:PREV]->(c)
return c

即:从没有传入[PREV]关系的同一会话中获取节点。将返回c2

╒═══════════════════════╕
│"c"                    │
╞═══════════════════════╡
│{"name":"C2","click":2}│
└───────────────────────┘

对于您的具体情况,以下查询应该有效:

merge (s:Session {name:'S0'})

with s

match (s)-[:GEN]->(last:Click)
where not (:Click)-[:PREV]->(last)

create (c3:Click {name:'C3', click:3}),
(c3)<-[:GEN]-(s),
(last)<-[:PREV]-(c3)

答案 1 :(得分:0)

我发现我的问题的答案是以下

MATCH (s:Session {name:'S0'})
CREATE (c3:Click {name:'C3', click:3})

WITH s, c3
MATCH (s)-[:GEN]->(c_prev:Click) 
WITH c_prev, c3, s
ORDER BY c_prev.click DESC LIMIT 1
WITH c_prev, c3, s
CREATE (c_prev)<-[:PREV]-(c3), (c3)<-[:GEN]-(s)

使用s关键字将节点链接为变量c3last_cWITH。不幸的是,这涉及很多重复,因为原则上每个WITH都是查询中的部分分隔符,所以我学会了。

这也允许继承已经过的MERGED / CREATED节点,这可能有助于确保它们的存在。

编辑:

如果点击应该生成prozedural,这个问题似乎更加复杂,因此使用一个cypher语句来插入和链接任何点击。

我的解决方案如下所示

MERGE (s:Session {name: $session_name})
WITH s
CREATE (c:Click {name: $click_name, click: $click_count})

WITH s, c
OPTIONAL MATCH (s)-[:GEN]->(c_prev:Click) 
WITH c_prev, c, s
ORDER BY c_prev.click DESC LIMIT 1
WITH c_prev, c, s
FOREACH (o IN CASE WHEN c_prev IS NOT NULL THEN ['1'] ELSE [] END |
  CREATE (c_prev)<-[:PREV]-(c)
)

WITH s, c 
CREATE (c)<-[:GEN]-(s)

{$session_name, $click_name, $click_count} =[{'AAA', 'C1', 1}, {'AAA', 'C2', 2}, {'AAA', 'C3', 3}]执行此语句。

请注意,我必须通过显式捕获此条件然后不在空列表中执行带有FOREACH循环的后续连接语句来解决返回的空节点列表。这不仅看起来很丑陋,我真诚地认为应该有更好的方法在不久的将来通过Cypher明确指出这种期望的行为。