WJA
WJA

Reputation: 7004

Formatting RETURN in neo4j: grouping by an item

I use the following cypher to get all the entities of the label User:

MATCH (u:User)
OPTIONAL MATCH (u)-[r:RATED]->(m:Movie) 
WITH u,r,m
RETURN u.id as uid, m.id as mid, r.rating as rating

This returns me an array of objects formatted as:

[
    {
      "uid": "user1",
      "mid": "bettercallsaul",
      "rating": 9
    },
    {
      "uid": "user1",
      "mid": "breakingbad",
      "rating": 10
    }
    // ... etc
]

I would like however to group it by the u.id (or uid) such that it returns something like (or similar):

[
   {"user1": 
       {"mid": "bettercallsaul", "rating": 9},
       {"mid": "breakingbad", "rating": 10},
       // ... etc
   },
   {"user2":
       {"mid": "breakingbad", "rating": 7},
       {"mid": "bettercallsaul", "rating": 8},
       // ... etc
   }
   // ... etc
]

Upvotes: 0

Views: 286

Answers (2)

Mark Boessenkool
Mark Boessenkool

Reputation: 101

I do not know if it is completely possible to do what you want. However I think you will get close with the collect function of Neo.

MATCH (u:User)
OPTIONAL MATCH (u)-[r:RATED]->(m:Movie) 
WITH u.id as uid, m.id as mid, r.rating as rating
RETURN uid, collect([mid, rating])

Upvotes: 1

InverseFalcon
InverseFalcon

Reputation: 30407

I think you're looking for for the COLLECT() function.

Maybe try this query:

MATCH (u:User)
OPTIONAL MATCH (u)-[r:RATED]->(m:Movie) 
RETURN u.id,COLLECT({mid:m.id, rating:r.rating}) as movieRatings

If you're using Neo4j 3.1.x or higher, you can use pattern comprehension and map projection to make this easier:

MATCH (u:User)
RETURN u.id as user, 
  [(u)-[r:RATED]->(m:Movie) | m {.id, rating:r.rating}] as movieRatings

And if you want the list of movieRatings to be a part of each user's properties map, you can use map projection to do this too:

MATCH (u:User)
RETURN u {.id, .name, movieRatings:
  [(u)-[r:RATED]->(m:Movie) | m {.id, rating:r.rating}] } as user

Upvotes: 1

Related Questions