I am new to cypher. I am using the movie database of neo4j CE 3.1.2.
I want to get output of my query
match (a:Person)-[r]-(b:Movie) return a, r, b
in the form source, edge, destination, for example
Tom Hanks, ACTED_IN, That Thing You Do
Tom Hanks, DIRECTED, That Thing You Do
Gary Sinise, ACTED_IN, The Green Mile
Basically I want a row for every source_node, destination_node connection.
Please help.
EDIT 1
If my graph is like A->B->C->D and if I want all down tree nodes of A, then my output should be like
A,connected,B
B,connected,C
C,connected,D
You're looking at the graphical view of the results. If you look to the left of the graph, you'll see the ability to change to Row and Text views of the results, which should give you what you want...almost.
Output for relationships currently shows only properties on the relationships, not the type, so you may need to adjust your query slightly.
match (a:Person)-[r]-(b:Movie)
return a, type(r) as type, b
If you want ONLY the person's name, the type of the relationship, and the movie title, then you'll need to return the properties from the nodes, not just the nodes themselves:
match (a:Person)-[r]-(b:Movie)
return a.name as name, type(r) as type, b.title as title
Related
I want to display all Person who act as well as direct a movie. It does not matter if the person direct a movie but does not act in the movie. As long as there are edges ACTED_IN and DIRECTED exist on a node, the query will display the result.
I have tried several Cypher queries. This one I believe show the nearest result I intend to:
MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WHERE exists( (p)-[:DIRECTED]->() )
RETURN distinct *
Now, the issue is, one of the result shows "James Marshall" ACTED_IN "A Few Good Men" but he also DIRECTED two different movies which are "Ninja Assasin" and "V for Vendetta".
My current outcome only display "James Marshall" ACTED_IN "A Few Good Men" and does not show the other two movies he DIRECTED. So, how can I improve my Cypher?
You can first match on persons that have the relationships you need (this will be a degree check), then MATCH on the pattern using both relationships at once (which would be an OR match for the relationships in question otherwise):
MATCH (p:Person)
WHERE (p)-[:ACTED_IN]->() AND (p)-[:DIRECTED->()
MATCH path = (p)-[:ACTED_IN | DIRECTED]->(m:Movie)
RETURN path
You can use the solution in this post
The key point is to add another relationships in the other way around (right to the left to the movie), and then add in the WHERE clause the condition.
MATCH (a1:Person)-[:ACTED_IN]->(m:Movie)<-[:ACTED_IN]-(a2:Person)
WHERE exists( (a2)-[:DIRECTED]->(m) ) RETURN a2, m
I have currently visualised a graph between myself and a number of other people.
My Current query is:
MATCH (p)-[:emailed]->(m)
WITH p,count(m) as rels, collect(m) as Contact
WHERE rels > 2
RETURN p,Contact, rels
It creates a pretty complex graph as per image below:
Messy Graph
You can manually remove them by directly clicking on them as per below:
Manually hide node from visualisation
Which then results in a very different looking graph.
Q. How do I change my query to automatically show the graph visualisation without showing the nodes that I wish to remove? (i.e by editing the query, so I dont have to manually remove each one)
By doing either
A) Adding a list of the specific Node ID's in the query to ignore, OR
B) (Ideally) Exclude all nodes that meet a criteria against the node Property
In this case: Ignore [Slug: "myname" ] where includes 'myname'
MATCH (p)-[:emailed]->(m)
WITH p,count(m) as rels, collect(m) as Contact
WHERE rels > 2 AND NOT WHERE p.slug Contains 'Mahdi'
RETURN p,Contact, rels
Thanks for any help!
I would change it slightly. If you collect the actual :emailed relationships rather than just counting the node they are connect to you can use them in your result set. Then if you turn off autocomplete as JeromeB suggests above then you will actually see some relationship. If you turn off autocomplete in your current query there will only be nodes and no relationships which I don't think you are after (unless of course you are).
You could also check to make sure that the p.slug attribute exists when testing for CONTAINS otherwise if the attribute does not exist you will not generate any results for that row.
MATCH (p:User)-[r:emailed]->(m:User)
WITH p, COLLECT(r) as rels, COLLECT(m) as contact
WHERE (NOT p.slug CONTAINS 'Mahdi' OR NOT EXISTS(p.slug))
AND size(rels) > 2
RETURN p, contact, rels
I would also add a label to the nodes in the match and an index on the slug property.
The autocomplete is 'Connect result nodes' in the Gear tab.
I have a graph but need to be sure that all nodes are in the path (but more than those nodes can exist in the path).
Here is an example (sorry, had to black some stuff out):
I want to find end2 and not end1 when I have the values of the same property in all three intermediary nodes in the list I pass in. But I can't get a query that will return end2 without end1. There can be more nodes out there that have the same routes but I will only every pass in distinct values that are not duplicated across the middle nodes. Anyone know of a query that will give me only the end node that has all the values from the intermediary nodes? There are also nodes that hang off of those end nodes and some of them interlink between end1 and end2. Some others do not and those are the nodes I do not want but because there is a path between the yellow and blue to that end1 I can't use ANY but because there other paths to those same nodes (not pictured) I can't use ALL either.
Thanks in advance for help.
[Update]
Here is the current query I use but it only allows for one "end" node per a start node and I want multiple. I needed that id(eg)={eg_id} passed in but that limits it to one. I would much rather use the fact that every a in the path below needs to match up to the list of name properties in the middle node must be there to get to which end node. So if yellow and blue are htere then end1 and end2 would come back but if yellow, blue and purple are there then only end2 would come back.
start td = node({td_id})
match (td:Start)-[:Rel1]->(a)<-[:Rel2]-(eg:End)-[es:Rel3]->(n:WhatsPastEnd)
with collect(a.name) as pnl, n, td, eg, es
where id(eg) = {eg_id}
and all(param_needs in {param_name_list} where param_needs in pnl)
return n
order by es.order
[SOLVED]
Thank you very much InverseFalcon, got what I need from the solution below!
Okay, let's modify your query, and drop the matching of the endnode id.
start td = node({td_id})
// unwind your list of names so every row has a name
with td, {param_name_list} as param_names
unwind param_names as param_name
match (td:Start)-[:Rel1]->(a)
where a.name = param_name
// now a has all nodes with the required names
// collect then unwind so we have the full collection for each a
with collect(a) as requiredNodes
unwind requiredNodes as a
match (a)<-[:Rel2]-(eg:End)
where all(node in requiredNodes where (node)<-[:Rel2]-(eg))
with eg
match (eg)-[es:Rel3]->(n:WhatsPastEnd)
return n
order by es.order
I'm trying to find a query that will show me any length relationship that exists between two nodes that share the same index. Basically, if there is any overlap between for a specific label. My graph is Pretty simple and not particularly large:
(m:`Campaign`), (n:`Politician`), (o:`Assistant`), (p:`Staff`), (q:`Aid`), (s:`Contributor`)
(m)<-[:Campaigns_for]-(n)
(o)<-[:works_for]-(m)
(p)<-[:works_for]-(o)
(q)<-[:volunteers_for]-(p)
(m)<-[:contributes_to]-(s)
I want to find all the shared nodes and their relationships between Campaigns.
so far i have:
MATCH (n:`Campaign`)-[r*]-(m:`Campaign`)
RETURN n,count(r) as R,m
ORDER BY R DESC
but it's not returning everyhing I want, I want in addition to the counts, the labels of each relationship and the names of the nodes in between.
Assuming that "names of the nodes" means "return the name property of the node" (you could always substitute in "labels(n)" if you're after labels), then something like this might work, but you have some aggregation going on here so you may need to parse a bit:
MATCH p =(a:Campaign)-[r*]-(b:Campaign)
RETURN a, length(relationships(p)) AS count, b, extract(x IN relationships(p)| type(x)), extract(x IN nodes(p)| x.name)
ORDER BY count DESC
I'm also assuming that when you say "not returning everything you want", you mean that in addition to what's currently returned in your result set, you want just those other items you listed.
Keep in mind it might also be possible to have a cycle in your graph (not knowing too much about your particular graph), so, you may want to check your beginning and ending nodes.
for example:
a-[r]->b, there are multi r between the two nodes, each r.userId is unique.
(eg: a-[r:R {userId:"user1"}]->b, (a-[r:R{userId:"user2"}]->b,
and the same for a-[r]->c
And the situation is a-[r]->b has a relationship: r.userId = amdin, but a-[r]->c doesn't have this relationship.
how can i only return c.
i try to create cypher:
"MATCH (a:SomeLabel)-[r:SomeR]->(any:SomeLabel) "
"WHERE id(a)=0 AND r.userId <> \"admin\" "
"RETURN any";
but this will also return b ,because a->b has other relationship: r.userId=xxxx
how can i write the cypher to return nodes not inculde user.Id="admin"......
If you not clearly understand what i say,please let me know....i need your help for this case..thanks
I draw a picture below, multi relationship named sr but with different properties (userId is unique),
and i want to find all nodes that related to node A, but not contains sr {userId:admin}, i add a red underline there. So as in the picture, node B has the relationship sr {userId:admin}, so i only want to return node C, no node B
For showing simple representations of graph problems, graphgists are really helpful as people can explore the data.
I've created one based on your description: http://gist.neo4j.org/?94ef056e41153b116e4f
To your problem, you can collect all usernames involved in the relationships per pair of nodes and filter based on those:
MATCH (a { name:'A' })-[r:sr]->b
WITH a,b, collect(r.name) AS usernames
WHERE NOT 'admin' IN usernames
RETURN a, b
Your question is pretty unclear. My interpretation is that you want to find nodes c that are not connected to a node a with a relationship of type R.
You basically want to do a negative match aka search for a pattern that does not exist. Negative patterns can be retrieved using a where not:
MATCH (a:SomeLabel), (c:SomeLabel)
WHERE ID(a)=0 AND NOT (a)-[:R]->(c)
RETURN c
This returns a list of all SomeLabel nodes not being connected to a.
See http://docs.neo4j.org/chunked/stable/query-where.html#query-where-patterns in the reference manual.