javascript - 解析: Compound Query on Followers times out

标签 javascript android parse-platform inner-query

我有一个 Activity 表,其中显示哪些用户关注谁。 (fromUsertoUser) 我正在构建一个排行榜,以查看关注者中谁的评分最高。

所以我创建了这个查询:

ParseQuery<ParseObject> queryActivityFollowing = new ParseQuery<>("Activity");
queryActivityFollowing.whereEqualTo("type", "follow");
queryActivityFollowing.whereEqualTo("fromUser", ParseUser.getCurrentUser());
queryActivityFollowing.setLimit(500);

// innerQuery, only get Users posted by the users I follow
ParseQuery<ParseUser> queryUserFollowing = ParseUser.getQuery();
queryUserFollowing.whereMatchesQuery("toUser", queryActivityFollowing);

// querySelf
ParseQuery<ParseUser> querySelf = ParseUser.getQuery();
querySelf.whereEqualTo("objectId", ParseUser.getCurrentUser().getObjectId());

List<ParseQuery<ParseUser>> queries = new ArrayList<>();
queries.add(queryUserFollowing);
queries.add(querySelf);

query = ParseQuery.or(queries);
query.orderByDescending("rating_count");
query.setLimit(20);

但不知何故,它超时并且从未显示结果。 我的查询是否存在效率低下的问题?

谢谢!

编辑: 数据说明: Activity 是一个包含 3 列的类,fromUsertoUsertypefromUsertoUser 是指向 _User 类的指针,type 是一个字符串

_User中,我有经典属性和一个名为 rating_count的整数,它是orderBy条件(上面更新的代码)。

实际上,我认为查询并没有超时,只是返回0个结果。我关注了一些用户,所以这绝对不是预期的输出。

最佳答案

这是一个困难的问题,因为 parse 的查询仅最低程度地支持此类事情。我能提供的最好的想法是这个:

  1. 对 Activity 表进行一次查询 whereEqualTo("type", "follow")whereEqualTo("fromUser", ParseUser.getCurrentUser())
  2. 没有queryUserFollowing,没有querySelf。这些都是不必要的。这也使您从 Parse.Query.or() 中解放出来。
  3. setLimit(1000) 将在下面解释原因
  4. include("toUser")
  5. 完成后,循环遍历结果,最大化 result.get("toUser").getInt("rating_count") 因为结果将是 Activity 的实例,并且您会急切地获取其相关的 toUsers。

这个方案比您编码的方案更简单,并且可以完成工作。然而,一个主要问题可能是它会丢失关注者超过 1000 名的用户的数据。如果这是一个问题,请告诉我,我可以提出更复杂的答案。一个小缺点是,您将被迫自己在内存中进行搜索(也许是排序)以找到最大的 rating_count。

编辑 - 对于 > 1k 关注者,您必须多次调用查询,将 skip 设置为上一个查询中收到的记录数,收集结果在一个大数组中。

您关于传输如此多数据的观点得到了很好的理解,您可以通过将所有这些放入云函数中,在云中执行内存工作并仅返回客户端需要的记录来最大限度地减少网络使用。 (这种方法的另一个好处是使用 javascript 进行编码,我比 java 说得更流利,因此我可以对代码更加规范)。

编辑 2 - 在云代码中执行此操作的好处是减少了那些具有最高评级的用户(例如 20 个)的网络流量。它没有解决我之前指出的其他问题。这是我在云中执行此操作的方法...

var _ = require('underscore');

Parse.Cloud.define("topFollowers", function(request, response) {
    var user = new Parse.User({id:request.params.userId});
    topFollowers(user, 20).then(function(result) {
        response.success(result);
    }, function(error) {
        response.error(error);
    });
});

// return the top n users who are the top-rated followers of the passed user
function topFollowers(user, n) {
    var query = new Parse.Query("Activity");
    query.equalTo("type", "follow");
    query.equalTo("fromUser", user);
    query.include("toUser");
    return runQuery(query).then(function(results) {
        var allFollowers = _.map(results, function(result) { return result.get("toUser"); });
        var sortedFollowers = _.sortBy(allFollowers, function(user) { return user.get("rating_count"); });
        return _.first(sortedFollowers, n);
    });
}

// run and rerun a query using skip until all results are gathered in results array
function runQuery(query, results) {
    results = results || [];
    query.skip(results.length);
    return query.find().then(function(nextResults) {
        results = results.concat(nextResults);
        return (nextResults.length)? runQuery(query, results) : results;
    });
}

注意 - 我还没有测试过这个,但在生产中也有类似的东西。

关于javascript - 解析: Compound Query on Followers times out,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30444204/

相关文章:

javascript - 在 Angular 路由/ View 加载后加载 jQuery 脚本

javascript - 将 JSON 字符串转换为 JSON 对象,这样我就不需要更改基础 jquery.dataTables.js

java - Android中的单例与应用程序上下文?

Android webview 加载数据给出 NullPointerException

ios - 如何使 Parse Installation 对象的属性成为指向 User 对象的指针?

javascript - 使用 Json Schema 的构造函数、getter 和 setter 生成 Javascript 类

javascript - 使用 Draftjs 的简单撤消和重做按钮

java - 用Java创建一个文字游戏(字典文件组织问题)

ios - 如何使用 parse.com 服务器 iOS 保存对象数组?

android - 在哪里使用解析为Android应用程序添加电子邮件验证码