3

I want to solution for nested queries. Actually, i want to get all reviews for each movie. I have two tables:

Movie:

Movie

Review:

Review

It's possible to calculate rating for each movie and set it to avgRating? I don't know why, but i can't get all reviews for one movie.

Parse.Cloud.define("setAvg", function(request, response) {

    var Movie = Parse.Object.extend("Movie");
    var MovieReview = Parse.Object.extend("MovieReview");

    var query = new Parse.Query(Movie);
    query.each(function(movie){
        var reviewQuery = new Parse.Query(MovieReview);
        reviewQuery.equalTo("relatedMovie", movie);
        reviewQuery.find({
          success: function(reviews){
               console.log(reviews);
            }
        });
    }).then(function() {
    response.success("Migration completed successfully.");
    }, function(error) {
    response.error("Uh oh, something went wrong.");
});
});

I getting in logs:

I2015-12-21T17:34:57.777Z][]
I2015-12-21T17:34:57.778Z][{}]
I2015-12-21T17:34:57.779Z][{},{}]
I2015-12-21T17:34:57.780Z][{},{}]
I2015-12-21T17:34:57.781Z][{},{},{}]
I2015-12-21T17:34:57.782Z][{},{}]
4
  • Don't forget return before reviewQuery.find() Commented Dec 21, 2015 at 15:03
  • 1
    Possible duplicate of Group By / Sum Aggregate Query with Parse Cloud Code Commented Dec 21, 2015 at 15:04
  • In addition to the options outlined in that question, there's also the option of using Cloud Code to update a separate table when ratings are inserted/updated/deleted. Commented Dec 21, 2015 at 15:05
  • I already saw this answer. But for first, i need to get all reviews for each movie. Commented Dec 21, 2015 at 15:06

3 Answers 3

1
Parse.Cloud.define("setAvg", function(request, response) {

    var Movie = Parse.Object.extend("Movie");
    var MovieReview = Parse.Object.extend("MovieReview");
    var reviewQuery = new Parse.Query(MovieReview);
    var query = new Parse.Query(Movie);
    query.equalTo("relatedMovie",reviewQuery);
    query.find(function(movie){
        //do whatever you want with the query results
    });
});
Sign up to request clarification or add additional context in comments.

3 Comments

Thank for you answer, but it doesn't work. Each review have relation to Movie.
do you want to get all the movies and then calculate the avg ?
I have table with movie_reviews. Movie may contains 3 reviews. I need to calculate avg for each movie from 3 review.
0

I can see several potential issues :

  • You should use a background job instead of a function to ensure you have enough time

  • You should define the reviewQuery inside the each block to avoid mixing

  • If you can have more than 100 ratings for one movie, you should set the limit of query to 1000 (which is the maximum limit - if there could be more than 1000, you will have to make the same query several times while incrementing the skip parameter).

3 Comments

Thanx for your answer. 1) I use function only for tests. 2) I already fix it 3) Maximum - it's 3 ratings
When some reviews are missing, are there other reviews for the same movie which are not missing ?
Sorry, i don't fully understand, what you mean. Each movie contains 3 reviews. Data filled by script. Script check all data, before inserting. Each review contains rating and related field to movie.
0

The solution was as simple as possible. Thank all for answers.

Parse.Cloud.job("setMovieRating", function(request, response) {
Parse.Cloud.useMasterKey();
var Movie = Parse.Object.extend("Movie");
var MovieReview = Parse.Object.extend("MovieReview");
var query = new Parse.Query(Movie);
query.each(function(movie){
        var reviewQuery = new Parse.Query(MovieReview);
        reviewQuery.equalTo("relatedMovie", movie);
        return reviewQuery.find().then(function(reviews){
            var avgRating = 0;
            for (var i=0; i<reviews.length;i++){
                avgRating+=reviews[i].get('starRating');
            }
            avgRating = avgRating/reviews.length;
            var floatRating = Math.floor(avgRating * 100) / 100;
            movie.set('avgRating', parseFloat(floatRating.toFixed(1)));
            console.log(movie);
            movie.save();
        });
}).then(function() {
    response.success("Success");
  }, function(error) {
    response.error("Uh oh, something went wrong.");
});
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.