You can use Cypher projection to be more selective about which nodes and relationships to process with an graph algorithm.
For example, to execute the algo.pageRank algorithm only on Page
nodes whose timestamp > 1000
, and LINKS
relationships that have a specific property x
, this should work:
MERGE (dummy:Dummy)
WITH dummy, ID(dummy) AS dummy_id
CALL algo.pageRank.stream(
'OPTIONAL MATCH (p:Page) WHERE p.timestamp > 1000 RETURN CASE WHEN p IS NOT NULL THEN ID(p) ELSE ' + dummy_id + ' END AS id',
'OPTIONAL MATCH (p1:Page)-[link:LINKS]->(p2:Page) WHERE EXISTS(link.x) WITH CASE WHEN link IS NOT NULL THEN [ID(p1), ID(p2)] ELSE [' + dummy_id + ',' + dummy_id + '] END AS res RETURN res[0] AS source, res[1] as target',
{graph:'cypher', iterations:20, dampingFactor:0.85})
YIELD node, score
WITH dummy, node, score
WHERE node <> dummy
RETURN node, score ORDER BY score DESC LIMIT 20;
NOTE: The graph algorithms are currently badly behaved (i.e., they throw exceptions) when either of the Cypher statements used in a Cypher projection return no results. The above query works around that by making sure that both statements return a dummy node instead of returning nothing. The Cypher statement that "wraps" the algorithm call will then filter out the dummy node if it is returned by the algorithm.