【发布时间】:2020-09-07 05:22:02
【问题描述】:
我正在开发一个带有 Node.JS / MongoDB 后端的 MERN 堆栈 Web 应用程序。
我正在构建一个聊天收件箱,用于显示用户最近的对话,并预览该对话中的最新消息。
我正在尝试创建一个 MongoDB 聚合,以查找 12 个最近的“对话”并返回该对话中的最新聊天并附加关联的用户。
管道涉及两个数据库集合:
- 用户集合(每个用户的文档)
- 聊天集合(发送的每条消息的文档)
聚合管道的目标是返回最近的聊天(发送或接收)并附加来自用户集合的关联用户
聊天模式的结构如下:
{
sender: (User Document ID of the sender),
receiver: (User Document ID of the receiver),
timestamp: (Date Message Was Sent)
}
这是我迄今为止构建的管道。注意:userid 变量是请求用户的 ObjectID。
var findUserMessages = await Chat.aggregate([
{
$match: {
receiver: userid,
},
},
{ $sort: { createdAt: -1 } },
{
$group: {
_id: "$sender",
createdAt: { $first: "$createdAt" },
isRead: { $first: "$isRead" },
chat_id: { $first: "$_id" },
message: { $first: "$message" },
},
},
{
$project: {
_id: "$chat_id",
createdAt: "$createdAt",
isRead: "$isRead",
senderId: "$_id",
message: 1,
},
},
{
$lookup: {
from: "users",
localField: "senderId",
foreignField: "_id",
as: "user",
},
},
{ $unwind: "$user" },
{ $sort: { createdAt: -1 } },
{ $skip: skip },
{ $limit: 12 },
]);
问题是这个聚合返回用户 ID 是接收者的最新消息。我需要它返回用户是发送者或接收者的最新消息。
我在比赛阶段试过这个:
$match: {
$or: [{ sender: userid }, { receiver: userid }],
},
但是在小组赛阶段,我相信我现在需要根据用户是发送者还是接收者来确定 ID。如果用户是发送者,则组 ID 应该是接收者,反之亦然。
{
$group: {
_id: "$sender",
createdAt: { $first: "$createdAt" },
isRead: { $first: "$isRead" },
chat_id: { $first: "$_id" },
message: { $first: "$message" },
},
},
这就是我卡住的地方。我尝试聘请了几位代码导师,但没有人能够解决这个问题。
目标:应该从每个对话中返回最近的聊天(数量:1),按最近的排序,并附有相关的用户
- 第一步:查找用户是发件人或收件人的所有聊天记录
- 第二步:按最近排序
- 第三步:按对话分组
- 第四步:通过对话获取最近的聊天记录
- 第五步:找到关联的其他用户并放松
【问题讨论】:
-
你的问题太大了。如果你能把它分成几个问题,那就更好了。
-
我建议您应该单独存储必要的数据以帮助查询。如果您的用例是聊天应用程序。您可能有太多的数据和流量来进行如此复杂的聚合
-
我在您的聚合中看到您使用了架构中不存在的其他字段,请同时将它们包含在架构中以供参考。
标签: node.js reactjs mongodb aggregation-framework