让我们假设你有一个拥有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子句中检查。
请注意,即使绘画中包含聚合颜色中的多种颜色,我也只想计算每个聚合颜色一次。
我希望能够添加新的调色板,只需添加调色板和聚合颜色之间的关系。
有什么建议吗?
答案 0 :(得分:0)
您的查询有几个错误。第一个MATCH
应该在aggregates
和contains
之间寻找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)
上创建索引(或唯一性约束),以加快按名称查找调色板的速度。