cypher query to match on multiple relationships

2,345 views
Skip to first unread message

Greg Jordan

unread,
Mar 27, 2012, 11:11:49 AM3/27/12
to ne...@googlegroups.com
Just getting started with cypher queries, so bear with me...

I've created a query that finds a user's followers and returns the followers' posts in a List, like so:

@Query("START profile=node:Profile(username={0}) MATCH (post)-[:POSTSOUTPROFILE]->(following)<-[:FOLLOWING]-(profile) RETURN post")

I'd like to include the user's posts as well, but I got empty results on the following

@Query("START profile=node:Profile(username={0}) MATCH (post)-[:POSTSOUTPROFILE]->(following)<-[:FOLLOWING]-(profile)<-[:POSTSOUTPROFILE]-(post) RETURN post")

Do I need to do multiple matches or I missing something fundamental about expressing multiple rels?


Andres Taylor

unread,
Mar 27, 2012, 11:19:04 AM3/27/12
to ne...@googlegroups.com
On Tue, Mar 27, 2012 at 5:11 PM, Greg Jordan <gregory...@gmail.com> wrote:
Just getting started with cypher queries, so bear with me...

I've created a query that finds a user's followers and returns the followers' posts in a List, like so:

@Query("START profile=node:Profile(username={0}) MATCH (post)-[:POSTSOUTPROFILE]->(following)<-[:FOLLOWING]-(profile) RETURN post")

I'd like to include the user's posts as well, but I got empty results on the following

@Query("START profile=node:Profile(username={0}) MATCH (post)-[:POSTSOUTPROFILE]->(following)<-[:FOLLOWING]-(profile)<-[:POSTSOUTPROFILE]-(post) RETURN post")

In this query you are describing a circular pattern. Without the rel-types, it is:

post-->following<--profile<--post

The start node and the end node must be the same in this pattern. Is that what you intended?

Andrés

Greg Jordan

unread,
Mar 27, 2012, 11:47:55 AM3/27/12
to ne...@googlegroups.com
not sure exactly (pardon my newbieness).

are suggesting something like this:

@Query("START post=node:Post(0) MATCH (post)-[:POSTSOUTPROFILE]->(following)<-[:FOLLOWING]-(profile)<-[:POSTSOUTPROFILE]-(post) WHERE post.profile.username={0} RETURN post")


On Tuesday, March 27, 2012 10:19:04 AM UTC-5, Andres Taylor wrote:

Peter Neubauer

unread,
Mar 29, 2012, 1:39:38 PM3/29/12
to ne...@googlegroups.com
Not sure if this is still open Greg?

Cheers,

/peter neubauer

G:  neubauer.peter
S:  peter.neubauer
P:  +46 704 106975
L:   http://www.linkedin.com/in/neubauer
T:   @peterneubauer

Neo4j                                - Graphs rule.
Program or be programmed - Computer Literacy for kids.
http://foocafe.org/#CoderDojo

Greg Jordan

unread,
Mar 29, 2012, 2:29:53 PM3/29/12
to ne...@googlegroups.com
Thanks, Peter.

I tried the following as - I believe - Andres suggested, but it returned zero results

@Query("START profile=node:Profile(username={0}) MATCH (post)-[:POSTSOUTPROFILE]->(following)<-[:FOLLOWING]-(profile)<-[:POSTSOUTPROFILE]-(post)  RETURN post")


this however, returns all the posts of username={0}'s followers


@Query("START profile=node:Profile(username={0}) MATCH (post)-[:POSTSOUTPROFILE]->(following)<-[:FOLLOWING]-(profile)  RETURN post")

I've moved to 1.7MO2 and tried something like:

@Query("START post=node(*) MATCH (profile)<-[:POSTSOUTPROFILE]-(post) RETURN post WHERE profile.username IN ['name','another'] ")


which IIRC worked, but somewhat seems defeat the point of the relationships to other profiles in this instance.



On Thursday, March 29, 2012 12:39:38 PM UTC-5, Peter Neubauer wrote:
Not sure if this is still open Greg?

Cheers,

/peter neubauer

G:  neubauer.peter
S:  peter.neubauer
P:  +46 704 106975
L:   http://www.linkedin.com/in/neubauer
T:   @peterneubauer

Neo4j                                - Graphs rule.
Program or be programmed - Computer Literacy for kids.
http://foocafe.org/#CoderDojo

Peter Neubauer

unread,
Mar 29, 2012, 4:36:36 PM3/29/12
to ne...@googlegroups.com
Greg,
remember that when you bind a variable it means that it refers to the
SAME node in the pattern.

@Query("START profile=node:Profile(username={0}) MATCH
(post)-[:POSTSOUTPROFILE]->(following)<-[:FOLLOWING]-(profile)<-[:POSTSOUTPROFILE]-(post)
RETURN post")

means that the first and the last (post) ARE THE SAME post. I believe
that what you want is something like

@Query("START profile=node:Profile(username={0}) MATCH

(following_post)-[:POSTSOUTPROFILE]->(following)<-[:FOLLOWING]-(profile)<-[:POSTSOUTPROFILE]-(profile_pos)
RETURN following_post, profile_post")

in order to return the correct data, possibly chunking it a bit with
Count(*) or group ...

Cheers,

/peter neubauer

G:  neubauer.peter
S:  peter.neubauer
P:  +46 704 106975
L:   http://www.linkedin.com/in/neubauer
T:   @peterneubauer

Neo4j                                - Graphs rule.
Program or be programmed - Computer Literacy for kids.
http://foocafe.org/#CoderDojo

Greg Jordan

unread,
Apr 4, 2012, 7:52:14 PM4/4/12
to ne...@googlegroups.com
So I was able to get results as you suggested by doing this:

@Query("START profile=node(1) MATCH (profile)<-[:POSTSOUTPROFILE]-(post)-[:POSTSOUTCHANNEL]->(channel)<-[:POSTSOUTCHANNEL]-(following_post)-[:POSTSOUTPROFILE]->(following) WHERE  channel.channelName='Links' AND (following<-[:FOLLOWING]-profile AND following_post.hasPrivacy=false) RETURN  post,following_post, Count(*) as postCount ORDER BY post.modified")

which then returned as using @MapResult.  

However, I am getting duplicates in the results and have searched and tried various hacks for a few days on returning unique results,e.g. RETURN DISTINCT post.

Could you provide a litte more guidance on using count(*) or group as you suggsted?  


On Thursday, March 29, 2012 3:36:36 PM UTC-5, Peter Neubauer wrote:
Greg,
remember that when you bind a variable it means that it refers to the
SAME node in the pattern.

@Query("START profile=node:Profile(username={0}) MATCH
(post)-[:POSTSOUTPROFILE]->(following)<-[:FOLLOWING]-(profile)<-[:POSTSOUTPROFILE]-(post)
 RETURN post")

means that the first and the last (post) ARE THE SAME post. I believe
that what you want is something like

@Query("START profile=node:Profile(username={0}) MATCH
(following_post)-[:POSTSOUTPROFILE]->(following)<-[:FOLLOWING]-(profile)<-[:POSTSOUTPROFILE]-(profile_pos)
 RETURN following_post, profile_post")

in order to return the correct data, possibly chunking it a bit with
Count(*) or group ...

Cheers,

/peter neubauer

G:  neubauer.peter
S:  peter.neubauer
P:  +46 704 106975
L:   http://www.linkedin.com/in/neubauer
T:   @peterneubauer

Neo4j                                - Graphs rule.
Program or be programmed - Computer Literacy for kids.
http://foocafe.org/#CoderDojo

Andres Taylor

unread,
Apr 11, 2012, 10:33:09 AM4/11/12
to ne...@googlegroups.com
On Thu, Apr 5, 2012 at 1:52 AM, Greg Jordan <gregory...@gmail.com> wrote:
So I was able to get results as you suggested by doing this:

@Query("START profile=node(1) MATCH (profile)<-[:POSTSOUTPROFILE]-(post)-[:POSTSOUTCHANNEL]->(channel)<-[:POSTSOUTCHANNEL]-(following_post)-[:POSTSOUTPROFILE]->(following) WHERE  channel.channelName='Links' AND (following<-[:FOLLOWING]-profile AND following_post.hasPrivacy=false) RETURN  post,following_post, Count(*) as postCount ORDER BY post.modified")

which then returned as using @MapResult.  

However, I am getting duplicates in the results and have searched and tried various hacks for a few days on returning unique results,e.g. RETURN DISTINCT post.

Could you provide a litte more guidance on using count(*) or group as you suggsted?  

What do you mean duplicates? The result rows should be unique if you look at both post and following_post.

Andrés
 

Greg Jordan

unread,
Apr 11, 2012, 10:48:29 AM4/11/12
to ne...@googlegroups.com

Here's what I mean (see attached).  the result rows may be unique, but the sets of nodes aren't. 




On Wednesday, April 11, 2012 9:33:09 AM UTC-5, Andres Taylor wrote:

Andres Taylor

unread,
Apr 11, 2012, 3:28:36 PM4/11/12
to ne...@googlegroups.com
I'm sorry, but I don't understand what it is you are trying to achieve. 

Your are not asking for sets of nodes, you are asking for an aggregation where the key is two columns - post and following_post. The result is unique, if you look at both these columns. If you only want a single column to be key, exclude the other one from your return clause, and you're set. Or am I still missing something?

Andrés

Michael Hunger

unread,
Apr 11, 2012, 5:40:06 PM4/11/12
to ne...@googlegroups.com
Otherwise you could also do:

return collect(distinct post) ,collect(distinct following_post), count(*)

so it returns one line with just the distinct values if that is what you need?

Michael

Greg Jordan

unread,
Apr 11, 2012, 5:54:33 PM4/11/12
to ne...@googlegroups.com
Thanks, Andres and Michael. Correct, the result row is unique, but I am after what Michael suggested - collections of distinct nodes.  

I'll add that collect( distinct nodes) and share the results. 
Reply all
Reply to author
Forward
0 new messages