5

我有以下函数,我用它来确定用户在记分牌中的排名。

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);                
        },

…………

但是,如果符合该标准的条目超过 1000 个,则不会给出准确的响应。我想将一组 .find 方法链接在一起,随后我可以对其执行 .count 。有谁知道我怎么能做到这一点?如果你能提供一个代码示例那就太好了!

非常感谢,詹姆斯

4

5 回答 5

5

以下答案适用于 Cloud Code,因为它通过在对 getUserGlobalRank() 的连续调用中使用函数参数来跟踪计数。我在类似的案例中成功地使用了这种架构。

正如 Gene Z. Ragan 在他的评论中提到的,当前接受的答案在 Cloud Code 中不起作用,因为没有“窗口”对象。

将递归卸载到常规 Javascript 函数的原因是 Parse 对 Cloud Code 函数的递归限制非常低(我已经验证对 Cloud Code 函数进行 >4 次递归调用会导致错误)。通过在 Javascript 函数中实现递归,您可以绕过 Parse 的递归限制,只要代码在允许的时间(大约 15 秒)内执行,就可以继续进行递归调用。

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);
        }
    });
}
于 2015-05-26T00:41:19.177 回答
4

我的目标是遍历 Parse 上的所有用户。这是我基于 keither04 的答案的答案,该答案基于 Cam Tullos 的答案 =]

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);
        }
    });
}

PS:我很好奇是否可以使用承诺。

于 2015-09-05T06:51:09.730 回答
3

使用计数时要小心。对于具有超过 1000 个对象的类,计数操作受超时限制。它们通常会产生超时错误或返回仅大致正确的结果。因此,最好构建您的应用程序以避免这种计数操作。我通常像这样使用跳过参数:

Parse.Cloud.define('getUserGlobalRank', function(request, response) {
var output = [];
var usernameString = request.params.username;
var scoreAmount = request.params.score;
var skip = (request.params['skip']) ? request.params.skip : 0;

if (skip == 0 || !window['results']) { window['results'] = []; }

var qry = new Parse.Query('scoreDB');
qry.greaterThanOrEqualTo('score', scoreAmount);
qry.descending('score');
qry.limit(1000);
qry.skip(skip);
qry.find({
    success: function (results) {
        if (results.length > 0) { // got results..
            output = output.concat(results);

            // Call the function again
            var params = request.params;
            params['skip'] = results.length;
            request.params = params;
            Parse.Cloud.run('getUserGlobalRank', request, response);

        } else { // we're done here
            response.success(output);
        }
    },
    error: function (err) {

    }
});
});
于 2013-06-24T04:56:31.950 回答
3

Parse.Query.count() 不受 Parse.com 1000 查询限制的影响。

因此,无论查询匹配多少条目,您都会返回正确的计数。

例如:

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

加分 -.limit()将数字作为参数,而不是代码中的字符串。 https://www.parse.com/docs/js/symbols/Parse.Query.html#limit

hth

于 2013-02-15T17:47:15.800 回答
0

估计这应该在实现承诺方面起作用。另外,很遗憾的是,skip 只支持最多 10,000 个,但我以前错了。完全披露,我没有测试过这段代码。

    Parse.Cloud.job("checkUsers", function(request, response) {
        // {} - empty params for first iteration
        getAllUsers({}).then(function(users) {
            // Do stuff with users
          response.success("Loaded " + users.length + " users");
        },
        function(error) {
            response.error(error);
        });

    });

    function getAllUsers(request) {
        //
      var users = (request["users"]) ? request["users"] : [];
      var skip = users.length;
      var userQuery = new Parse.Query(Parse.User);
      userQuery.limit(1000);
      userQuery.skip(skip);

      Parse.Promise.as().then(function() {
        //
        return userQuery.find().then(null, function(error) {
            //
            return Parse.Promise.error(error);

        });     

      }).then(function(userObjects) {
        //
        if (userObjects.length > 0) {
          var allUsers = users.concat(userObjects);
          var params = {"users": allUsers};
          getAllUsers(params);
        } else {
            //
          return Parse.Promise.resolve(allUsers);
        }       

      },
      function(error) {
        //
        return Parse.Promise.reject(error);
      });

    }
于 2016-01-22T10:06:28.400 回答