如何根据 Cypher 中的属性创建节点链

问题描述

我在 neo4j 中有以下数据集,表示来自消息应用 slack 的元数据:

MERGE(abc:channel{name:'abc'})
MERGE(fgh:channel{name:'fgh'})
MERGE(a:message {text:'a',ts:'123.4',channel:'abc'})<-[:contains]-(abc)
MERGE(b:message {text:'b',ts:'123.8',channel:'abc'})<-[:contains]-(abc)
MERGE(c:message {text:'c',ts:'125.4',channel:'abc'})<-[:contains]-(abc)
MERGE(d:message {text:'d',ts:'130.4',channel:'abc'})<-[:contains]-(abc)
MERGE(e:message {text:'e',ts:'150.4',channel:'abc'})<-[:contains]-(abc)

MERGE(f:message {text:'f',ts:'100.0',channel:'fgh'})<-[:contains]-(fgh)
MERGE(g:message {text:'g',channel:'fgh'})<-[:contains]-(fgh)
MERGE(h:message {text:'h',ts:'150.0',channel:'fgh'})<-[:contains]-(fgh)
MERGE(i:message {text:'i',ts:'180.0',channel:'fgh'})<-[:contains]-(fgh)
MERGE(j:message {text:'j',ts:'180.2',channel:'fgh'})<-[:contains]-(fgh)

我想创建以下格式的消息链: (a)<-[:follows]-(b)<-[:follows]-(c)<-[:follows]-(d)<-[:follows]-(e) (f)<-[:follows]-(g)<-[:follows]-(h)<-[:follows]-(i)<-[:follows]-(j),基于写作时间ts

我得到以下代码

MATCH(msg:message)<-[:contains]-(cs:channel)
UNWIND cs AS Channel
    WITH collect(msg.ts) AS  messagestimeline,COUNT(msg) AS nomsg,Channel
    ORDER BY messagestimeline 
    FOREACH (i IN RANGE (1,nomsg-1)|
        MERGE (prevIoUsmessage {ts:  messagestimeline[i-1],channel:  Channel.name })
        MERGE (nextmessage {ts: messagestimeline[i],channel: Channel.name })
        MERGE (nextmessage)-[rel:follows]->(prevIoUsmessage)
        SET rel.delta_t = toFloat(messagestimeline[i])-toFloat(messagestimeline[i-1])
    )

并得到结果: (a)-[:follows]->(b)-[:follows]->(c)-[:follows]->(d)-[:follows]->(e) (i)-[:follows]->(j)-[:follows]->(f)-[:follows]->(g)-[:follows]->(h)

有趣的是,当我在 DESC 子句中添加 ORDER BY 时,结果并没有改变

对我做错了什么的任何帮助将不胜感激,我已经坐了 2 天,无法弄清楚。

解决方法

以下代码可以解决问题:

MATCH(cs:channel)
UNWIND cs AS Channel
    MATCH(msgs)<-[:contains]-(Channel)
    WITH Channel,msgs ORDER BY msgs.ts 
    WITH collect(msgs.ts) as msgtimeline,count(msgs) as nom,Channel
    FOREACH(i IN RANGE(1,nom-1)|
        MERGE(prvsmsg{ts:msgtimeline[i-1],channel:Channel.name})
        MERGE(nxtmsg{ts:msgtimeline[i],channel: Channel.name})
        MERGE(prvsmsg)<-[rel:follows]-(nxtmsg)
        set rel.delta_t = toFloat(nxtmsg.ts)-toFloat(prvsmsg.ts)
        )

不同之处在于我在一堆节点的属性上使用了 ORDER BY 子句,然后为 FOREACH 语句创建了列表。 不过,为什么这会产生如此大的差异对我来说仍然是个谜。