在连接的节点上查找特定关系的属性

时间:2015-03-23 21:55:59

标签: neo4j cypher

我的示例图的创建代码是:

CREATE (a:Product { name:"A" }),(b:Product { name:"B" }),(c:Product { name:"C" }),(d:Product { name:"D" }),(e:Product { name:"E" }),(f:Product { name:"F" }),(s1:Supplier { name:"s1" }),(s2:Supplier { name:"s2" }),(s3:Supplier { name:"s3" }),(c)-[:Parent]->(b),(b)-[:Parent]->(a),(f)-[:Parent]->(d),(e)-[:Parent]->(d),(d)-[:Parent]->(a),(s1)-[:PRICE { value:10 }]->(a),(s2)-[:PRICE { value:20 }]->(c),(s3)-[:PRICE { value:30 }]->(d)

示例图片的图片:

Graph

这个想法是E和F“继承”价格与D的PRICE关系,C的价格来自其直接传入的PRICE关系而B继承自A.不用说生产图更深,价格水平不同“遗产”。实际上,产品可能有多个价格(多个供应商),但这是为了以后。 现在,我想创建一个查询,为每个产品生成价格表。

我对cypher查询的问题是使价格继承成为通用的,因为价格可能来自任意数量的Parent跳数的节点。

欢迎任何建议。

编辑:只是为了澄清:价格仅从具有传入PRICE关系的第一个父母继承。因此,例如,E和F只从D中获取价格。

编辑编号2:

感谢所有回复。妮可,我刚刚看到你的答案,因为我回来发布我的答案,所以我把它添加为编辑而不是答案,并将你的标记作为原始问题的答案,因为我认为你的答案最接近什么我最终想出来了。

我学会发布这个问题的一件事不是过多地简化问题,我确实暗示了许多供应商的作品,但这应该是中心的。

有了这个,我想发布我提出的解决方案。

创建新图表的代码

CREATE (a:Product { name:"A" }),(b:Product { name:"B" }),(c:Product { name:"C" }),(d:Product { name:"D" }),(e:Product { name:"E" }),(f:Product { name:"F" }),(s1:Supplier { name:"s1" }),(s2:Supplier { name:"s2" }),(s3:Supplier { name:"s3" }),(c)-[:Parent]->(b),(b)-[:Parent]->(a),(f)-[:Parent]->(d),(e)-[:Parent]->(d),(d)-[:Parent]->(a),(s1)-[:PRICE { value:10 }]->(a),(s2)-[:PRICE { value:20 }]->(c),(s3)-[:PRICE { value:30 }]->(d),(s3)-[:PRICE{value:40}]->(f)

enter image description here

从供应商S3向产品F添加了另一个价格报价。价格表包含按关系明确规定的产品价格或从母产品继承价格,但仅继承任何给定供应商的第一个价格。所以在新图表F中得到了价格 直接来自S3,不继承S3的价格,但继续并从A继承S1的价格。

我目前使用的查询如下:

MATCH
path = ((product)-[:Parent*0..]->(parentProduct)<-[price:PRICE]-(supplier:Supplier))
where single ( code in nodes(path) where (code)<-[:PRICE]-(supplier) )
with product,parentProduct,price,supplier
order by price.value
with product.name as ProductName, collect([supplier.name,price.value]) as PriceList
order by ProductName
return ProductName,PriceList

给出以下价格表: enter image description here

3 个答案:

答案 0 :(得分:1)

这是我将如何做到的:

MATCH path = (p:Product)-[:Parent*0..]->(:Product)<-[r:PRICE]-(:Supplier)
WITH p, LENGTH(path) AS len, r.value AS prices
ORDER BY p.name, len
RETURN p.name AS product, HEAD(COLLECT(prices)) AS price
ORDER BY product

结果:

product price
      A    10
      B    10
      C    20
      D    30
      E    30
      F    30

这从一个产品节点开始,并遵循父关系到最近的产品,并具有传入的PRICE关系。请注意,* 0 ..负责具有直接传入PRICE关系的产品。对于每个产品,路径按长度递增排序,您可以从最短路径获得价格。

见这里:http://console.neo4j.org/r/ovhajx

答案 1 :(得分:0)

您可以尝试这样的事情:

match (s:Supplier)-[p:PRICE]->(prod:Product)<-[:parent*]-(other:Product)
where not (other)<-[:PRICE]-(s2:Supplier)
RETURN prod, other, p;

这会尝试构建与产品关联的所有价格的列表,在父链接返回具有相同价格的other产品之后。 where子句保证由:parent关系链接的其他产品没有自己的本地价格。

答案 2 :(得分:0)

怎么样

MATCH path=(p:Product)-[:Parent*0..]->(parent)<-[:PRICE]-(s)
WITH path,head(nodes(path)) as product
WITH product,min(length(path)) as size,collect(path) as allPaths 
UNWIND allPaths as path
WITH product,size,path,length(path) as length
WHERE size=length
RETURN product,last(relationships(path)).value;

这匹配从产品到供应商的路径,确定链中第一个供应商的最短路径,然后过滤该长度。