As of April 12th, you must go to Progress SupportLink to create new support cases or to access existing cases. Please, bookmark the SupportLink URL and use the new portal to contact the support team.
Even tough I'm working with Kinveys HTML/Javascript API my question is of general purpose:
Let's say there is a collection called PRODUCTS holding a list of simple products with name, description, type, price, etc.
Users now can rate these products within a range from 1 (worst) to 5 (best). All the user ratings are stored in collection RATINGS.
As you can think there is a 1:many relation from a PRODUCTS to RATINGS (a product can be have one or many ratings).
Requirement:Whenever a user requests a product list from PRODUCTS collection he also should see the average rating of each product in that list.
In a relational database this an easy task but I don't know what's the best way to do that in Kinvey? I'm aware there are grouping and average functions in Kinvey API. So the math part is not the point. I wonder how I should "join" the data to get the average rating of each request product. Consider there could be like 1'000 ratings for a single product and a user may request 100 distinct products.
I'm open for any idea to solve this in a proper and effective/fast way.
Regards
Best Answer
M
Martin Apostolov
said
about 4 years ago
Hi Tayger,
It mostly depends what your expected usage pattern is - whether GET request are more, whether you expect to have more request to the PRODUCTS collection or to the USER collection (retrieving users that made the rating).
If you mainly expect to retrieve the average rating each product has, and rarely to retrieve all the ratings a user has made, then storing the ratings as an array in the PRODUCTS would be a good solution as you would retrieve both the Products and the Ratings in a single request.
Another solution would be to use a separate Ratings collection and to store just the the calculated average for each product in the Products collections. This requires that when a new rating is added by a user, you would:
1) add the rating to the RATINGS collection
2) calculate the new average and update that number in the Products collection for the given item.
The benefit of this approach is that you would not have to calculate the average each time someone makes a GET request but you would calculate it just once - when new entry is added.
It mostly depends what your expected usage pattern is - whether GET request are more, whether you expect to have more request to the PRODUCTS collection or to the USER collection (retrieving users that made the rating).
If you mainly expect to retrieve the average rating each product has, and rarely to retrieve all the ratings a user has made, then storing the ratings as an array in the PRODUCTS would be a good solution as you would retrieve both the Products and the Ratings in a single request.
Another solution would be to use a separate Ratings collection and to store just the the calculated average for each product in the Products collections. This requires that when a new rating is added by a user, you would:
1) add the rating to the RATINGS collection
2) calculate the new average and update that number in the Products collection for the given item.
The benefit of this approach is that you would not have to calculate the average each time someone makes a GET request but you would calculate it just once - when new entry is added.
Regards
Martin Apostolov
1 person likes this
T
Tayger
said
about 4 years ago
Hi Martin
Wow, thanks for the answer! The last view days I was thinking around the solution you provided at last. That's now how exactly I will do it! There will be way more GETs than new ratings. So therefore this solution makes sense. I'll do the math with Kinvey's backend logic. Excellent, thank you!
Tayger
T
Tayger
said
about 4 years ago
A word after in case someone else needs something similar. I was able to create the needed Business Logic that now does the job:
1. POSTSAVE (on collection RATINGS): Get the product ID from the inserted/updated user rating.
2. Get all ratings of this inserted/updated product ID rating from RATINGS
3. Iterate through them to sum them up and divide the result by all found ratings of this product.
4. Replace the old rating of the related product in collection PRODUCT by the new calculated product. This can be done in two ways:
a) Read the product record from PRODUCT, replace the rating, store the product record back to PRODUCT
b) Pranav gave once a good hint in another post: Use $SET to modify single attributes inside a collection (works only in backend logic):
The $set command will only modify the product.rating (column product > key value of rating in stored object and product.amount (column product > key value of amount (amount of ratings) in stored object).
I would have wanted the Business Logic would/could do the average calculation AND the count (amount of ratings) but that seems not be possible in one step. Therefore I let Javascript do the job, no big thing.
I'm aware Business Logic shouldn't be used anymore but it's very powerful/easy to use while FlexService needs some local installation (as far as I've understood). So, Kinvey, please keep Business Logic. ;)
Regards
Tayger
L
Logan
said
about 4 years ago
Yes thank you so much for the answer..It was really helpful...Thanl you so much for sharing
Tayger
Even tough I'm working with Kinveys HTML/Javascript API my question is of general purpose:
Let's say there is a collection called PRODUCTS holding a list of simple products with name, description, type, price, etc.
Users now can rate these products within a range from 1 (worst) to 5 (best). All the user ratings are stored in collection RATINGS.
As you can think there is a 1:many relation from a PRODUCTS to RATINGS (a product can be have one or many ratings).
Requirement:Whenever a user requests a product list from PRODUCTS collection he also should see the average rating of each product in that list.
In a relational database this an easy task but I don't know what's the best way to do that in Kinvey? I'm aware there are grouping and average functions in Kinvey API. So the math part is not the point. I wonder how I should "join" the data to get the average rating of each request product. Consider there could be like 1'000 ratings for a single product and a user may request 100 distinct products.
I'm open for any idea to solve this in a proper and effective/fast way.
Regards
Hi Tayger,
It mostly depends what your expected usage pattern is - whether GET request are more, whether you expect to have more request to the PRODUCTS collection or to the USER collection (retrieving users that made the rating).
If you mainly expect to retrieve the average rating each product has, and rarely to retrieve all the ratings a user has made, then storing the ratings as an array in the PRODUCTS would be a good solution as you would retrieve both the Products and the Ratings in a single request.
Another solution would be to use a separate Ratings collection and to store just the the calculated average for each product in the Products collections. This requires that when a new rating is added by a user, you would:
1) add the rating to the RATINGS collection
2) calculate the new average and update that number in the Products collection for the given item.
The benefit of this approach is that you would not have to calculate the average each time someone makes a GET request but you would calculate it just once - when new entry is added.
Regards
Martin Apostolov
- Oldest First
- Popular
- Newest First
Sorted by Oldest FirstMartin Apostolov
Hi Tayger,
It mostly depends what your expected usage pattern is - whether GET request are more, whether you expect to have more request to the PRODUCTS collection or to the USER collection (retrieving users that made the rating).
If you mainly expect to retrieve the average rating each product has, and rarely to retrieve all the ratings a user has made, then storing the ratings as an array in the PRODUCTS would be a good solution as you would retrieve both the Products and the Ratings in a single request.
Another solution would be to use a separate Ratings collection and to store just the the calculated average for each product in the Products collections. This requires that when a new rating is added by a user, you would:
1) add the rating to the RATINGS collection
2) calculate the new average and update that number in the Products collection for the given item.
The benefit of this approach is that you would not have to calculate the average each time someone makes a GET request but you would calculate it just once - when new entry is added.
Regards
Martin Apostolov
1 person likes this
Tayger
Hi Martin
Wow, thanks for the answer! The last view days I was thinking around the solution you provided at last. That's now how exactly I will do it! There will be way more GETs than new ratings. So therefore this solution makes sense. I'll do the math with Kinvey's backend logic. Excellent, thank you!
Tayger
Tayger
A word after in case someone else needs something similar. I was able to create the needed Business Logic that now does the job:
1. POSTSAVE (on collection RATINGS): Get the product ID from the inserted/updated user rating.
2. Get all ratings of this inserted/updated product ID rating from RATINGS
3. Iterate through them to sum them up and divide the result by all found ratings of this product.
4. Replace the old rating of the related product in collection PRODUCT by the new calculated product. This can be done in two ways:
a) Read the product record from PRODUCT, replace the rating, store the product record back to PRODUCT
b) Pranav gave once a good hint in another post: Use $SET to modify single attributes inside a collection (works only in backend logic):
The $set command will only modify the product.rating (column product > key value of rating in stored object and product.amount (column product > key value of amount (amount of ratings) in stored object).
I would have wanted the Business Logic would/could do the average calculation AND the count (amount of ratings) but that seems not be possible in one step. Therefore I let Javascript do the job, no big thing.
I'm aware Business Logic shouldn't be used anymore but it's very powerful/easy to use while FlexService needs some local installation (as far as I've understood). So, Kinvey, please keep Business Logic. ;)
Regards
Tayger
Logan
Yes thank you so much for the answer..It was really helpful...Thanl you so much for sharing
-
What is the best way to store and load hierarchies/relationships in the Data Store?
-
How do I create in-app payments using Kinvey?
-
Link users to file uploads
-
question about references and user permissions
-
Data storage limits?
-
Relational Data - Files
-
What defines an Active User?
-
"The app backend is under lockdown"
-
query doesn't show files, can't download.
-
Posting Code to Forum
See all 316 topics