Создайте узел и назначьте ему сумму столбца таблицы в Cypher Neo4j - PullRequest
0 голосов
/ 06 февраля 2019

Я пытаюсь выяснить, как реализовать операцию OLAP Roll-up в Cypher.Я застрял в поиске, как создать узел, а затем назначить ему сумму столбца таблицы в Cypher.В частности, я пытаюсь добиться этого результата: Результат кода [РЕДАКТИРОВАНИЕ] С помощью этого кода я получаю результат, как показано на рисунке:

MATCH(p:Product)
WITH sum(p.unitsInStock) as SommeUnits, p.supplierID as Supplier, p.reorderLevel as ReordLevel
CREATE(reord:Product {productName : "TotalReord", unitsInStock : SommeUnits})
RETURN ReordLevel,Supplier, SommeUnits
ORDER BY ReordLevel

Отношения: Поставщик- [: SUPPLIES] -> (Product) Атрибуты продукта: unitsInStock, productName, productId, unitsInOrder, supplierID

Проблема заключается в том, что этот код работает неправильно, поскольку он генерирует не только один узел, но и множители, и результатто, что я получаю, получается только в том случае, если я проиграю запрос дважды.

1 Ответ

0 голосов
/ 06 февраля 2019

Агрегирующие функции , такие как SUM, используют неагрегированные элементы в том же предложении (WITH или RETURN) в качестве "ключей группировки".Итак, ваше предложение WITH генерирует значение SommeUnits для каждой отдельной комбинации SommeUnits/ReordLevel.И ваш CREATE вызывается для каждого SommeUnits значения.

Этот запрос должен работать правильно (при условии, что вы хотите, чтобы каждая возвращаемая запись имела одинаковое значение SommeUnits):

MATCH(p:Product) WHERE p.productName <> "TotalReord"
WITH SUM(p.unitsInStock) AS SommeUnits, COLLECT(p) AS ps
MERGE(t:Product {productName: "TotalReord"})
SET t.unitsInStock = SommeUnits
WITH ps, SommeUnits
UNWIND ps AS p
RETURN p.reorderLevel AS ReordLevel, p.supplierID AS Supplier, SommeUnits
ORDER BY ReordLevel

В этом запросе используется MERGE, чтобы избежать создания дублирующих узлов "TotalReord" при каждом вызове этого запроса.И предложение WHERE отфильтровывает узел «TotalReord», так что его существующее значение unitsInStock не будет использоваться при вычислении новой суммы, если оно будет накачано.

Если вы действительно хотите, чтобы каждая возвращаемая запись имеласумма только для комбинации SommeUnits/ReordLevel этой записи, вы можете сделать это:

MATCH(p:Product) WHERE p.productName <> "TotalReord"
WITH SUM(p.unitsInStock) AS u, p.reorderLevel AS r, p.supplierID AS s
WITH COLLECT({u:u, r:r, s:s}) AS data, SUM(u) AS total
MERGE(t:Product {productName: "TotalReord"})
SET t.unitsInStock = total
WITH data
UNWIND data AS d
RETURN d.r AS ReordLevel, d.s AS Supplier, d.u AS SommeUnits
ORDER BY ReordLevel

[ОБНОВЛЕНО]

Наконец, если вы хотите выполнить предыдущий запрос, но также получить общую суммуэтот запрос покажет итоговое значение в виде четвертого значения в каждой возвращаемой записи:

MATCH(p:Product) WHERE p.productName <> "TotalReord"
WITH SUM(p.unitsInStock) AS u, p.reorderLevel AS r, p.supplierID AS s
WITH COLLECT({u:u, r:r, s:s}) AS data, SUM(u) AS total
MERGE(t:Product {productName: "TotalReord"})
SET t.unitsInStock = total
WITH data, total
UNWIND data AS d
RETURN d.r AS ReordLevel, d.s AS Supplier, d.u AS SommeUnits, total
ORDER BY ReordLevel
...