我的人员和部门具有以下可能的关系
(p:Person)-[:WORKS_IN]->(d:Department)
(employee:Person)-[:REPORTS_TO]->(manager:Person)
(child:Department)-[:UNIT_OF]->(parent:Department)
Run Code Online (Sandbox Code Playgroud)
我没有获得识别特定部门经理的信息,但是在任何部门中,关系最为密切的[:REPORTS_TO]人都是老板。我正在尝试获取与该部门中“报告给”最多的人匹配的所有部门的列表,但是我却非常失败。
更复杂的是,部门内有“非部门”子组,其定义是一个人可以向部门中不是部门经理的人报告。
我正在寻找一种输出所有部门ID的列表的方法,该列表具有该部门中报告最多的员工的ID。每个部门一行是理想的。
谢谢
Dave的回答相当不错,但是却漏掉了部门经理因举报最多而绑架的情况。如果关系对您无所谓,请坚持戴夫的回答。
该查询有几个额外的步骤,但是应该返回每个部门中报告数量最多的经理,包括那些并列的经理。
// 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
Run Code Online (Sandbox Code Playgroud)
这是部门和经理的返回节点,但是您可以轻松地将其更改为从其属性中输出ID或名称。
Cypher中的聚合按剩余的非聚合列分组,这就是为什么我们manager
在计算时从范围中删除maxReports
;这样可以确保汇总是按部门而不是按经理和部门进行的(这与按经理的报告相同)。
可能有一种方法可以使用Neo4j 3.1的即将到来的更改(截至2016年9月初仍在开发中)进行优化,它们确实具有模式理解功能,就像子查询一样,可能非常有用。