Alexandre Estevam
11/23/2022, 7:35 AMKishore G
Kishore G
Alexandre Estevam
11/23/2022, 9:05 AMjson
{
"postId": "1",
"rating": 10
}
For each “PostRated” event, I’m doing an incremental calculation to a table storing a json like this to get a “FinalScore” of the post and some other values necessary to build the user rank:
“PostScore”
json
{
"avg": 0,
"oldAvg": 0,
"post": {
"postId": "1",
"userId": "2",
"createdAt": "2022-10-10T00:00:00.000Z"
},
"count": 0,
"avgScore": 0,
"finalScore": 0,
"karmaRange": { "max": 10, "min": 0 },
"newVariance": 0,
"oldVariance": 0,
"cntEachRating": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"sumScoreEachRating": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"avgRatingsWithinKarma": 0,
"cntRatingsWithinKarma": 0,
"isConsideredForRanking": false
}
I did it in this way because of the requirement to calculate the “FinalScore” based on standard deviation and some other rules. So I always store some
aditional values that helps me calculate the next score without querying all ratings to get the standard deviation and etc...
For the user scores I’m doing something similar to calculate the scores for each user based on the requirements and I always keep a document like this for each user:
“UserScore”
json
{
"avgs": {
"avgStd": 0,
"avgValidRating": 0,
"avgValidRatingQty": 0,
"avgAgeConsideredPosts": 0,
"avgScoreConsideredPosts": 0,
"avgAgeScoreConsideredPosts": 0,
"avgFinalScoreConsideredPosts": 0
},
"userId": "1",
"finalScore": 0,
"validPostsQuantity": 0
}
Finally, what I currently have is a query that ranks the top 100 users by the “FinalScore” and can also search by the name to get the positions of users that name match a query param:
sql
# sample query
SELECT position, # and other fields from user FROM
(SELECT ROW_NUMBER() over (order by finalScore DESC) position, userId from UserScore limit 100) # ...
# INNER JOIN User...
# WHERE User.name like "%something%"
With this I can only get the User Ranking with name filtering, this is for only one requirement of the app. I’m not sure if this would work in production scale for millions of users (probably not).
I’m trying to create different rankings for each type of dimensions like category, skill but with this approach I think would have to pre-calculate all possible
user scores for each separate rank. It would be very complex for me and that’s why I’m searching for another solution
I also have to create another query (or multiple queries) to build a table like this to display to the end user:
Ex:
--------------------------------------
Category | Country | All |
--------------------------------------
| Brazil | World |
-------------------------------------
All | 1° Pos | 20° pos |
(10 users) (500 users)|
--------------------------------------
Cat1 | 5° Pos | 5° pos |
(10 users) (20 users) |
--------------------------------------
- Position of a specific user in this ranking
- Number of users inside an specific ranking (when filtering post dimensions like category and skills)
---
When I found Apache Pinot, I though it could help me in some way. Maybe I could only use PostScore table to load information to Pinot and calculate the UserScore for each dimension in a query so I can rank it in real-time, but I’m not sure it is possible.
Sorry if it’s very long. I really don’t know what to do.Kishore G
Mayank
Alexandre Estevam
11/23/2022, 4:04 PMMayank
Alexandre Estevam
11/24/2022, 8:46 AMMayank
Alexandre Estevam
11/24/2022, 6:41 PMMayank
Mayank
Alexandre Estevam
11/24/2022, 6:54 PMKenny Bastani
11/26/2022, 5:42 PMKenny Bastani
11/26/2022, 5:46 PMKenny Bastani
11/26/2022, 5:47 PMMayank
Mayank
Alexandre Estevam
11/28/2022, 1:48 PMKenny Bastani
11/29/2022, 5:02 PM