Calling gds.pagerank.write for a nodequery

I am a newbie. I am a faculty and NWU and we have a StreamingAnalytics course where we walk students through a couple lessons on Neo4J. We have a retail example that we use to walk students through links, relationships. One of the exercises uses gds.pagerank.write.
The following runs in earlier 4.1.5 version of Neo4j.
CALL gds.pageRank.write({
nodeQuery: 'MATCH (c:Customer)-[:WROTE_REVIEW]->()-[:REVIEWS]->(p), (p)-[:IN_CATEGORY]->(:Category {category: $category}) WITH c, count(*) AS reviews WHERE reviews >= $cutoff RETURN id(c) AS id',
relationshipQuery: 'MATCH (c1:Customer)-[:WROTE_REVIEW]->()-[:REVIEWS]->(p), (p)-[:IN_CATEGORY]->(:Category {category: $category}) MATCH (c1)-[:FRIEND_WITH]->(c2) RETURN id(c1) as source, id(c2) AS target',
writeProperty: "tablesPageRank",
validateRelationships: false,
parameters: {category: "Tables", cutoff: 1}
})
YIELD nodePropertiesWritten, ranIterations
RETURN nodePropertiesWritten, ranIterations

But running this on the latest version returns the error,
Type mismatch: expected String but was Map (line 1, column 25 (offset: 24))
"CALL gds.pageRank.write({"
^

Has this changed in the latest version? I do not see examples of how this is supported in the latest version.
Thank you
Krishna

Warning, I have not used GDS, but I took a brief look at the manual. The way I interpret it, is you have to create a named graph using the ‘project’ method, then you call the ‘page rank’ algorithm specifying the projected graph and the algorithm parameters. This explains your error, where it is looking for a string as the first argument, which is the projected graph’s name.

I think this changed from GDS 1 to GDS 2.

2 Likes

Hello Krishna,
I'm in your class and dealt with this exact issue :smiley:

The problem as @glilienfield noted is that in GDS > 2.x it expects a graph projection. Some of the code that was provided is outdated with current versions. This is how I ultimately solved the issues below:

Step 1, Create a Graph Projection:

// Create Graph Projections
CALL gds.graph.project.cypher(
    'OnMart_v1',
    'MATCH (c:Customer)-[:WROTE_REVIEW]->()-[:REVIEWS]->(p), (p)-[:IN_CATEGORY]->(:Category {category: "Tables"}) WITH c, count(*) AS reviews WHERE reviews >= 1 RETURN id(c) AS id',
    'MATCH (c1:Customer)-[:WROTE_REVIEW]->()-[:REVIEWS]->(p), (p)-[:IN_CATEGORY]->(:Category {category: "Tables"}) MATCH (c1)-[:FRIEND_WITH]->(c2) RETURN id(c1) as source, id(c2) AS target',
    {validateRelationships: False}
)
YIELD graphName AS graph, nodeQuery, nodeCount AS nodes, relationshipQuery, relationshipCount AS rels

You'll notice above I simplified the query by getting rid of the parameters: {category: "Tables", cutoff: 1} values and simply inserting them into the cypher. It seemed unnecessarily complicated to keep the parameters so I simplified this to avoid any other breakages.

Step 2, write tablesPageRank values to nodes

// write tablesPageRank values to nodes
CALL gds.pageRank.write('OnMart_v1',{
    maxIterations: 20,
    dampingFactor: 0.85,
    writeProperty: 'tablesPageRank'
})
YIELD nodePropertiesWritten, ranIterations
RETURN nodePropertiesWritten, ranIterations

The rest of the code provided should work with zero modifications. I ingested and ran this against the 1000 node sample provided. You should have similar outputs:

Let me know if you have any other issues. I'll be out of pocket till Sunday running an ultra marathon.
Good Luck!
Chad

1 Like