通过查看所有 his/her 个帖子 MongoDB 获取用户收到的喜欢总数

Getting total number of likes that user received by going through all his/her posts MongoDB

我目前正在使用 MERN 堆栈创建一个简单的 SNS 应用程序。

然而,我在尝试提出一个查询时遇到了困难,该查询可以遍历用户 post 编辑的所有 post 并获得喜欢的总和。

目前我已经创建了 3 个架构。用户,Post,回复。

用户

  const userSchema = new Schema({
  
   facebookId: {
    required: true,
    type: String,
  },

  username: {
    required: true,
    type: String,
  },

  joined: Date
})

POST

const postSchema = new Schema({
  title: String,
  body: String,
  author: { type: Schema.Types.ObjectId, ref: "User" },
  datePosted: Date,
  reply: [{ type: Schema.Types.ObjectId, ref: 'Reply'}],
  tag: [ {type: String} ]

});

回复

 const replySchema = new Schema({
      title: String,
      body: String,
      author: { type: Schema.Types.ObjectId, ref: "User" },
      datePosted: Date,
      post: [{ type: Schema.Types.ObjectId, ref: 'Post'}],
      likes: [{ type: Schema.Types.ObjectId, ref: "User" }] // storing likes as array 
    });

如您所见,我在回复架构中添加了 likes 字段作为一个数组,该数组接受用户 ObjectId。 假设某个用户有 posted 4 个回复,每个回复分别收到 1 ,3, 4, 5 个赞。在排行榜部分,我想显示用户信息以及他们从所有回复中收到的总计数,即 1+3+4+5 = 13 个赞。

这是否可以在不添加额外字段的情况下实现,或者是否有更好的架构架构方法。

您可以使用模型聚合函数来执行此操作:

const userid = 1234

post.aggregate([
  { $match: { _id: userid } },
  { $lookup: {
    from: 'Reply',
    localField: 'reply',
    foreignField: '_id',
    as: 'replies'
  } },
  { $group: {
    _id: false,
    sumoflikes: { $sum: '$replies.likes' }
  } }
])

结构如下:

  1. 获取 'userid'
  2. 用户的所有帖子
  3. 加入 table 与 'Reply'
  4. 对所有 reply.likes
  5. 求和

(您可能需要输入 $unwind: '$replies between 2 and 3 there,我不是 100% 确定)

如果要公开显示此字段,那么我个人建议不要即时计算,而是预先计算并将其保存在用户身上,因为聚合数据非常昂贵,不应成为您应用程序的一部分逻辑,特别是如果需要为每个用户计算 leaderboard 功能。

这里说的是如何用 aggregation framework

计算它
db.replies.aggregate([
    {
        $match: {
            author: userid
        }
    },
    {
        $group: {
            _id: null,
            likes: {$sum: {$size: '$likes'}}
        }
    }
]);

正如我所说,我建议您离线执行此操作,运行 为每个用户执行一次并在用户上保存一个 likeCount 字段,然后您可以更新创建赞的其他路线使用 $inc.

更新用户点赞数
// .. new like created ...
db.users.updateOne({_id: liked_reply.author}, {$inc: {likeCount: 1}})

现在查找排行榜非常容易:

const leaders = await db.users.find({}).sort({likeCount: -1}).limit(10) //top 10?