测试 neo4j / spring 数据中是否存在关系
Test if relationship exists in neo4j / spring data
我正在尝试解决一个简单的问题,如果在具有 "knows" 关系的图中,某人 A 认识某人 B。理想情况下,我会用真或假来回答这个问题,但我'我没能解决这个问题。
我在另一个 Whosebug 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);
}
这意味着如果有一种不用密码的方法 - 使用 Springs Query 和 Finder 方法,那也很好。
Cypher 对此的查询很简单,这里的关键是 EXISTS() 函数,如果给定函数的模式存在于图中,它将 return 一个布尔值。
这是 Cypher 查询。
MATCH (p:Person {userId: {0}}), (b:Person {userId: {1}})
RETURN EXISTS( (p)-[:KNOWS]-(b) )
你甚至可以让它更简洁:
RETURN EXISTS( (:Person {userId: {0}})-[:KNOWS]-(:Person {userId: {1}}) )
作为@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
:
第一个在断开连接的模式之间构建笛卡尔积。
If a part of a query contains multiple disconnected patterns, this will build a Cartesian product between all those parts. This may produce a large amount of data and slow down query processing. While occasionally intended, it may often be possible to reformulate the query that avoids the use of this cross product, perhaps by adding a relationship between the different parts or by using OPTIONAL MATCH
这仅仅意味着如果你的数据库中有 5 个人 P={0,1,2,3,4};
- 第一个查询几乎检查了第一个 Person 节点的 id 等于 0 和第二个 Person 节点的 id 等于 1 的每个两人之间是否存在
|A|x|A| = 5x5 = 25
可能路径。
- 第二个查询检查是否存在来自 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 值重命名为某个新变量,例如:
RETURN exists( (:Person {userId: {0}})-[:KNOWS]-(:Person {userId: {1}}) ) as knows
我正在尝试解决一个简单的问题,如果在具有 "knows" 关系的图中,某人 A 认识某人 B。理想情况下,我会用真或假来回答这个问题,但我'我没能解决这个问题。
我在另一个 Whosebug 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);
}
这意味着如果有一种不用密码的方法 - 使用 Springs Query 和 Finder 方法,那也很好。
Cypher 对此的查询很简单,这里的关键是 EXISTS() 函数,如果给定函数的模式存在于图中,它将 return 一个布尔值。
这是 Cypher 查询。
MATCH (p:Person {userId: {0}}), (b:Person {userId: {1}})
RETURN EXISTS( (p)-[:KNOWS]-(b) )
你甚至可以让它更简洁:
RETURN EXISTS( (:Person {userId: {0}})-[:KNOWS]-(:Person {userId: {1}}) )
作为@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
:
第一个在断开连接的模式之间构建笛卡尔积。
If a part of a query contains multiple disconnected patterns, this will build a Cartesian product between all those parts. This may produce a large amount of data and slow down query processing. While occasionally intended, it may often be possible to reformulate the query that avoids the use of this cross product, perhaps by adding a relationship between the different parts or by using OPTIONAL MATCH
这仅仅意味着如果你的数据库中有 5 个人 P={0,1,2,3,4};
- 第一个查询几乎检查了第一个 Person 节点的 id 等于 0 和第二个 Person 节点的 id 等于 1 的每个两人之间是否存在
|A|x|A| = 5x5 = 25
可能路径。 - 第二个查询检查是否存在来自 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 值重命名为某个新变量,例如:
RETURN exists( (:Person {userId: {0}})-[:KNOWS]-(:Person {userId: {1}}) ) as knows