Reputation: 809
I'm trying to solve the simple question, if in a graph with the "knows" relationship, some person A knows some person B. Ideally I would answer this question with either true or false but I'm failing to solve this.
I found the following in another StackOverflow question which is almost what I want, except that apart from just answering my question, it also changes the graph:
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;
In the end I would like to put this in a Spring Neo4J repository like this
public interface PersonRepository extends GraphRepository<Person> {
boolean knows(final Long me, final Long other);
}
That means if there is a way to do it without cypher - using Springs Query and Finder methods, that would be fine too.
Upvotes: 7
Views: 18417
Reputation: 896
As below, cypher query worked for me.
MATCH (sNode{GUID:'ID3456'}), (aNode{ID:AD4567}) RETURN exists( (sNode)-[:my_Relation]-(aNode) )
This gave a result like below
[{'exists( (sNode)-[:my_Relation]-(aNode) )': False}]
Upvotes: 0
Reputation: 2341
As a complementary note to what @InverseFalcon said
// 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}}) )
There is a difference
between the two examples that were provided:
the first one builds a Cartesian product between disconnected patterns.
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
It merely means if you have 5 persons in your database P={0,1,2,3,4};
|A|x|A| = 5x5 = 25
possible path between every two-person where the first Person node has id equals to` 0 and the second Person node has id equals to 1.also cause exists
can be a function and keyword, convention suggests to write functions as lowercase and others as uppercase.
// Use an existential sub-query to filter.
WHERE EXISTS {
MATCH (n)-->(m) WHERE n.userId = m.userId
}
also, you can rename the return value to some new variable for example:
RETURN exists( (:Person {userId: {0}})-[:KNOWS]-(:Person {userId: {1}}) ) as knows
Upvotes: 5
Reputation: 30407
The Cypher query for this is a simple one, the key here is the EXISTS() function, which will return a boolean value if the pattern given to the function exists in the graph.
Here's the Cypher query.
MATCH (p:Person {userId: {0}}), (b:Person {userId: {1}})
RETURN EXISTS( (p)-[:KNOWS]-(b) )
You can even make it more concise:
RETURN EXISTS( (:Person {userId: {0}})-[:KNOWS]-(:Person {userId: {1}}) )
Upvotes: 22