Masonoise
Masonoise

Reputation: 1573

Neo4j aggregate/count of connected nodes

I'm trying to do a count of nodes connected to node A, where node A is part of a Cypher query starting from node B, and I'm getting unexpected results. Here's an example setup. Pretend we're looking at books and owners, and books cite other books while owners of course own books:

Book B1
Book B2 CITES B1
Book B3 CITES B1
Book B4
Owner O1 OWNS B1
Owner O2 OWNS B2
Owner O3 OWNS B3 and B4

So let's say I'm looking at Book B1, and I want to find each book that cites it, then count the books owned by each person who owns the citing book. So if I start with B1, I should find owners O2 and O3, since each owns a book that cites B1. If I count the books they own, I should get 1 for O2, and 2 for O3.

So first, a query to just list the owners works fine:

start a=node(1) MATCH a<-[:CITES]-b<-[:OWNS]-c return c.name

That returns the names as expected. But then this query:

start a=node(1) MATCH a<-[:CITES]-b<-[:OWNS]-c-[:OWNS]->d return c.name, count(d)

It seems as though it should get to c, which is the list of owners, then go through the OWNS relationship to the owned books as d, and count them. But instead I get:

+--------------------+
| c.name  | count(d) |
+--------------------+
| "O3"    | 1        |
+--------------------+

It feels like it's leaving out the books/nodes that have already been found through the other OWNS link -- the ones represented by b. Is there any way to do this in a single query, or is it best to gather up the owners as c, then query again for each of them? It feels like this should be possible, but I haven't figured it out yet. Any ideas would be great -- thanks in advance.

Upvotes: 1

Views: 2994

Answers (1)

Eve Freeman
Eve Freeman

Reputation: 33175

You're right, once a node gets found, you can't find it again in the same match under a different named variable. You can break this up using a WITH, and then use d in the same way, and it will match all of them.

START a=node(14) 
MATCH a<-[:CITES]-b<-[:OWNS]-c 
WITH c MATCH c-[:OWNS]->d 
RETURN c.name, count(d);

http://console.neo4j.org/?id=x1jst9

Upvotes: 0

Related Questions