neo4j / запрос расщепления шифров на типы отношений - PullRequest
0 голосов
/ 13 мая 2018

нужна помощь с Cypher: Я пытаюсь создать запрос, где тип следующего отношения 't' определит, в какой столбец будут помещены результаты. в моем случае отношения могут быть «внутри» или «вне». Вот пример того, что я хочу:

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

Я понимаю, что это невозможно сделать таким образом, потому что вы не можете определить отношения в обратной линии, но это лучше всего объясняет, что я хочу сделать. Я попытался создать еще один список раскрутки, используя только «in» и «out», но это просто суммирует результаты, а не разбивает их на «in» или «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

Я также попытался поиграться с другими пунктами, и все это либо искажает данные, либо просто не работает. я понимаю, что вы можете изменить тип отношений, используя [t: in |: out], но этого не достаточно, так как это снова сложит результаты. Я был бы признателен за любые советы по этому вопросу, так как это откровенно сводит меня с ума спасибо!

1 Ответ

0 голосов
/ 13 мая 2018

Вы можете выполнить union из двух запросов, один с t:in, один с t:out типом связи. Таким образом, вы получите две разные строки для счетов in и out.

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

Обратите внимание , что вы не можете постобработать объединение или использовать его как подзапрос. Результат всегда будет упорядочен сначала по type(t), затем n и будет иметь два входа для равных n с.

Чтобы иметь возможность постобработать объединение, оно переписывается, как описано здесь с collect и unwind.

Агрегация sum не может быть выполнена вложенной в collect, агрегация будет выполняться последней.

Будет сделано два независимых запроса для отношений in и out, и результаты будут collect ed.

В каждом collect список (строки) карты (столбца) создается из результата, вспомогательные столбцы / ключи создаются для количества in и out. Список составлен (data_in + collect(...)).

В конце список снова становится unwind в строках, и агрегирование выполняется на distinct(n).

Пример с упрощенным вычислением времени и значения:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...