0

I thought this would be very easy, because i have a typical graph use case: Expand a node.

This is easy if there are no additional requirements:

MATCH (s:Entity)-[]-(dest) WHERE s._id = 'xxx'
RETURN dest

Problem Nr.1: sometimes there are many children so i want to limit the return count!

MATCH (s:Entity)-[]-(dest) WHERE s._id = 'xxx'
RETURN dest
LIMIT 100

Additional requirement: Return all children ids of the children childrens!

MATCH (s:Entity)-[]-(dest) WHERE s._id = 'xxx'
WITH collect(dest) as childrenSource
LIMIT 100
MATCH (childrenSource)-[]-(childDestination)
RETURN childrenSource as expandNode, collect(childDestination) as childrenIds
LIMIT 100

Problem 2: The limits are in the wrong place, because collect already did the collection before the limit.

Possible solution:

MATCH (s:Entity)-[]-(dest) WHERE s._id = 'xxx'
WITH collect(dest)[..100] as childrenSource
LIMIT 100
MATCH (childrenSource)-[]-(childDestination)
RETURN childrenSource as expandNode, collect(childDestination)[..100] as childrenIds

But i dont thinks this is a performant solution. Because it takes quite a lot of time

Exact Problem description: If i have 1 node with 1000 children and each child has another 1000 children i want to execute a query which returns 100 children with 100 child ids

-------------------------------------------------
| node 1   | child id 1_1,....   child id 1_100 |
| node 2   | child id 2_1,....   child id 2_100 |
| ...      | ...                                |
| node 100 | child id 100_1,.. child id 100_100 |
-------------------------------------------------

Other solution: i do a simple expand for the node. and than i call an expand on each child node. But doing 101 queries instead of 1 query sounds not too performant either.

mabr
  • 370
  • 4
  • 17

2 Answers2

1

EDIT

As usual, APOC Procedures to the rescue. Using apoc.cypher.run(), you can use LIMIT within a subquery, which lazy-load the expansion up to your limit.

MATCH (s:Entity)-[]-(dest) WHERE s._id = 'xxx'
WITH dest
LIMIT 100
CALL apoc.cypher.run('
 MATCH (dest)-[]-(childDestination)
 RETURN childDestination LIMIT 100
 ', {dest:dest}) YIELD value
RETURN dest as expandNode, COLLECT(value.childDestination) as childrenIds
InverseFalcon
  • 29,576
  • 4
  • 38
  • 51
  • this would be a good possibility. but i think the lib is not compatible with the latest neo4j version? I am using Neo4j 3.1.1 CE i tried: - apoc 3.0.8.4: Server didnt start anymore - apoc 3.1.0.3 & 3.1.0.2: this adds only a single new function: apoc.schema.assert – mabr Feb 27 '17 at 07:44
  • Others have mentioned something's going on here. Are you on Windows? – InverseFalcon Feb 27 '17 at 09:31
  • yes i am using neo4j on windows (the community edition) – mabr Feb 27 '17 at 15:21
  • In a different question, another Windows user had problems getting APOC to work. They mentioned after following [these instructions](https://indexoutofrange.com/Neo4jStoredProceduresWindows/) they were able to get it working. – InverseFalcon Feb 28 '17 at 11:32
  • i use the solution with the APOC library. Thanks a lot – mabr Feb 28 '17 at 15:57
  • for the installation, see also: http://stackoverflow.com/questions/42286508/apoc-is-only-partially-installing-its-extension-in-neo4j-one-procedure – mabr Feb 28 '17 at 16:18
-2

Using cypher would help you

MATCH (entity1)-[rel]-(entity2) WHERE entity1.title = "something"
WITH entity2
LIMIT 100
CALL apoc.cypher.run('
 MATCH (entity2)-[]-(childDestination)
 RETURN childDestination 
 LIMIT 100
 ', {entity2:entity2}) YIELD value
RETURN entity2 as expandNode, COLLECT(value.childDestination) as childrenId
Nikolai Shevchenko
  • 7,083
  • 8
  • 33
  • 42
s1lcon
  • 1
  • 1