我将描述我的数据模型以及一些我想实现的东西。 我有Neo4j作为数据库,现在数据结构是不可变的,因此“仅创建其他标签更改的节点”这样的建议不适用于我的情况,对不起!
在Neo4j中,我有Node:Category
,Node:Goods
,Node:Property
。货物可能与财产有许多关系。例如:(:Goods {name: "Chair"})-[:PROP]-(:Property)
。此Node:Goods
与两个Node:Properties
有关-价格和材料。您可能已经猜到了-我有很多Node:Goods
,每个人都与价格和材料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值分组,以找到max和min以及将其传递给前端过滤器的变量?
我的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的方法。感谢您的帮助和提示,谢谢!
答案 0 :(得分:2)
在处理min()
type:Properties时,您可以只使用max()
和num
聚合函数。
要解决这三个变体,您可以使用如下查询:
MATCH (good:Good)
WITH good
OPTIONAL MATCH (good)-[:PROP]-(p:Property {type:'text'})
WITH good, p.name as name, collect(p.value) as variants
WITH good, collect({name:name, type:'text', variants:variants}) as properties
OPTIONAL MATCH (good)-[:PROP]-(p:Property {type:'num'})
WITH good, properties, p.name as name, min(p.value) as min, max(p.value) as max
WITH good, properties + collect({name:name, type:'num', min:min, max:max}) as properties
WITH good, properties + [(good)-[:PROP]-(p:Property {type:'bool'}) | p {.name, type:'bool'}] as properties
RETURN good, properties
答案 1 :(得分:2)
汇总时可以使用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