优化多个可选匹配

时间:2016-06-23 13:12:35

标签: neo4j cypher

在这个查询中,我希望匹配所有在他们的简历和我的简历之间拥有共享节点的用户,即[:CONTAINS],或者我们感兴趣的简历中有节点,即[:FOLLOWS] 我想命令查询首先返回我与之共享最多的查询(或者:FOLLOWS或:CONTAINS) 这种尝试有效但成本高(并且速度慢)甚至会使服务器崩溃。

您是否看到了获得所需用户的更好方法?



MATCH (me:User {uuid: "XXX"}) 
OPTIONAL MATCH (me)-[:HAS]->(:Resume)-[:CONTAINS]->(n0:Diploma)<-[:CONTAINS]-(:Resume)<-[:HAS]-(u0:User) WHERE me <> u0 WITH me, COLLECT({u: u0, node: n0}) as rows0 
OPTIONAL MATCH (me)-[:HAS]->(:Resume)-[:CONTAINS]->(n1:DiplomaMajor)<-[:CONTAINS]-(:Resume)<-[:HAS]-(u1:User) WHERE me <> u1 WITH me, COLLECT({u: u1, node: n1}) as rows1, rows0 
OPTIONAL MATCH (me)-[:HAS]->(:Resume)-[:CONTAINS]->(n2:Job)<-[:CONTAINS]-(:Resume)<-[:HAS]-(u2:User) WHERE me <> u2 WITH me, COLLECT({u: u2, node: n2}) as rows2, rows0, rows1 
OPTIONAL MATCH (me)-[:HAS]->(:Resume)-[:IN]->(n3:Location)<-[:IN]-(:Resume)<-[:HAS]-(u3:User) WHERE me <> u3 WITH me, COLLECT({u: u3, node: n3}) as rows3, rows0, rows1, rows2 
OPTIONAL MATCH (me)-[f:FOLLOWS]->(n4:Location)<-[:IN]-(:Resume)<-[:HAS]-(u4:User) WHERE f.is_wish = 1 WITH me, COLLECT({u: u4, node: n4}) as rows4, rows0, rows1, rows2, rows3 
OPTIONAL MATCH (me)-[f:FOLLOWS]->(n5:Diploma)<-[:CONTAINS]-(:Resume)<-[:HAS]-(u5:User) WHERE f.is_wish = 1 WITH me, COLLECT({u: u5, node: n5}) as rows5, rows0, rows1, rows2, rows3, rows4 
OPTIONAL MATCH (me)-[f:FOLLOWS]->(n6:DiplomaMajor)<-[:CONTAINS]-(:Resume)<-[:HAS]-(u6:User) WHERE f.is_wish = 1 WITH me, COLLECT({u: u6, node: n6}) as rows6, rows0, rows1, rows2, rows3, rows4, rows5 
OPTIONAL MATCH (me)-[f:FOLLOWS]->(n7:Job)<-[:CONTAINS]-(:Resume)<-[:HAS]-(u7:User) WHERE f.is_wish = 1 WITH me, COLLECT({u: u7, node: n7}) as rows7, rows0, rows1, rows2, rows3, rows4, rows5, rows6 
UNWIND rows0+rows1+rows2+rows3+rows4+rows5+rows6+rows7 as row WITH DISTINCT row.u AS u, COLLECT(DISTINCT row.node) AS shared_nodes 
WHERE LENGTH(shared_nodes) > 0 
RETURN u, shared_nodes 
ORDER BY LENGTH(shared_nodes) DESC 
SKIP 0 LIMIT 10 
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

MATCH (me:User {uuid: "XXX"}) 
      // The path length from one to two, 
      // and the possible relationship types listed
MATCH (me)-[:HAS|CONTAINS|IN|FOLLOWS*1..2]->(n)
            // Check for the selected node matching label
      WHERE ANY( l in ['Diploma','DiplomaMajor','Job','Location'] 
                 WHERE l in labels(n) )
WITH me, n
      // Find shared user
MATCH (u)-[:HAS|CONTAINS|IN|FOLLOWS*1..2]->(n)
      WHERE me <> u
RETURN u, collect(distinct n) as shared_nodes