如何在cypher / neo4j中找到与一系列节点关联的最多连接人员

时间:2016-09-06 16:12:31

标签: neo4j cypher

我的人员和部门有以下可能的关系

(p:Person)-[:WORKS_IN]->(d:Department)
(employee:Person)-[:REPORTS_TO]->(manager:Person)
(child:Department)-[:UNIT_OF]->(parent:Department)

我没有获取信息来识别特定部门的经理,但在任何部门中,具有最多[:REPORTS_TO]关系的人可能是老板。我试图获取所有与最多的部门相关的列表"报告给"那个部门的人,但我非常失败。

为了使它更复杂,有非部门的"部门内的子组,由一个人可以向部门中不是该部门经理的人报告的事实来定义。

我正在寻找一种方法来输出所有部门ID的列表,其中包含该部门中报告最多的员工的ID。每个部门一排是理想的。

由于

3 个答案:

答案 0 :(得分:4)

戴夫的答案非常好,但它错过了一个部门的经理与最多报道相关的案例。如果关系对你不重要,请坚持戴夫的回答。

此查询还有一些额外的步骤,但应该返回报告数量最多的每个部门的经理,包括那些合并的人。

// first find managers with people reporting to them
MATCH (manager:Person)-[:WORKS_IN]->(d:Department)
WHERE EXISTS((:Person)-[:REPORTS_TO]->(manager))
// get the number of reporters for each manager, then find the max for all managers in each department per department
WITH d, manager, size( (:Person)-[:REPORTS_TO]->(manager) ) as reportSize
WITH d, max(reportSize) as maxReports
// find all managers in the department with the department's max report size
MATCH (manager:Person)-[:WORKS_IN]->(d)
WHERE size( (:Person)-[:REPORTS_TO]->(manager) ) = maxReports
RETURN d, COLLECT(manager) as topManager, maxReports

这是为部门和经理返回节点,但您可以轻松地将其更改为从其属性输出ID或名称。

Cypher中的聚合按剩余的非聚合列进行分组,这就是我们在计算manager时从范围中删除maxReports的原因。确保按部门进行聚合,而不是按经理和部门进行聚合(这与每个经理的报告相同)。

可能有一种方法可以使用Neo4j 3.1即将发生的变化进行优化(截至2016年9月初仍处于开发阶段),它们确实具有模式理解功能,其功能类似于可能非常有用的子查询。 / p>

答案 1 :(得分:2)

我认为这样的事情可能会让你开始。

查找具有Person关系的所有REPORTS_TO条目,然后找到他们所在的部门。按部门和最高报告_to排序结果集。汇总每个部门的结果,然后只返回第一个。

match (:Person)-[:REPORTS_TO]->(manager:Person)
with manager
match (manager)-[:WORKS_IN]->(d:Department)
with d.name as dept,manager.name as manager, count(*) as size
order by dept, size desc
with dept, collect([manager,size]) as managers
return dept, managers[0][0] as manager, managers[0][1] as size 
order by size desc, dept    

答案 2 :(得分:1)

你不应该需要任何收集声明,只需要一个关系#的单一计数。

MATCH (worker:Person)-[REPORTS_TO]->(manager:Person), 
      (manager:Person)-[WORKS_IN]->(department:Department)
WITH manager.name as managerName, 
     count(*) AS reportCount, 
     department.name as departmentName
WHERE reportCount > 0
RETURN managerName, reportCount, departmentName

此查询将计算与经理的所有REPORTS_TO关系,并返回经理的姓名,报告数量和部门。

如果您需要ORDER BY或GROUP BY语句,您可以将这些添加到每个部门的每个经理的报告数量级别。