简体   繁体   中英

neo4j/cypher splitting query to relationship types

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM