neo4j查询中的加权和

时间:2018-03-21 04:54:12

标签: neo4j cypher

让我们假设你有一个拥有100,000"颜色"的neo4j图表。节点和50,000"绘画"节点。每个绘制节点都有一个"包含"与50到100种颜色的关系。让我们再说200"聚合颜色"节点各自与〜1000种颜色的关系。聚合颜色节点包含标量权重。最后,您创建一个"调色板"与10-20种聚合颜色关系的节点。

我想要一个node4j cypher查询,该查询根据绘画中的颜色识别前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,这将给出正确的答案。

似乎我无法在RETURN子句中检查。

请注意,即使绘画中包含聚合颜色中的多种颜色,我也只想计算每个聚合颜色一次。

我希望能够添加新的调色板,只需添加调色板和聚合颜色之间的关系。

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

您的查询有几个错误。第一个MATCH应该在aggregatescontains之间寻找a关系(不是c关系)。并且第一个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)上创建索引(或唯一性约束),以加快按名称查找调色板的速度。