schabluk
schabluk

Reputation: 708

Neo4j missing node from collect function

Please consider this example: there are three Groups and four Persons:

CREATE (group1:Group {
  name: 'Group 1'
})
CREATE (group2:Group {
  name: 'Group 2'
})
CREATE (group3:Group {
  name: 'Group 3'
})
CREATE (personA:Person {name: 'Anna'})
CREATE (personB:Person {name: 'Bob'})
CREATE (personC:Person {name: 'Carla'})
CREATE (personD:Person {name: 'Denis'})
CREATE
  (personA)-[:IS_PART_OF]->(group1),
  (personB)-[:IS_PART_OF]->(group1),
  (personB)-[:IS_PART_OF]->(group2),
  (personC)-[:IS_PART_OF]->(group2),
  (personC)-[:IS_PART_OF]->(group3),
  (personD)-[:IS_PART_OF]->(group3)

Anna and Bob belong to Group 1, Bob and Carla are members of Group 2, and Carla and Denis are in Group 3. A simple cypher query will show this relation:

MATCH (g:Group)<-[:IS_PART_OF]-(m:Person)
RETURN g, collect(DISTINCT m)

+-------------------------------------------------------------------------+
| g                       | collect(DISTINCT m)                           |
+-------------------------------------------------------------------------+
| Node[2]{name:"Group 3"} | [Node[6]{name:"Denis"},Node[5]{name:"Carla"}] |
| Node[1]{name:"Group 2"} | [Node[5]{name:"Carla"},Node[4]{name:"Bob"}]   |
| Node[0]{name:"Group 1"} | [Node[4]{name:"Bob"},Node[3]{name:"Anna"}]    |
+-------------------------------------------------------------------------+
3 rows

Now, I want to show all groups to which Anna and Bob belong, with all the members that are in those groups, including Anna and Bob.

My query is following:

MATCH (p:Person)-[:IS_PART_OF]->(g:Group)<-[:IS_PART_OF]-(m:Person)
WHERE p.name IN ['Anna', 'Bob']
RETURN g, collect(DISTINCT m)

+----------------------------------------------------------------------+
| g                       | collect(DISTINCT m)                        |
+----------------------------------------------------------------------+
| Node[1]{name:"Group 2"} | [Node[5]{name:"Carla"}]                    |
| Node[0]{name:"Group 1"} | [Node[4]{name:"Bob"},Node[3]{name:"Anna"}] |
+----------------------------------------------------------------------+
2 rows

The result is not what I expected to get.

Why Bob is not shown, as a member of Group 2?

Upvotes: 0

Views: 76

Answers (1)

stdob--
stdob--

Reputation: 29167

Node on the left side of the pattern will not be repeated on the right side if the relationship of the pattern matches the left and right sides.

Try this query:

// Find group
MATCH (p:Person)-[:IS_PART_OF]->(g:Group) WHERE p.name IN ['Anna', 'Bob']
// Get all person from group
WITH g 
  MATCH (g)<-[:IS_PART_OF]-(m:Person)
RETURN g, COLLECT(distinct m)

For a better understanding see the result of this query:

MATCH (p:Person)-[:IS_PART_OF]->(g:Group)<-[:IS_PART_OF]-(m:Person)
WHERE p.name IN ['Anna', 'Bob']
RETURN g, p, m

╒═══════════════╤════════════╤═════════════╕
│g              │p           │m            │
╞═══════════════╪════════════╪═════════════╡
│{name: Group 1}│{name: Anna}│{name: Bob}  │
├───────────────┼────────────┼─────────────┤
│{name: Group 2}│{name: Bob} │{name: Carla}│
├───────────────┼────────────┼─────────────┤
│{name: Group 1}│{name: Bob} │{name: Anna} │
└───────────────┴────────────┴─────────────┘

When you apply g, collect(distinct m) for group 1 you collect Bob and Anna and for group 2 you collect Carla.

Upvotes: 3

Related Questions