Finding relevant reviews

Finding relevant reviews


We want to return relevant reviews for a business based on the user’s context. In this section we’ll learn how to use the Personalized PageRank algorithm to do this.

The Personalized PageRank allows us to find influential nodes in a certain part of our graph. We’ll be using it to find influential users so that we can boost the reviews written by those users.

Pre-load reviews graph


We’re going to run the algorithm on a projected graph of users that have written reviews about the same businesses. We’ll pre-load the in memory graph using the following query as we want to run the algorithm multiple times for different users:

CALL algo.graph.load('review-graph',
  'MATCH (u:User) RETURN id(u) AS id',
  'MATCH (u:User)-[:WROTE]->()-[:REVIEWS]->()<-[:REVIEWS]-()<-[:WROTE]-(u2)
   RETURN id(u) AS source, id(u2) AS target, count(*) AS weight',
  {graph:'cypher', direction: "BOTH"});

When we run our algorithms procedures we’ll need to pass in the parameter graph: "review-graph" to have the procedure run against this graph.

Trusted users


We’re going to run the algorithm in the context of a specific user, so let’s first define the userId parameter:

:params userId => "Lk70TsLeGBYSXsnr5q-cXg"

The query below provides a template for computing Personalized PageRank for our user, where the sourceNodes are the users who have reviewed more than one same business as our user. Update the query to:

  • Run the algorithm against our review-graph

  • Use the source nodes computed in the first part of the query

  • Create a relationship between our user and the users returned from the procedure

// Compute source nodes
MATCH (u:User {id: $userId})-[:WROTE]->()-[:REVIEWS]->()<-[:REVIEWS]-()<-[:WROTE]-(other)
WITH u, other, count(*) AS count
WHERE count > 1
WITH u, collect(other) AS sourceNodes

// Execute the PageRank algorithm
CALL algo.pageRank.stream(null, null, {
  iterations:5, direction: "BOTH"
})

// Only keep users that have a PageRank score bigger than the default
YIELD nodeId, score
WITH u, algo.getNodeById(nodeId) AS node, score
WHERE score > 0.15 AND node <> u

// Keep up to 50 users
WITH u, node, score
ORDER BY score DESC
LIMIT 50

// Create a relationship between our user (u) and the influential users (node)

Answer: Trusted users


This is what the answer should look like:

// Compute source nodes
MATCH (u:User {id: $userId})-[:WROTE]->()-[:REVIEWS]->()<-[:REVIEWS]-()<-[:WROTE]-(other)
WITH u, other, count(*) AS count
WHERE count > 1
WITH u, collect(other) AS sourceNodes

// Execute the PageRank algorithm
CALL algo.pageRank.stream(null, null, {
  iterations:5, direction: "BOTH",
  graph: "review-graph", sourceNodes: sourceNodes
})

// Only keep users that have a PageRank score bigger than the default
YIELD nodeId, score
WITH u, algo.getNodeById(nodeId) AS node, score
WHERE score > 0.15 AND node <> u

// Keep up to 50 users
WITH u, node, score
ORDER BY score DESC
LIMIT 50

// Create a relationship between our user (u) and the influential users (node)
MERGE (u)-[trust:TRUSTS]->(node)
SET trust.score = score

Find trusted users


Now we can find the other users that our user trusts by executing the following query:

match (u:User {id: $userId})-[trusts:TRUSTS]->(other)
RETURN other.name, other.id, trusts.score AS score
ORDER BY score DESC

Now let’s update the application to use this new information. Instead of showing reviews based on the date they were written, we want to boost the reviews written by our trusted users.