james.dole
james.dole

Reputation: 3

Neo4j 5 Star User rating implementation

I am attempting to create a user rating system through the use of Neo4j and was hoping y'all could lend some advice. The way I originally thought to approach this is through relating the user to a StarRate node. In this node I was to have properties of relating property id, as well as a property for each of the 5 stars in the rating system. For every rating they are given (1-5 stars) I will increment said star's property.

My question is, with this approach, how should I go about collecting the overall star rating? Feel free to drop some ideas or places I could tweak my implementation. Thanks

Upvotes: 0

Views: 84

Answers (2)

yawmoght
yawmoght

Reputation: 767

At the end of the day, it depends on which extra uses you are going to need. Anyway you will need a variable votesAmount for the amount of votes received and totalStars for the sum of all stars, so you can get total rating while being easy to update it. I´ll drop some extra examples:

1) If you want to know, or think you will want to know in the future, who rated whom, then I would suggest creating for each rating:

(user:User)-[rates{rating:3}:RATES]->(otherUser:User)

This extra information could be used to track active users, toxic users, etc. Here the math would be:

MATCH (user:User{name:'user1'})
OPTIONAL MATCH (user)<-[rates:RATES]-(:User)
WITH count(rates) AS totalVotes, sum(rates.rating) AS totalStars

2) If just want to know the average rating of an User, then I would have:

(user:User)-[:HAS_RATING]->(rating{totalStars=16, votesAmount=4})

This makes it easy to get the average rating of an User directly from its node while it´s also easy to add a new rating (add stars to totalStars, add 1 to votesAmount). It´s the same as your idea, but with less information (no stars breakdown) in case you don´t want to use it.

With your original implementation, the total rating for an user it would be:

MATCH (user:User{name:'user1'})-[:HAS_RATING]->(rating:Rating)
WITH rating.stars1 + rating.stars2 + rating.stars3 + rating.stars4 + rating.stars5 as votesAmount,
rating.stars1 * 1 + rating.stars2 * 2 + rating.stars3 * 3 + rating.stars4 * 4 + rating.stars5 * 5 as totalStars

And in any implementation I would finish with

RETURN totalStars/votesAmount AS totalRating

Upvotes: 0

cybersam
cybersam

Reputation: 66999

Instead of creating a rating node (and a relationship) for each user, it would be much simpler if you just had a rating property in each user node.

Upvotes: 1

Related Questions