简体   繁体   中英

Neo4j how to get (DISTINCT) all nodes and relationships with at least one node in common?

I have been experimenting with neo4j and cypher lately but I don't quite manage to get the following query correctly. I would like to return all employees that share at least one project with a given employee and the projects they worked on. It is perhaps simpler if described with an example:

员工和项目图

The desired outcome for the graph above for the input being employee 1 is:

Employee Project
0 A
1 A
1 B
4 A

I tried the following query but it returns duplicated relationships:

MATCH (a0:Employee {name:1})-[:WORKS]->(b0:Project) 
MATCH (b0)<-[:WORKS]-(a:Employee) 
MATCH (a)-[:WORKS]->(b:Project) 
RETURN a.name AS employee, b.name AS project 
ORDER BY employee, project
Employee Project
0 A
1 A
1 A
1 B
1 B
4 A

Thank you in advance for your help.

Note: These queries can be used to create the graph above

CREATE (:Employee {name: 0}), 
       (:Employee {name: 1}), 
       (:Employee {name: 2}),  
       (:Employee {name: 3}), 
       (:Employee {name: 4}), 
       (:Project {name: 'A'}), 
       (:Project {name: 'B'}), 
       (:Project {name: 'C'})
MATCH (e:Employee), (p:Project) WHERE e.name=0 AND p.name='A' CREATE (e)-[:WORKS]->(p)
MATCH (e:Employee), (p:Project) WHERE e.name=1 AND p.name='A' CREATE (e)-[:WORKS]->(p)
MATCH (e:Employee), (p:Project) WHERE e.name=1 AND p.name='B' CREATE (e)-[:WORKS]->(p)
MATCH (e:Employee), (p:Project) WHERE e.name=4 AND p.name='A' CREATE (e)-[:WORKS]->(p)
MATCH (e:Employee), (p:Project) WHERE e.name=3 AND p.name='C' CREATE (e)-[:WORKS]->(p)

After struggling with it for a couple hours, I found a solution. I am not sure it is efficient though. In a way, the answer was already in the question - DISTINCT. This query does the job:

MATCH (a0:Employee {name:0})-[:WORKS]->(b0:Project) 
MATCH (b0)<-[:WORKS]-(a:Employee)
WITH DISTINCT(a)
MATCH (a)-[:WORKS]->(b:Project) 
RETURN a.name AS employee, b.name AS project 
ORDER BY employee, project

You seem to want the answer to the question: given the projects a certain employee works at, find all employees working on those projects.

You can answer this with a simple query:

MATCH (:Employee {name:1})-[:WORKS]->(b:Project) 
MATCH (a:Employee)-[:WORKS]->(b)
RETURN a.name AS employee, b.name AS project 
ORDER BY employee, project

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM