Neo4j GDS Certification study materials
Neo4j GDS Certification study resources

Citation Influence Ranking on a Directed Citation Graph

Neo4j GDS Certification · Put your knowledge to work in context.

All case studies

Citation Influence Ranking on a Directed Citation Graph

A research analytics team runs Neo4j 5 with GDS 2.6 on a 16 GB heap and 4 CPUs. Their graph has 8.4 million :Article nodes and 31 million directed :CITES relationships; 2.1 million articles have no outgoing citations. They project every Article and CITES relationship with orientation NATURAL, no relationship weight, then call gds.pageRank.stream with defaults (dampingFactor 0.85, maxIterations 20, tolerance 1e-7). The run takes 9 minutes and peaks at 14 GB. The top 500 contains many broad survey papers, a few self-citations, and scores move by up to 18% after a nightly ETL adds 120k citations and a new :Preprint label. Product wants a stable monthly top-500 influence list and asks whether to switch to ArticleRank, add reverse edges, or change the projection. They cannot increase heap.

1. Should the team use PageRank or ArticleRank for this citation-influence list? Explain the effect on citation semantics and how to validate the choice.

Read the worked answer

PageRank treats every outgoing citation as an equal vote: a paper's score is divided across the references it makes. In a citation graph, out-degree is usually small and uneven, so PageRank can over-reward a citation from a paper with a very short reference list. ArticleRank is designed for citation analysis and adds the average out-degree to the denominator, dampening that over-weighting of low-out-degree nodes. That does not make ArticleRank automatically correct; it is a modelling choice.

For a broad influence list, keep PageRank if the business believes each citation should count equally. Switch to ArticleRank if short bibliographies are distorting the ranking. Validate by running both in mutate mode, writing scores to node properties, and comparing the top-500 overlap, rank correlation, and a manual sample. Do not decide from a single top-10 list. Also filter self-citations in a Cypher projection or exclude them before ranking, because self-loops inflate scores without adding scholarly influence.

2. A colleague proposes changing the projection to UNDIRECTED to capture reciprocal citations. What are the consequences for scores and memory, and what would you do?

Read the worked answer

UNDIRECTED projection stores both directions internally, so 31 million CITES relationships become roughly 62 million directed storage entries. Memory already peaks at 14 GB of a 16 GB heap, so this is likely to fail or force unsafe concurrency reductions. Semantically it is also wrong for citation influence: a paper would receive rank from the papers it cites, not only from papers that cite it. Reciprocal citations that genuinely exist are already represented as two directed relationships in a NATURAL projection.

Keep orientation NATURAL. If the team needs co-citation or bibliographic coupling, create a separate derived relationship type and project that graph, rather than changing the meaning of the influence graph. Use gds.pageRank.mutate with a mutateProperty, then query the top 500 from the stored scores, instead of streaming 8.4 million rows. That reduces client-side overhead and makes month-over-month comparison straightforward.

3. How would you make the monthly run stable and memory-safe without adding heap?

Read the worked answer

First estimate both projection and execution: gds.graph.project.estimate for the exact labels, relationship types, orientation, and properties, then gds.pageRank.mutate.estimate. Project only what the algorithm needs. If :Preprint nodes participate in citations, they must be included as nodes or the graph changes; if they are irrelevant, exclude them. Keep NATURAL orientation and do not add weights unless the business defines citation weights.

Run PageRank in mutate mode, write scores to a property, and inspect didConverge and ranIterations from gds.pageRank.stats. Use concurrency 2 or 4 rather than 8 on a 16 GB heap, and drop stale graphs after checking gds.graph.list. Exclude self-citations with a Cypher projection if they matter. Score movement after new citations is expected, not necessarily instability; persist each monthly score and compare rank movement. If the top 500 is still unstable, increase maxIterations or tighten tolerance only after confirming convergence.