Alex Pomazan
Alex Pomazan

Reputation: 21

Does neo4j have possibility to LIMIT collected data?

I have 2 types of nodes in my neo4j db: Users and Posts. Users relate to Posts as -[:OWNER]-> My aim is to query users by ids with their posts and posts should be limited (for example LIMIT 10). Is it possible to limit them using the COLLECT method and order by some parameter?

MATCH (c:Challenge)<-[:OWNER]-(u:User) 
WHERE u.id IN ["c5db0d7b-55c2-4d6d-ade2-2265adee7327", "87e15e39-10c6-4c8d-934a-01bc4a1b0d06"] 
RETURN u, COLLECT(c) as challenges

Upvotes: 2

Views: 279

Answers (1)

InverseFalcon
InverseFalcon

Reputation: 30407

You can use slice notation to indicate you want to take only the first 10 elements of a collection:

MATCH (c:Challenge)<-[:OWNER]-(u:User) 
WHERE u.id IN ["c5db0d7b-55c2-4d6d-ade2-2265adee7327", "87e15e39-10c6-4c8d-934a-01bc4a1b0d06"] 
RETURN u, COLLECT(c)[..10] as challenges

Alternately you can use APOC's aggregation functions:

MATCH (c:Challenge)<-[:OWNER]-(u:User) 
WHERE u.id IN ["c5db0d7b-55c2-4d6d-ade2-2265adee7327", "87e15e39-10c6-4c8d-934a-01bc4a1b0d06"] 
RETURN u, apoc.agg.slice(c, 0, 10) as challenges

The APOC approach is supposed to be more efficient, but try out both first and see which works best for you.

EDIT

As far as sorting, that must happen prior to aggregation, so use a WITH on what you need, ORDER BY whatever, and then afterwards perform your aggregation.

If you don't see good results, we may need to make use of LIMIT, but since we want that per u instead of across all rows, you'd need to use that within an apoc.cypher.run() subquery (this would be an independent query executed per u, so we would be allowed to use LIMIT that way):

MATCH (u:User) 
WHERE u.id IN ["c5db0d7b-55c2-4d6d-ade2-2265adee7327", "87e15e39-10c6-4c8d-934a-01bc4a1b0d06"] 
CALL apoc.cypher.run("MATCH (c:Challenge)<-[:OWNER]-(u) WITH c ORDER BY c.name ASC LIMIT 10 RETURN collect(c) as challenges", {u:u}) YIELD value
RETURN u, value.challenges as challenges

Upvotes: 2

Related Questions