Можно ли использовать несколько уровней агрегации в одном запросе Cypher? - PullRequest
0 голосов
/ 18 января 2019

Я написал запрос Cypher, чтобы найти произведение степеней обратных узлов для всех путей между данным источником и целью. Я также хотел бы иметь возможность включать процент от общего числа, которое будет представлять каждый путь, если бы все степени обратного узла были суммированы вместе. Однако когда я создаю эту сумму в операторе WITH (см. Ниже), возвращаемый процент всегда равен 100.

MATCH path = (n0:Compound)-[:BINDS_CbG]-(n1)-[:PARTICIPATES_GpPW]-(n4:Disease)
WHERE n0.identifier = "DB01156"
AND n4.identifier = "DOID:0050742"
WITH
[
...
] AS degrees, path

// Adding a second with query allows us to access PDP for creating the PERCENT_OF_DWPC field in the return
WITH degrees, path, reduce(pdp = 1.0, d in degrees| pdp * d ^ -1) AS PDP
WITH path, PDP, sum(PDP) AS DWPC
RETURN
path,
PDP,
100 * (PDP / DWPC) AS PERCENT_OF_DWPC

ORDER BY PERCENT_OF_DWPC DESC

Я знаю, что это можно сделать, дважды написав запрос (см. Ниже), но для его выполнения требуется вдвое больше времени. Можно ли отказаться от дополнительных издержек и рассчитать процент в предложении WITH?

MATCH path = (n0:Compound)-[:BINDS_CbG]-(n1)-[:PARTICIPATES_GpPW]-(n4:Disease)
WHERE n0.identifier = "DB01156"
AND n4.identifier = "DOID:0050742"
WITH
[
...
] AS degrees, path

WITH sum(reduce(pdp = 1.0, d in degrees| pdp * d ^ -0.4)) AS DWPC

MATCH path = (n0:Compound)-[:BINDS_CbG]-(n1)-[:PARTICIPATES_GpPW]-(n4:Disease)
WHERE n0.identifier = "DB01156"
AND n4.identifier = "DOID:0050742"
WITH
[
...
] AS degrees, path, DWPC

WITH path, DWPC, reduce(pdp = 1.0, d in degrees| pdp * d ^ -0.4) AS PDP
RETURN
path,
PDP,
100 * (PDP / DWPC) AS PERCENT_OF_DWPC

ORDER BY PERCENT_OF_DWPC DESC

1 Ответ

0 голосов
/ 18 января 2019

Вы можете заменить этот фрагмент:

WITH path, PDP, sum(PDP) AS DWPC
RETURN
  path,
  PDP,
  100 * (PDP / DWPC) AS PERCENT_OF_DWPC
ORDER BY PERCENT_OF_DWPC DESC

с этим:

WITH path, collect(PDP) AS pdps, sum(PDP) AS DWPC
UNWIND pdps AS PDP
RETURN
  path,
  PDP,
  100 * (tofloat(PDP) / DWPC) AS PERCENT_OF_DWPC
ORDER BY PERCENT_OF_DWPC DESC

Исходное предложение WITH имеет 2 "ключа группировки", path и PDP, поэтому агрегирующая функция sum() будет суммироваться по разным парам path и PDP ( другими словами, он будет использовать только один PDP в каждой сумме), что не соответствует вашим ожиданиям.

В новом предложении WITH добавлено использование функции агрегирования collect() для сбора всех значений PDP. Поскольку в этом новом предложении теперь есть только один неагрегирующий термин, path, этот термин используется как полный ключ группировки (для обеих функций). Это приводит к тому, что функция sum() фактически суммирует по всем PDP значениям для одного и того же path. Предложение UNWIND затем используется для разделения отдельных значений PDP. Кроме того, я предполагаю, что PDP является целым числом, поэтому функция tofloat() используется для гарантии того, что деление не выполняет целочисленное усечение.

[UPDATE]

Если вам действительно нужно вычислить сумму DWPC по всем path значениям, то новый фрагмент кода должен быть немного более сложным:

WITH path, collect(PDP) AS pdps, sum(PDP) AS sum1
WITH collect({path: path, pdps: pdps}) AS allData, sum(sum1) AS DWPC
UNWIND allData AS data
UNWIND data.pdps AS PDP
RETURN
  data.path AS path,
  PDP,
  100 * (tofloat(PDP) / DWPC) AS PERCENT_OF_DWPC
ORDER BY PERCENT_OF_DWPC DESC
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...