通过查看所有 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' }
} }
])
结构如下:
- 获取 'userid'
用户的所有帖子
- 加入 table 与 'Reply'
- 对所有 reply.likes
求和
(您可能需要输入 $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?
我目前正在使用 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' }
} }
])
结构如下:
- 获取 'userid' 用户的所有帖子
- 加入 table 与 'Reply'
- 对所有 reply.likes 求和
(您可能需要输入 $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?