neo4j / cypher将查询拆分为关系类型

时间:2018-05-13 08:52:01

标签: neo4j cypher

需要Cypher的帮助: 我正在尝试创建一个查询,其中包含以下关系的类型' t'将确定结果放入哪一列。在我的情况下,关系可以是' in'或者' out'。这是我想要的一个例子:

UNWIND range(0,10)[0..10] AS n
MATCH (c:cluster{clusterid:'abc'}) - [:in_cluster]-() -[t] -()
where AND (1525132800 +3600*(n)) <= t.time < (1525132800 + 3600*(n+1)) 
return n, type(t), count(t:in), (sum(t:in.value)/100000000) as in, count(t:out), (sum(t:out.value)/100000000) as out
ORDER BY n

我意识到这不可能以这种方式完成,因为你无法在回归线中定义关系,但这最能说明我想做什么。 我试过制作另一个展开列表,其中只有&#39; in&#39;并且&#39; out&#39;,但这只是将结果加起来而不是按照&#39;或者&#39; out&#39;:

UNWIND ['out', 'in'][0..2] AS g
UNWIND range(0,10)[0..10] AS n
MATCH (c:cluster{clusterid:'abc'}) - [:in_cluster]-() -[t] -()
where type(t)=g AND (1525132800 +3600*(n)) <= t.time < (1525132800 + 3600*(n+1)) 
return n, count(t), (sum(t.value)/100000000) as inflow_or_outflow
ORDER BY n

我也尝试过使用其他条款,这些都会扭曲数据或者根本不起作用。我意识到你可以使用[t:in |:out]改变关系类型,但这还不够,它会将结果加起来。 我很感激任何有关这方面的建议,因为这坦率地让我发疯:( 谢谢!

1 个答案:

答案 0 :(得分:0)

您可以执行union两个查询,一个t:in一个t:out关系类型。这样,您将获得两个不同的行inout计数。

UNWIND range(0,9) AS n
MATCH (c:cluster {clusterid: 'abc'})-[:in_cluster]-()-[t:in]-()
where (1525132800 + 3600*(n)) <= t.time < (1525132800 + 3600*(n+1))
return n, type(t), count(t), (sum(t.value)/100000000) as value
ORDER BY n

 UNION

UNWIND range(0,9) AS n
MATCH (c:cluster {clusterid: 'abc'})-[:in_cluster]-()-[t:out]-()
where (1525132800 + 3600*(n)) <= t.time < (1525132800 + 3600*(n+1))
return n, type(t), count(t), (sum(t.value)/100000000) as value
ORDER BY n

注意您不能post-process the union或将其用作子查询。结果将始终由type(t)然后n排序,并且将有两个相等的n个。

为了能够对联盟进行后期处理,它将按here所述的collectunwind进行重写。

sum聚合无法嵌套在collect中,聚合将在最后完成。

将针对inout关系进行两次独立查询,结果为collect

在每个collect中,根据结果创建地图(列)的列表(行),为inout计数创建帮助列/键。该列表是连接的(data_in + collect(...))。

最后,列表再次unwind成行,并在distinct(n)上完成聚合。

简化时间和值caluclation的示例:

unwind range(0,9) as n  
match (c:cluster{clusterid:'abc'}) - [:in_cluster]-() -[t:in] -() 
where n<= t.time < (n+1) 
with collect({ c: c, ty: type(t), c_in: 1, c_out: 0, v_in: t.value, v_out: 0, n: n}) as data_in

unwind range(0,9) as n
match (c:cluster{clusterid:1}) - [:in_cluster]-() -[t:out] -() 
where n<= t.time < (n+1) 
with data_in + collect({ c: c, ty: type(t), c_in: 0, c_out: 1, v_in: 0, v_out: t.value, n: n}) as data_in_out 

unwind data_in_out as row 
return distinct(row.n) as n,
   sum(row.c_in) as count_in,
   sum(row.c_out) as count_out,
   sum(row.v_in) as in,
   sum(row.v_out) as out
order by n