我将描述我的数据模型,以及我想要实现的一些目标。 我有 Neo4j 作为 db,数据结构目前是不可变的,所以像“只需创建其他带有更改标签的节点”这样的建议不适合我的情况,提前抱歉!
在 Neo4j 中我有 Node:Category
, Node:Goods
, Node:Property
. cargo 可能与属性(property)有很多关系。例如:(:Goods {name: "Chair"})-[:PROP]-(:Property)
.这Node:Goods
与两个有关Node:Properties
- 价格和 Material 。你可能已经猜到了——我有很多 Node:Goods
每一个都与价格和 Material 有关Node:Property
.
我需要为此结构构建具有过滤能力的前端客户端 Node:Goods
通过其相关Node:Property
.例如我需要所有 Node:Goods
与 Node:Property
有关与 {name:"Price"}
和 {value: >40, <100}
.我在这里问过这个问题,@InverseFalcon 得到了很好的答案:
...
WITH g, size([(g)-[:Prop]-(p:Property) WHERE p.name = "Price" AND 190 < p.value < 320 | p]) > 0 as priceRange
WHERE priceRange
...
当我知道过滤什么以及如何过滤时,这个解决方案就能完美运行。我的问题是如何按名称对所有 Node:Propery 值进行分组,以找到最大值和最小值以及变体以将它们传递给前端过滤器?
我的 Node:Property
看起来像这样:
{
"name":"Price",
"type":"num", //text, bool
"value":245
}
我期待这样的事情(但不管响应是否会不那么漂亮):
{
"Category": "Chair",
"Goods": 157,
"Properties": [
{ "Name": "Material", "type":"text", "variants": "Metal", "Oak", "Maple" },
{ "Name": "Price", "type": "num", "min": 25, "max": 490 },
{ "Name": "InStock", "type": "bool" },
...
]
}
我试图通过 UNWIND 和 FOREACH 来实现这一点,但我发现无法在 FOREACH 中进行 RETURN。我感谢任何帮助和提示,谢谢!
最佳答案
聚合时可以使用CASE:
MATCH (C:Category)
OPTIONAL MATCH (C)-[:Good]->(G:Goods)-[:Prop]->(P:Property)
WITH C,
count(DISTINCT G) AS cnt,
P.Name AS name, P.type AS type,
CASE WHEN P.type = "num" THEN min(P.value) ELSE null END AS min,
CASE WHEN P.type = "num" THEN max(P.value) ELSE null END AS max,
CASE WHEN P.type = "text" THEN collect(P.value) ELSE null END AS variants
WITH C.name AS name, cnt,
{name: name, type: type, min: min, max: max, variants: variants } AS prop
RETURN {Category: name, Goods: cnt, Properties: collect(prop)} AS category
关于database - 如何通过 Cypher Neo4j 中的其他 Prop 对 Node Prop 的值进行分组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52038068/