测试neo4j / spring数据中是否存在关系

时间:2017-02-03 10:35:26

标签: neo4j cypher spring-data-neo4j

我试图解决这个简单的问题,如果在图表中使用"知道"关系,有些人A知道某个人B.理想情况下我会用真或假来回答这个问题,但我没有解决这个问题。

我在另一个StackOverflow question中找到了以下内容,这几乎是我想要的,除了回答我的问题之外,它还会更改图表:

MATCH  (p:Person {userId: {0}}), (b:Person {userId: {1}}) 
MERGE (p)-[r:KNOWS]->(b) 
ON CREATE SET r.alreadyExisted=false 
ON MATCH SET r.alreadyExisted=true 
RETURN r.alreadyExisted;

最后,我想把它放在像这样的

的Spring Neo4J存储库中
public interface PersonRepository extends GraphRepository<Person> {
    boolean knows(final Long me, final Long other);
}

这意味着如果有一种方法可以在没有cypher的情况下使用Spring Query和Finder方法,那也没关系。

2 个答案:

答案 0 :(得分:6)

Cypher对此的查询很简单,这里的关键是EXISTS()函数,如果图中存在赋予函数的模式,它将返回一个布尔值。

这是Cypher的查询。

MATCH  (p:Person {userId: {0}}), (b:Person {userId: {1}}) 
RETURN EXISTS( (p)-[:KNOWS]-(b) )

你甚至可以使它更简洁:

RETURN EXISTS( (:Person {userId: {0}})-[:KNOWS]-(:Person {userId: {1}}) )

答案 1 :(得分:2)

作为对@InverseFalcon 所说的补充说明

// first
MATCH  (p:Person {userId: {0}}), (b:Person {userId: {1}}) 
RETURN exists( (p)-[:KNOWS]-(b) )
// second
RETURN exists( (:Person {userId: {0}})-[:KNOWS]-(:Person {userId: {1}}) )

提供的两个示例之间有一个 difference

第一个在断开连接的模式之间构建笛卡尔积。

<块引用>

如果查询的一部分包含多个断开连接的模式,这将在所有这些部分之间构建笛卡尔积。这可能会产生大量数据并减慢查询处理速度。虽然偶尔有意,但通常可以重新制定查询以避免使用此交叉产品,也许通过添加不同部分之间的关​​系或使用 OPTIONAL MATCH

这仅仅意味着如果你的数据库中有 5 个人 P={0,1,2,3,4};

  • 第一个查询几乎检查每个两人之间是否存在 |A|x|A| = 5x5 = 25 可能的路径,其中第一个 Person 节点的 id 等于` 0,第二个 Person 节点的 id 等于 1。
  • 第二个查询检查来自 ID 为 0 的 Person 节点和 ID 为 1 的 Person 节点的路径是否存在。

也导致 exists 可以是函数和关键字,约定建议将函数写成小写,其他写成大写。

// Use an existential sub-query to filter.
WHERE EXISTS {
  MATCH (n)-->(m) WHERE n.userId = m.userId
} 

此外,您可以将返回值重命名为一些新变量,例如:

RETURN exists( (:Person {userId: {0}})-[:KNOWS]-(:Person {userId: {1}}) ) as knows