解析服务器,MongoDB - 获取对象的“喜欢”状态

时间:2018-01-14 10:39:04

标签: database mongodb parse-platform mongodb-query parse-server

我正在使用在MongoDB上运行的Parse Server。

假设我有集合UserComment以及用户和评论的联接表。 用户可以喜欢注释,这会在连接表中创建新记录。

特别是在Parse Server中,可以使用集合中的“关系”字段定义连接表。

现在,当我想要检索所有评论时,我还需要知道当前用户是否都喜欢它们。如何在不进行其他查询的情况下执行此操作?

你可能会说我可以在likers表中创建一个数组字段Comment并使用$elemMatch,但这似乎不是一个好主意,因为可能有数千个喜欢评论。

我的想法,但我希望有更好的解决方案:

我可以在someLikers表中创建一个数组字段allLikers,一个关系(连接表)字段likesCount和一个数字字段Comment。然后将someLikersallLikers中的前100个喜欢者和allLikers中的其他喜欢者放在一起。我总是递增likesCount

然后在查询评论列表时,我会用$elemMatch实现调用,这会告诉我当前用户是否在someLikers内。当我收到评论时,我会检查一些评论是否likesCount > 100$elemMatch返回null。如果是这样,我将不得不在连接表中运行另一个查询,查找这些注释并检查(查询)当前用户是否喜欢它们。

有更好的选择吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

好吧,加入集合并不是真正的noSQL思维方式;-) 我不知道ParseServer,所以下面只是基于纯MongoDB。

我要做的是,在评论文档中为每个喜欢评论的用户使用一个ObjectId数组。

示例文档布局

Credential credential = new Credential(BearerToken.authorizationHeaderAccessMethod()).setAccessToken(accessToken);
JsonArray members = new JsonArray();
JsonPrimitive element = new JsonPrimitive("String value is shown here");
members.add(element);

JsonObject closeGroupchat = new JsonObject();
closeGroupchat.addProperty("propertie", false);
closeGroupchat.add("members", members);
Gson gson = new Gson();
HttpContent hc = new ByteArrayContent("application/json", gson.toJson(closeGroupchat).getBytes());

HttpRequestFactory requestFactory = httpTransport.createRequestFactory(credential);
HttpRequest httpreq = requestFactory.buildRequest(HttpMethods.DELETE, genericUrl, hc);
return httpreq.execute();

然后使用聚合来获取数据。我认为你有评论的_id,你知道用户的_id。

以下聚合返回带有like count和boolean的注释,表示用户喜欢该注释。

{ 
    "_id" : ObjectId(""), 
    "name" : "Comment X", 
    "liked" : [
        ObjectId(""), 
        ....
    ]
}

返回

db.Comment.aggregate(

    [
        {
            $match: {
            _id : ObjectId("your commentId")
            }
        },
        {
            $project: {
                _id : 1,
                name :1,
                number_of_likes : {$size : "$liked"},
                user_liked: {
                            $gt: [{
                                $size: {
                                    $filter: {
                                        input: "$liked",
                                        as: "like",
                                        cond: {
                                            $eq: ["$$like", ObjectId("your userId")]
                                        }
                                    }
                                }
                            }, 0]
                        },
            }
        },
    ]
);

}

希望这是你的追求。

答案 1 :(得分:2)

我建议再次直接访问MongoDB,除非你绝对不得不这样做;毕竟,集合和关系的构建方式是Parse的一个实现细节,理论上可能在将来发生变化,破坏你的代码。

即使您想避免多次查询,我建议您这样做(根据您的平台,您甚至可以并行运行两个Parse查询):

  1. 第一个是Comment上的查询,用于获取您要显示的所有评论;假设您有某种Post可以写入注释,查询将查找引用当前帖子的所有注释。
  2. 第二个查询再次针对Comment,但这一次
    • 约束于第一个查询中检索到的评论,例如:containedIn("objectID", arrayOfCommentIDs)
    • 并限制为当前用户处于likers关系的评论,例如:equalTo("likers", currentUser)