I don't know why my "subquery" is not working properly

Hi all,

I just tried plenty of queries and it either doesn't show me results I want or it throws timeout, I think it is set to 1 hour.
I'm trying to answer the following question: which are the 20 nodes with highest degree and the 200 nodes with highest degree connected to them?
The details are that they have User label and the relationship direction has to be ("200 nodes":User)-[:wrote]->("20 nodes":User)
The network has more than 400k nodes (users is 200k) and more than 3M relationships (2M rel. authorship)

Neo4j version: 4.1.3 community

What I tried:

  • Timeout after 1 hour
MATCH (n:User)
WHERE SIZE((n)-[:AUTHORSHIP]-()) > 10
CALL {
MATCH(p:User)
RETURN p ORDER BY SIZE((p)<-[:AUTHORSHIP]-()) DESC LIMIT 20
UNION
MATCH(p:User)
RETURN p ORDER BY SIZE((p)-[:AUTHORSHIP]->()) DESC LIMIT 200
}
RETURN p
  • Wrong output
MATCH (n:User)<-[:AUTHORSHIP]-()
WITH n ORDER BY SIZE((n)<-[:AUTHORSHIP]-()) DESC LIMIT 20
CALL {
WITH n
MATCH (m)-[r:WROTE]->(n)
RETURN m ORDER BY SIZE((m)-[:AUTHORSHIP]->()) DESC LIMIT 200
}
RETURN n,m


Relationship sample

MATCH (n:User)-[r:WROTE]->(m:User)
RETURN n.name, m.name, RAND() as r ORDER BY r LIMIT 1000

sample.txt (27.6 KB)

Hello @j_crz and welcome to the Neo4j community :slight_smile:

  1. Did you use UNIQUE CONSTRAINTS?
  2. You should test your query by only selecting one User just to check if the query is working.
  3. You should modify a bit your first query because you are not using n.
MATCH (n:User)
WHERE SIZE((n)-[:AUTHORSHIP]-()) > 10
CALL {
    WITH n
    MATCH (n)
    RETURN n, SIZE((n)<-[:AUTHORSHIP]-()) AS degreeIn
    ORDER BY degreeIn DESC LIMIT 20
    UNION
    WITH n
    MATCH (n)
    RETURN n, SIZE((n)<-[:AUTHORSHIP]-()) AS degreeIn
    ORDER BY degreeIn DESC LIMIT 200
}
RETURN n, degreeIn

Regards,
Cobra

Thank you @cobra for your answer.

I actually got what I needed by using the following query:

MATCH (p:User)
WITH p, SIZE((p)<-[:AUTHORSHIP]-()) AS degreeIn
ORDER BY degreeIn DESC LIMIT 20
UNWIND p as hub
MATCH (hub)<-[:AUTHORSHIP]-(m:User)
RETURN m, SIZE((m)-[:AUTHORSHIP]->(:User)) AS degree
ORDER BY degree DESC LIMIT 900
UNION
MATCH (m:User)
RETURN m, SIZE((m)<-[:AUTHORSHIP]-()) AS degree
ORDER BY degree DESC LIMIT 20