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