为具有cypher的节点获取的所有节点创建链接列表

时间:2016-08-04 09:17:33

标签: neo4j cypher

我正在努力用cypher语句做一个链表。我试图为每个k做以下事情。链接列表和:NEXT关系应该用k隔离。

match (elem:Event)<-[r:HAS_EVENT]-(k)
WITH elem ORDER BY elem.id ASC
WITH COLLECT(elem) AS elems
FOREACH (n IN RANGE(0, LENGTH(elems)-2) |
FOREACH (prec IN [elems[n]] |
FOREACH (next IN [elems[n+1]] |
MERGE (prec)-[:NEXT]->(next))))

由于不可能在FOREACH语句中执行MATCH语句,我尝试使用as x UNWIND x作为k的MATCH(a:Some_Label)以及为每个k运行此代码的其他可能方法(id lockup等)。我总是得到一个长链:NEXT throu all:事件节点,表明match语句考虑所有k个节点。我需要有关如何匹配的帮助:Some_Label节点并将它们中的每一个传递给上面的代码。

3 个答案:

答案 0 :(得分:0)

我假设您要在NEXT列表中创建Events链。每个Event列表都来自MATCH到特定的k节点。

我认为您可以通过稍微不同的WITH子句然后执行订购步骤来实现此目的:

MATCH (k:Ticket) // however you match here...
WITH k
// MATCH your k to Events
MATCH (elem:Event)<-[r:HAS_EVENT]-(k)
// include k in the WITH clause
// now you have one result 'row' per k with the matching elem nodes
WITH k, COLLECT(elem) AS elems
// UNWIND, ORDER BY and collect() again to sort the list in each row
UNWIND elems AS x
WITH x ORDER BY x.id ASC
WITH collect(x) AS ordered_elems_per_k
// now the foreach should be applied for each k/list of elem pair
FOREACH (n IN RANGE(0, LENGTH(ordered_elems_per_k)-2) |
FOREACH (prec IN [ordered_elems_per_k[n]] |
FOREACH (next IN [ordered_elems_per_k[n+1]] |
MERGE (prec)-[:NEXT]->(next))))

我认为不可能将ORDER BYcollect()结合起来。这将以更简单的方式解决您的问题,但沿着这条线的某些事情应该有效。

答案 1 :(得分:0)

我设法解决了这个问题;

CALL apoc.periodic.iterate('Match (a:Ticket) return id(a) as id_p', 
'match (elem:Event)<-[r:HAS_EVENT]-(k) where id(k)={id_p} 
WITH elem ORDER BY elem.id ASC WITH COLLECT(elem) AS elems 
FOREACH (n IN RANGE(0, LENGTH(elems)-2) | 
FOREACH (prec IN [elems[n]] | 
FOREACH (next IN [elems[n+1]] | MERGE (prec)-[:NEXT]->(next))))',
{batchSize:1000,parallel:true}) YIELD batches, total

答案 2 :(得分:0)

听起来有两个部分。首先,仅匹配您希望包含在链表中的k个节点(过滤,排序等)。

完成此操作后,您只需将它们收集到一个列表中,然后使用apoc.coll.pairs([list]) YIELD value即可。这会将列表更改为每个顺序元素对的列表([[first,second],[second,third] ...])。你只需要留意最后一对,即[last,null]。

此时您需要做的就是对每个元素(对)执行FOREACH并合并您的:NEXT关系。

修改

看起来你正在使用周期函数迭代你感兴趣的k个元素。你可以使用COLLECT()和pairs()函数来替换嵌套的FOREACH循环。

更新

虽然有一个apoc.coll.pairsMin()函数可以确保我们在最后一个配对中没有空值,但现在强烈建议使用apoc.nodes.link()代替,将有序的节点列表传递给链接在一起要使用的关系的类型:

Match (elem:Event)<-[r:HAS_EVENT]-(k)
WITH elem ORDER BY elem.id ASC
WITH COLLECT(elem) AS elems
CALL apoc.nodes.link(elems, 'NEXT')
RETURN elems
相关问题