need help with Cypher: I'm trying to create a query where the type of the following relationship 't' will determine which column the results are put into. in my case, a relationship can either be 'in' or 'out'. here is an example of what i want:
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
I realize this can't be done this way because you can't define a relationship within the return line but this best explains what i want to do. I have tried making another unwind list with just 'in' and 'out', but this just adds up the results rather than split them per 'in' or 'out':
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
I also tried playing around with other clauses and it all either distorts the data or simply doesn't work. i realize you can change relationship type using [t:in|:out] but this isn't enough as again, it will add up the results. i would appreciate any advice on this as this is frankly driving me crazy :( thank you!
You can do a union
of two queries, one with t:in
one with t:out
relationship type. This way you will get two different rows for in
and out
counts.
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
Note that you can not post-process the union or use it as a subquery. The result will always be ordered first by type(t)
then n
and will have two entires for equal n
s.
To be able to postprocess the union it is rewritten as described here with collect
and unwind
.
The sum
aggregation cannot be done nested in the collect
, aggregation will be done last.
Two independent queries will be done for in
and out
relations and the results are collect
ed.
In every collect
a list (rows) of map (column) is created from the result, helper columns/keys are created for in
and out
count. The list is concatenated ( data_in + collect(...)
).
In the end the list is unwind
into rows again and aggregation is done on distinct(n)
.
Example with simplified time and value 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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.