在Neo4j中如何从另一个

时间:2017-03-29 05:41:20

标签: neo4j cypher

说我有两个问题

MATCH (a:User)-[:Likes]->(b:Object) WHERE <condition on b> RETURN a

MATCH (a:User)-[:HasVisited]->(c:Location) WHERE <condition on c> RETURN a

我想把两者结合起来。这样我从query2得到的结果不适合query1

到目前为止,我已尝试过以下

MATCH (a:User)-[:Likes]->(b:Object) MATCH (a:User)-[:HasVisited]->(c:Location) WHERE <condition on c> AND NOT <condition on b> RETURN a

但这种方法并不排除我想要排除的所有结果。

MATCH (a:User)-[:Likes]->(b:Object) WHERE <condition on b> WITH collect(DISTINCT a) as exc MATCH (a:User)-[:HasVisited]->(c:Location) WHERE <condition on c> AND NOT a IN exc RETURN a

这给出了正确的结果,但是一旦query1和query2开始变得更加复杂,效率就会降低

我也试过

MATCH (a:User)-[:Likes]->(b:Object) WHERE <condition on b> WITH collect(DISTINCT a) as exc MATCH (a:User) WHERE NOT a IN exc WITH a MATCH MATCH (a:User)-[:HasVisited]->(c:Location) WHERE <condition on c> RETURN a

我曾希望减少可以提前匹配的节点数量可以提高性能,但这种方法似乎没有任何改善。

是否有一种标准/更好的方法可以排除一个查询与另一个查询匹配的结果?

2 个答案:

答案 0 :(得分:0)

第一个例子的问题是它仍然可以匹配(a:User)-[:Likes]->(b:Object)的某些关系,其中&#39; b&#39;不符合条件,而你想完全排除&#39; a&#39;从结果中选择的&#39; b&#39;。

要实现此目的,您可以使用OPTIONAL MATCH子句:

MATCH (a:User)-[:HasVisited]->(c:Location)
WHERE <condition on c>
OPTIONAL MATCH (a)-[:Likes]->(b:Object)
WHERE <condition on b>
WITH a, b, c
WHERE b IS NULL
RETURN a

答案 1 :(得分:0)

你可以试试这样的:

MATCH (U1:User)-[:HasVisited]->(L:Location) 
    WHERE <condition on c>
WITH distinct U1
OPTIONAL MATCH (U2:User)-[:Likes]->(O:Object) 
    WHERE U2 = U1 AND 
          <condition on b>
WITH U1, 
     count(U2) as excl 
    WHERE excl = 0
RETURN U1