解析服务器,MongoDB - 获取对象的 "liked" 状态

Parse Server, MongoDB - get "liked" state of an object

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

假设我有集合 UserComment 以及用户和评论的连接 table。 用户可以点赞评论,这会在连接 table.

中创建一条新记录

特别是在 Parse Server 中,可以使用集合中的 'relation' 字段定义连接 table。

现在当我想检索所有评论时,我还需要知道当前用户是否喜欢每条评论。在不进行额外查询的情况下,我该怎么做?

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

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

我可以在 Comment 中创建一个数组字段 someLikers、一个关系(连接 table)字段 allLikers 和一个数字字段 likesCount table。然后在 someLikersallLikers 中放置前 100 个喜欢者,仅在 allLikers 中放置额外的喜欢者。我总是会增加 likesCount.

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

还有更好的选择吗?

谢谢!

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

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

文档布局示例

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

然后使用聚合来获取数据。我假设你有评论的 _id 并且你知道用户的 _id。

以下聚合 returns 带有喜欢计数和表示用户喜欢该评论的布尔值的评论。

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

这个returns

{ 
"_id" : ObjectId(""), 
"name" : "Comment X", 
"number_of_likes" : NumberInt(7), 
"user_liked" : true

}

希望这就是你想要的。

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

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

  1. 第一个是Comment上的查询,用于获取要显示的所有评论;假设你有某种可以写评论的 Post,查询会找到所有引用当前 post.
  2. 的评论
  3. 第二个查询再次针对 Comment,但是这次
    • 仅限于第一个查询中检索到的评论,例如:containedIn("objectID", arrayOfCommentIDs)
    • 并限制为当前用户在其 likers 关系中的评论,例如:equalTo("likers", currentUser)