Combine Complex Neo4J queries as One

Hello All,

I have quite a complex query that I really need to understand on how to solve it.
I have an objective on doing a recommendation system in Neo4J. These are my two key routes and I have all the query working:

  1. The first Neo4J query looks for friends you have a [:FOLLOW] relationship with, it then checks all the other friends [:FOLLOW] relationship exists and suggest to the main id the restaurants he can potentially [:LIKE]. I paste the code below:
MATCH (user1:User {id:"61e06691c958cbd19baf4843"})-[:FOLLOWS]->(user2:User)-[:FOLLOWS]->(otherFriends1:User),
(otherFriends1)-[:FOLLOWS]->(user3:User)-[:LIKES]->(restaurant:Restaurant)
RETURN restaurant.id AS SuggestedRestaurants, count(*)AS Strength
ORDER BY Strength DESC
  1. I do a traversal to first search for Other users who you might not have a [:FOLLOW] relationship with but [:LIKES] a Restaurant you like, which also traverses to suggest his other Restaurants that you do not [:FOLLOW] but can possibly follow. I have the code below:

MATCH (user1:User {id:"61e06691c958cbd19baf4843"})-[:LIKES]->(restaurant:Restaurant)<-[:LIKES]-(otherUser:User),
(otherUser)-[:LIKES]->(otherRestaurant:Restaurant)
RETURN otherRestaurant.id AS OtherRestaurants, count(*) AS STRENGTH ORDER BY STRENGTH DESC

Now my question is I will want to combine these queries as one which will also integrate all results into one. I am building an API with this and I need your help on how to possibly accomplish this.
Thank you.

Since the columns are the same for the two queries, you can combine with the ‘Union’ clause.

You can also put the order by clause after if you want to rank the full list as one.

I don't have test data to test, but it executes. The following joins the two queries with a union, sorting the after they are merged to get a total ranking. I also included a literal type so you can distinguish what type of restaurant suggestion each is if that matters. Remove it if not.

I also removed the unused variable bindings, and compressed the first pattern by noticing that you wanted exactly 3 'FOLLOWS' relationships between two users.

MATCH (user:User {id:"61e06691c958cbd19baf4843"})
CALL {
MATCH (user)-[:FOLLOWS3..3]->(:User)-[:LIKES]->(restaurant:Restaurant)
RETURN 'suggested' as type, restaurant.id AS SuggestedRestaurants, count(
) AS Strength
UNION
MATCH (user)-[:LIKES]->(:Restaurant)<-[:LIKES]-(otherUser:User),
(otherUser)-[:LIKES]->(otherRestaurant:Restaurant)
RETURN 'otherSuggested' as type, otherRestaurant.id AS SuggestedRestaurants, count(*) AS Strength
}
RETURN type, SuggestedRestaurants, Strength
ORDER BY Strength DESC

Thank you so much, I refactored using your approach and it works

MATCH (user:User {id:"61e06691c958cbd19baf4843"})
CALL {
MATCH (user)-[:FOLLOWS]->(user2:User)-[:FOLLOWS]->(user3:User),(user3)-[:FOLLOWS]->(user4:User)-[:LIKES]->(restaurant:Restaurant)
RETURN 'suggested' as type, restaurant.id AS SuggestedRestaurants, count(*) AS Strength
UNION
MATCH (user)-[:LIKES]->(:Restaurant)<-[:LIKES]-(otherUser:User),
(otherUser)-[:LIKES]->(otherRestaurant:Restaurant)
RETURN 'otherSuggested' as type, otherRestaurant.id AS SuggestedRestaurants, count(*) AS Strength
}
RETURN type, SuggestedRestaurants, Strength
ORDER BY Strength DESC

However, I am getting some warnings emitted in Neo4J. What could be the reason? An image has been attached below


@glilienfield

Try inserting a “WITH user” statement between the MATCH and CALL statements.

1 Like