假设您有一个neo4j图,它有10万个“颜色”节点和5万个“绘制”节点。每个绘图节点都有一个与50到100种颜色的“包含”关系。我们还可以说,您有200个“聚合颜色”节点,每个节点与大约1000种颜色有关系。聚合颜色节点包含一个标量权重。最后,创建一个与10-20聚合颜色相关的“调色板”节点。
我想要一个node4j密码查询,该查询根据绘画中的颜色来识别前10幅绘画,并且具有最高的加权聚合颜色之和。
让
c represent a color node
a represent a aggregate color node
p represent a painting
l represent a palette所以
(p)-[:contains]->(c)
(a)-[:aggregates]->(c)
(l)-[:uses]->(a)假设我有一个名为"MY_PALETTE“的调色板,这个查询将根据唯一的聚合颜色的匹配数告诉我前10幅绘画。
MATCH (l)-[:uses]->(a)-[:contains]->(c) WHERE l.name = 'MY_PALETTE'
WITH a MATCH (p)-[:contains]->(c), (a)-[:aggregates]->(c)
WITH p, a RETURN p.name, COUNT(DISTINCT a) ORDER BY COUNT(DISTINCT a)
DESC LIMIT 10;我要按加权和计算的最上面的画。如果所有的权重都是1,这将给出正确的答案。
看来我不能检查退货条款中的一个。
请注意,我只想计数每种聚合颜色一次,即使绘画包含几种颜色的聚合颜色。
我希望能够添加新的调色板,只需要添加调色板和聚合颜色之间的关系。
有什么建议吗?
发布于 2018-03-21 22:43:05
您的查询有几个bug。第一个MATCH应该是寻找a和c之间的aggregates关系(而不是contains关系)。第一个WITH子句不是向前传递c值。
以下是该查询的一种简化和更有效的形式:
MATCH (l:Palette)-[:uses]->(a)-[:aggregates]->()<-[:contains]-(p)
WHERE l.name = 'MY_PALETTE'
WITH p, COUNT(DISTINCT a) AS aggregate_count
RETURN p.name AS palette_name, aggregate_count
ORDER BY aggregate_count DESC
LIMIT 10;要按总总重量(最多一次使用aggregate的权重,即使该集合中的多种颜色由一幅绘画使用)获得前10幅绘画,您可以这样做:
MATCH (l:Palette)-[:uses]->(a)-[:aggregates]->()<-[:contains]-(p)
WHERE l.name = 'MY_PALETTE'
WITH DISTINCT p, a
RETURN p.name AS palette_name, SUM(a.weight) AS aggregate_weight_total
ORDER BY aggregate_weight_total DESC
LIMIT 10;请注意,如果有多个同名的绘画(例如,“静物”),上述查询将多次返回相同的palette_name。为了减少这种可能性,您还可能希望为每幅画返回一个唯一的属性值(例如,p.id)。
此外,您应该考虑在:Palette(name)上创建索引(或唯一性约束),以加快按名称查找调色板。
https://stackoverflow.com/questions/49398447
复制相似问题