Search code examples
neo4jcypherneo4j-apocneodash

Concise way to Add virtual property with neighbour count to each result node in Cypher


I'm using NeoDash, and I want to generate a graph report where each node size is weighted by the number of neighbors.

So this count must become a property of the node to be analyzed by NeoDash properly.

Now, after 4 hours, I finally succeeded with the following query, but I'm pretty sure there should be a more elegant and concise way to do the same, right?

  MATCH path=(n)-[r]->(c) //n is already from a subset, and here we exclude _events
    WHERE NOT c:_event

WITH collect(distinct n) as listN, collect(distinct c) as listC
  UNWIND listN as n
    MATCH (n)-[r]->(c) WHERE c in listC

WITH listN, listC, n, count(c) as countC
  SET n.counter=countC

WITH collect(n) as listN, listC
  UNWIND listC as c
    MATCH (n)-[r]->(c) WHERE n in listN

WITH c, count(n) as countN, listN
  SET c.counter=countN

WITH collect(c) as listC, listN
  MATCH (n)-[r]->(c)
    WHERE n in listN 
      and c in listC

RETURN n,r,c

or is there an apoc shortcut for that?


Solution

  • The query below only needs one MATCH, and does not need APOC. The CALL subqueries do not return anything, and therefore leave the single outer row as-is.

    .
    .
    .
    MATCH (n)-[rel]->(:!_event) //n was defined earlier, and here we exclude _events
    WITH COLLECT(rel) as rels
    CALL {
      WITH rels
      UNWIND rels AS r
      WITH STARTNODE(r) AS n, COUNT(*) AS countC
      SET n.counter = countC
    }
    CALL {
      WITH rels
      UNWIND rels AS r
      WITH ENDNODE(r) AS c, COUNT(*) AS countN
      SET c.counter = countN
    }
    UNWIND rels AS r
    RETURN STARTNODE(r) AS n, r, ENDNODE(r) AS c