I have the following function below which I am using to determine a users rank in a scoreboard.
Parse.Cloud.define("getUserGlobalRank", function(request, response)
{
var usernameString = request.params.username;
var scoreAmount = request.params.score;
var globalRankQuery = new Parse.Query("scoreDB");
globalRankQuery.greaterThanOrEqualTo("score",scoreAmount);
globalRankQuery.descending("score");
globalRankQuery.limit("1000");
globalRankQuery.count(
{
success: function(count);
{
response.success(count);
},
.........
However this will not give an accurate response if there are more than 1000 entries that meet that criteria. I would like to chain together a set of .find methods that I can subsequently perform a .count on. Does anyone have any idea how I can achieve this? If you could provide a code example that would be great!
Many thanks, James
Cloud Code is easy to use because it’s built on the same Parse JavaScript SDK that powers thousands of apps. The only difference is that this code runs in your Parse Server rather than running on the user’s mobile device. When you update your Cloud Code, it becomes available to all mobile environments instantly.
The more of your Cloud Code you cover, the more you can be assured that changes don’t have any unforeseen consequences. Traditionally, you have to restart your Parse Server whenever you make changes to Cloud Code. Now, you can type npm run watch, and your Parse Server will auto-restart when any affected files are changed.
Rather than writing code once for each client environment, you can write it just once with Cloud Code. Let’s take a look at our movie review example. When you’re choosing how many stars to give something, you can typically only give 1, 2, 3, 4, or 5 stars.
These are only a few examples of how to write better Cloud Code. You can learn more about new ES6, ES7, ES8, and other ES release features here. On the latest Parse Server Example project, you can now run npm run prettier to style your code, followed by npm run lint , which will run over your Cloud Code and check for quality issues.
The following answer will work in Cloud Code as it keeps track of the count by using a function parameter in successive calls to getUserGlobalRank(). I have used this architecture in similar cases successfully.
As Gene Z. Ragan mentioned in his comment, the currently accepted answer will not work in Cloud Code because there is no 'window' object.
The reason that recursion has been offloaded to a regular Javascript function is because Parse has a very low recursion limit for Cloud Code functions (I have verified that >4 recursive calls to a Cloud Code function will result in an error). By implementing the recursion in a Javascript function, you can bypass Parse's recursive limit, and continue making recursive calls as long as the code executes in the permitted time (about 15 seconds).
Parse.Cloud.define('getUserGlobalRank', function(request, response) {
getUserGlobalRank({'username':request.params.username, 'score':request.params.score}, {
success: function(count) {
response.success(count);
},
error: function(error) {
response.error(error);
}
});
});
function getUserGlobalRank(request, response) {
var usernameString = request['username'];
var scoreAmount = request['score'];
var count = (request['count'])? request['count'] : 0;
var globalRankQuery = new Parse.Query("scoreDB");
globalRankQuery.greaterThanOrEqualTo("score", scoreAmount);
globalRankQuery.descending("score");
globalRankQuery.limit(1000);
globalRankQuery.skip(count);
globalRankQuery.find({
success: function(results) {
if (results.length > 0) {
count = count + results.length;
getUserGlobalRank({'count':count, 'username':usernameString, 'score':scoreAmount}, response);
}
else { // found count of users with higher ranks
response.success(count);
}
},
error: function(error) { // query error
response.error(error);
}
});
}
My goal was to iterate through all users on Parse. Here's my answer based on keither04's answer that is based on Cam Tullos's answer =]
Parse.Cloud.job("checkUsers", function (request, response)
{
// {} - empty params for first iteration
getAllUsers({}, {
success: function (users) {
// Do stuff with users
response.success("Loaded " + users.length + " users");
},
error: function (error) {
response.error(error);
}
});
});
function getAllUsers (request, response)
{
var users = (request["users"]) ? request["users"] : [];
var skip = users.length;
var userQuery = new Parse.Query(Parse.User);
userQuery.limit(1000);
userQuery.skip(skip);
userQuery.find({
success: function (results) {
if (results.length > 0) {
var allUsers = users.concat(results);
var params = {"users": allUsers};
getAllUsers(params, response);
} else {
response.success(users);
}
},
error: function (error) {
response.error(error);
}
});
}
P.S.: I'm curious if it's possible to do using promises.
Parse.Query.count() is not affected by the Parse.com 1000 query limit.
So you will get a correct count returned no matter how many entries matched by the query.
eg:
var userQ = new Parse.Query('_User');
userQ.count({success:function(count){console.log(count)}});
> 1512
var userQ = new Parse.Query('_User');
userQ.limit(100);
userQ.count({success:function(count){console.log(count)}});
> 1512
Bonus points - .limit()
takes a number as its parameter, not a string as in your code.
https://www.parse.com/docs/js/symbols/Parse.Query.html#limit
hth
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With