4

I need count of all child nodes until first condition meet.

e.g. I have data like

-MainParent
   -ParentChild 1
       -Child 1
       -Child 2   
   -ParentChild 2
       -Child 1
       -Child 2
       -Child 3
          -grand child 1
          -grand child 2

It will give me total count of nodes = 10. But suppose I blocked Child 3, then all child from Child 3 should not be count.

This is my query-

MATCH (m:MainParent)-[c:HAS_COMMENT*]-(child)
WHERE child.blocked <> 1
return count(child) as child_count

Now it will give me child_count = 9. But I need it to 7, after matching first condition that is child.blocked <> 1 further count should be ignored.

Thanks. Please tell me if i need to elaborate more.

Satish Shinde
  • 2,878
  • 1
  • 24
  • 41

3 Answers3

3

If there is only a single path to each comment then you could use something like this:

MATCH path =(m:MainParent)-[c:HAS_COMMENT*0..]-(child)
WITH path
WHERE ALL (node IN TAIL(NODES(path)) 
       WHERE node.blocked = FALSE )
RETURN COUNT(path)

The [c:HAS_COMMENT*0..] matching zero length paths is because I think that you want to count the MainParent node too.

WHERE ALL mandates that the nested query be true for all elements in the collection which means that if a single Node in the path is marked as blocked then that path will not match.

TAIL(NODES(path)) is used because the head node is always going to be the MainParent node, which will never match the node.blocked contraint.

If you need the nodes (this is untested, but something along these lines):

MATCH path =(m:MainParent)-[c:HAS_COMMENT*0..]-(child)
WITH path
WHERE ALL (node IN TAIL(NODES(path)) 
       WHERE node.blocked = FALSE )
WITH NODES(path) AS nodes
UNWIND nodes as node
RETURN DISTINCT node

An alternative
If this isn't working for you, or is a bit too complex I wonder if you have considered allowing the model to do the work for you

One of two options would work, if instead of marking a comment as blocked you marked the relationship between two nodes as blocked.

You could either achieve this by moving the blocked property to the relationship:

(c:Comment)-[:HAS_COMMENT{blocked:true}]-(cc:Comment)

Enabling:

MATCH (m:MainParent)-[c:HAS_COMMENT*]-(child)
WHERE c.blocked <> 1
RETURN count(child) as child_count

or by changing the relationship type to BLOCKED_COMMENT:

(c:Comment)-[:HAS_BLOCKED_COMMENT]-(cc:Comment)    

Enabling:

MATCH (m:MainParent)-[c:HAS_COMMENT*]-(child)
RETURN count(child) as child_count
JohnMark13
  • 3,709
  • 1
  • 15
  • 26
0

Try this

MATCH path = (m:MainParent)-[c:HAS_COMMENT*]-(child)
WHERE child.blocked <> 1 and all(n in nodes(path) where child.blocked <> 1)
return count(distinct child) as child_count
Michael Hunger
  • 41,339
  • 3
  • 57
  • 80
  • Thanks for your response, I have checked it doesn't work for me. My requirement is if the condition meets then it should stop counting. In my example it meets condition for Child 3 then further nodes should not be counted. – Satish Shinde Oct 14 '14 at 10:21
  • @Michael Your answer is working partially. OP/I require to stop traversing if condition is satisfying. And not to include further children. Please please help. – Somnath Muluk Oct 21 '14 at 11:57
0

Sounds like the traversal api might help in your case. http://docs.neo4j.org/chunked/stable/tutorial-traversal-concepts.html

It allows you to decide how to traverse a graph and when to stop traversing.

Ryan Walls
  • 6,962
  • 1
  • 39
  • 42