Using neo4j find the current user unrelated nodes in neo4j - neo4j

I have a trouble when fetch the unrelated nodes. pls refer the image attached. as per the image "Mother of john" is the current user. i want to find which nodes all are unrelated for "Mother of john"
(Eg: "Father of Mohanraj" , etc.)
here is my query
match (m:member) where id(m) = 36
with m
match (p:member)-[*]-()
with collect(p) as parents
match (w:wedding)<-[:WED_TO]-(i)
where not i in parents
return i
Thanks in advance

In your query, m is not used to filter the results of the second part.
I would go along the lines below:
// return the user
MATCH (m:member) where id(m) = 36
WITH m
// return all members that are not related to m
MATCH (p:member)
WHERE NOT (p)-[:WED_TO|PARENT_FROM*]-(m)
RETURN p

Related

Return nodes with only one specified relationship

i have a graph like this:
What i wanna do, is to return actors, which only played in one specified film.
So for example if I pass an Iron Man 2 id, it should return only Robert Downey. Scarlett Johansson is skipped because she has played in 3 films, and also she has a "IS_FRIEND_WITH" relationship.
This code which i wrote, return all the actors that played in film of id 11 in this case
MATCH (a)
WHERE ID(a) = 11
MATCH (b:Actor)-[:ACTED_IN]-(a:Movie)
RETURN b
If Iron Man 2 would be of Id = 11 it would return Scarlett and Robert Downey. I just want it to return only Robert Downey.
You need to apply another filter to select only nodes that have a single ACTED_IN relationship.
MATCH (a:Movie)
WHERE ID(a) = 11
MATCH (b:Actor)-[:ACTED_IN]-(a)
// apply filter for nodes that have only a single ACTED_IN relationship
WITH b, size((b)-[:ACTED_IN]->()) as number_of_movies
WHERE number_of_movies = 1
RETURN b
I would do
WITH 11 AS movieId
MATCH (a:Actor)
WHERE [(a)-[:ACTED_IN]->(m:Movie) | id(m)] = [movieId]
RETURN a
As an alternative to the other answers you could do
MATCH (a:Movie)
WHERE ID(a) = 11
MATCH (b:Actor)-[:ACTED_IN]->(a)
// Make sure there are no ACTED_IN relationships apart from the one to a
AND NOT (:Movie)<-[:ACTED_IN]-(b)-[:ACTED_IN]->(a)
RETURN b
This might have a minor advantage in that it doesn't first collect all the :ACTED_IN relationships of the actor, but instead can quit the query as soon as it finds an additional relationship.
If you also want to remove the ones that have an IS_FRIENDS_WITH relationship then you can modify the query to
MATCH (a:Movie)
WHERE ID(a) = 11
MATCH (b:Actor)-[:ACTED_IN]->(a)
// Make sure no other relationships exist
AND NOT ()<-[]-(b)-[:ACTED_IN]->(a)
RETURN b
Here is my suggestion:
we can specify the title of the movie to filter the query results,
then we use with to specify the variables that we will pass to the next part, among the variable we pass the number of movies which an actor acted in .
In the second part of the query we verify that the actor has acted only in the given movie.
Finally we collect these actors and return them as list along with the movie.
MATCH(a:Person)-[:ACTED_IN]->(m:Movie {title:'The Matrix'})
WITH size((a)-[:ACTED_IN]->(:Movie)) AS uniqueMovieActor, m as theMovie
MATCH()
WHERE uniqueMovieActor = 1
RETURN collect(DISTINCT actor) as uniqueMovieActors, theMovie

How to get the path with relationships from randomWalk call in Cypher?

I am using Neo4j randomWalk algorithm on a base 2 types of nodes (N1 and N2) and one type of relationship (R1).
The random walk algorithm returns a list of NodeId. The issue here is that I'd like to get the relationships R1 between the nodes of each path.
I've tried the following query :
MATCH (n:N1) WHERE ID(n) = 38
CALL algo.randomWalk.stream(ID(n), 4, 4)
YIELD nodeIds
UNWIND nodeIds as nodeId
OPTIONAL MATCH (l:N1)-[r:R1]-(q:N2)
WHERE (ID(l) = nodeId) AND (ID(q) in nodeIds)
RETURN l,q, nodeIds, nodeId,ID(q), ID(l)
However, this is not a good solution cause it is showing every relationships between node l and node q that are present in nodeIds. Hence I don't get the path.
Do you know how could I solve this problem?
Thanks for your time,
Syndorik
After some research, I found a way to get the nth element and nth+1 element in the same UNWIND loop.
This is what I did :
MATCH (n:Clips) WHERE ID(n) = 39
CALL algo.randomWalk.stream(ID(n),4,1)
YIELD nodeIds
UNWIND RANGE(0,size(nodeIds)-1) as idx
MATCH (l)-[r:R1]-(q)
WHERE ID(l) = nodeIds[idx] and ID(q) = nodeIds[idx+1]
RETURN ID(l), ID(q),nodeIds
With this, I successfully retrieved the path with relations and nodes. Do not hesitate if you have some questions on how it works. The image bellow is what I get.

How to show only the nodes connected to the ones selected using Cypher of Neo4J?

I want to see only the nodes labeled ':Context' that are connected to all (or the maximum) number of the nodes labeled ':Concept'.
I'm currently using a query:
match (c:Concept), (ctx:Context), (c)-[r]->(ctx) where (c.name = 'italy' or c.name = 'pick') return ctx,c;
This gives out the following result:
How would I remove all the unnecessary green nodes (they are the ones of the ':Context' type) and only leave those, which are connected both to "pick" and "italy" :Concept nodes?
I also want to be able to perform the same search for 3 nodes and more. Can't understand what's the best way to do that (with or without APOC).
This query below works:
match (c1:Concept{name:"italy"})-->(ctx:Context)<--(c2:Concept{name:"pick"}) return ctx;
but only for 2 items. What if I want to do the same for 3 or more?
this one is too slow:
match (c1:Concept{name:"italy"})-->(ctx:Context)<--(c2:Concept{name:"pick"})-->(ctx:Context)<--(c3:Concept{name:"novice"}) return ctx;
Thanks!
You can match as many branches as you want in additional matches like this
match (c1:Concept{name:"italy"})-->(ctx:Context)<--(c2:Concept{name:"pick"})
match (c3:Concept{name:"france"})-->(ctx)
return ctx;
Although, I would recommend using params as they are more reusable. So assuming you have the param 'list' that contains ["italy", france", "pick"]
MATCH (c:Concept)
WHERE c.name in $list
WITH COLLECT(c) as concepts
MATCH (ctx:Context)
WHERE ALL(c in concepts WHERE (c)-->(ctx))
RETURN ctx

Neo4j return subgraph based on certain id

My database stores family relationships.
What I am trying to do is to return the whole family tree of a person with a certain ID.
I have tried the following query:
MATCH (p:Person {id:'1887'})-[r*1..3]-(k:Person)
RETURN distinct(p), r, k
but I didn't get the result that I wanted.
To make it more clear, I would like to get all the relationships that a person with specified ID has, along with the relationships of all the other nodes that he is connected to.
To explain further, here is an example:
Boris is a parent of Mike and Anna. Apart of seeing Boris' relationship to them, I also want to see Mike and Anna's further relationships with their subgraphs.
I believe you should try returning the complete path, like this:
MATCH path = (p:Person {id:'1887'})-[r*1..3]-(k:Person)
RETURN path
This query will store each the path between a person with id = 1887 and another person with depth 1 to 3 and return it. Or if you are interested only in the nodes you can extract it with the nodes() function:
MATCH path = (p:Person {id:'1887'})-[r*1..3]-(k:Person)
RETURN nodes(path)

Neo4J exclude nodes after set property

I have only just started with Neo4j so I suspect I am missing something very basic here. Given I have the following graph.
And starting on the highlighted node (ID 7937) I need to get all the connected nodes but nothing passed any of the "off" nodes.
Using this
match (n:TestNode)-[:LINK*]-(m)
where ID(n) = 7937
return *
Gives me everything of course which I would suspect due to no filter.
I need the end result to be:
This seems to give me the result I need. Is this the correct way or something better:
match p=n-[:LINK*..]-m
where ID(n) = 7937 and all(x in nodes(p) WHERE x.status = 'on')
return p;
Your query does not give you the results you said you wanted. That is, it does not include the nearest off nodes in the results.
Here is a query that does include the nearest off nodes. However, the results will contain partial paths as well as full paths; this is because your data has no consistent directionality to the LINK relationships, so it is hard to determine when we have reached the end of a path (it can probably be done, but it would make the query more complex).
MATCH p=n-[:LINK*..]-m
WHERE ID(n) = 7937
RETURN DISTINCT REDUCE(s =[n], x IN NODES(p)[1..] |
CASE (s[-1]).status
WHEN 'on' THEN s + x
ELSE s
END) AS res;
Here is a console that shows sample results.

Resources