2016-09-06 11 views
0

は私がの管理者を特定するための情報を取得していない以下の可能性の関係私はCYPHERにおける一連のノードに関連した最も接続された人をどのように見つけるか/のNeo4j

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

を持つ人々や部門を持っています特定の部門ですが、どの部門でも、最も多くの[:REPORTS_TO]関係を持つ人がボスになる可能性があります。私はその部門の人に「報告された」と最も一致したすべての部門のリストを取得しようとしていますが、私はひどく失敗しています。

さらに複雑にするために、部署内には「非部署」のサブグループがあり、部門のマネージャではない部門の担当者に報告することができます。

私は、その部門の最も報告された従業員のIDを持つすべての部門IDのリストを出力する方法を探しています。部門ごとに1つの行が理想的です。

ありがとうございました

答えて

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の集約は、残りの非集約列によってグループ化されます。そのため、maxReportsを計算するとスコープからmanagerが削除されます。マネージャーごとと部門ごとではなく、部門ごとに集計が行われます(マネージャーごとのレポートと同じです)。

Neo4j 3.1の今後の変更(2016年9月上旬にはまだ開発中)を使用して最適化する方法があるかもしれませんが、非常に有用なサブクエリのように機能するパターン理解機能があります。

+1

もう一度ありがとうございます。この答えは、私がシリアルWITHの力を理解するのを助け、サイズ(パターン)オプションに私をもたらしました。 – Daniel

2

私はこのような何かが始まったかもしれないと思います。

REPORTS_TOの関係を持つPersonのエントリをすべて見つけて、どの部門に所属しているのかを調べます。部門と最高のreports_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  
1

collectステートメントは必要ありません。関係の数は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 

このクエリは、管理者へのすべての報告先との関係をカウントし、管理者の名前、レポートや部門の数を返します。

ORDER BYまたはGROUP BYステートメントが必要な場合は、マネージャごと、部門ごとのレポートのランク付けにそれらを追加できます。

関連する問題