我正在尝试使用 React.js 和 Node.js/Express.js + MongoDB/Mongoose 制作一个聊天应用程序
我没有任何对话/聊天表,因为用户只有一个对话,所以我尝试通过聚合获取与每个用户相关的最新消息,唯一的问题是,它不返回最新消息它会针对每个请求返回一条随机记录。
这是我的消息架构
mongoose.Schema(
{
sender: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: "User",
},
receiver: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: "User",
},
text: {
type: String,
required: true,
},
},
)
我添加了 3 个名为 a、b、c 的用户进行测试
我添加了一些测试消息,如下所示:
[
{
_id: new ObjectId("6593533fcb45be67f96ad506"),
sender: new ObjectId("659010d3df83767d3ccf7ef8"),
receiver: new ObjectId("6591d954aeb1253a9a00111b"),
text: 'Message from a to b',
type: 'message',
isForwarding: false,
isEdited: false,
status: 'unread',
createdAt: 2024-01-02T00:05:19.734Z,
updatedAt: 2024-01-02T00:05:19.734Z,
__v: 0
},
{
_id: new ObjectId("6593533fcb45be67f96ad507"),
sender: new ObjectId("659010d3df83767d3ccf7ef8"),
receiver: new ObjectId("65934563c5cc0035755d1bcc"),
text: 'Message from a to c',
type: 'message',
isForwarding: false,
isEdited: false,
status: 'unread',
createdAt: 2024-01-02T00:05:19.734Z,
updatedAt: 2024-01-02T00:05:19.734Z,
__v: 0
},
{
_id: new ObjectId("6593533fcb45be67f96ad50a"),
sender: new ObjectId("6591d954aeb1253a9a00111b"),
receiver: new ObjectId("65934563c5cc0035755d1bcc"),
text: 'Message from b to c',
type: 'message',
isForwarding: false,
isEdited: false,
status: 'unread',
createdAt: 2024-01-02T00:05:19.735Z,
updatedAt: 2024-01-02T00:05:19.735Z,
__v: 0
},
{
_id: new ObjectId("6593533fcb45be67f96ad50b"),
sender: new ObjectId("65934563c5cc0035755d1bcc"),
receiver: new ObjectId("6591d954aeb1253a9a00111b"),
text: 'Message from c to b',
type: 'message',
isForwarding: false,
isEdited: false,
status: 'unread',
createdAt: 2024-01-02T00:05:19.736Z,
updatedAt: 2024-01-02T00:05:19.736Z,
__v: 0
},
{
_id: new ObjectId("6593533fcb45be67f96ad509"),
sender: new ObjectId("65934563c5cc0035755d1bcc"),
receiver: new ObjectId("659010d3df83767d3ccf7ef8"),
text: 'Message from c to a',
type: 'message',
isForwarding: false,
isEdited: false,
status: 'unread',
createdAt: 2024-01-02T00:05:19.735Z,
updatedAt: 2024-01-02T00:05:19.735Z,
__v: 0
},
{
_id: new ObjectId("6593533fcb45be67f96ad508"),
sender: new ObjectId("6591d954aeb1253a9a00111b"),
receiver: new ObjectId("659010d3df83767d3ccf7ef8"),
text: 'Message from b to a',
type: 'message',
isForwarding: false,
isEdited: false,
status: 'unread',
createdAt: 2024-01-02T00:05:19.735Z,
updatedAt: 2024-01-02T00:05:19.735Z,
__v: 0
},
{
_id: new ObjectId("659417678ea29bb72b66713e"),
sender: new ObjectId("659010d3df83767d3ccf7ef8"),
receiver: new ObjectId("6591d954aeb1253a9a00111b"),
text: 'Last message from a to b',
type: 'message',
isForwarding: false,
isEdited: false,
status: 'unread',
createdAt: 2024-01-02T14:02:15.773Z,
updatedAt: 2024-01-02T14:02:15.773Z,
__v: 0
},
{
_id: new ObjectId("659417678ea29bb72b66713f"),
sender: new ObjectId("659010d3df83767d3ccf7ef8"),
receiver: new ObjectId("65934563c5cc0035755d1bcc"),
text: 'Last message from a to c',
type: 'message',
isForwarding: false,
isEdited: false,
status: 'unread',
createdAt: 2024-01-02T14:02:15.773Z,
updatedAt: 2024-01-02T14:02:15.773Z,
__v: 0
}
]
这就是我尝试过的代码:
const Chats = await Message.aggregate([
{
$sort: {
createdAt: -1,
},
},
{
$project: {
receiver: 1,
sender: 1,
text: 1,
timeStamp: 1,
messageFrom: ["$sender", "$receiver"],
},
},
{
$unwind: "$messageFrom",
},
{
$sort: {
messageFrom: 1,
},
},
{
$group: {
_id: "$_id",
messageFrom: {
$push: "$messageFrom",
},
sender: {
$first: "$sender",
},
receiver: {
$first: "$receiver",
},
text: {
$first: "$text",
},
},
},
{
$group: {
_id: "$messageFrom",
sender: {
$first: "$sender",
},
receiver: {
$first: "$receiver",
},
text: {
$first: "$text",
},
},
},
])
每次我发出新请求时,它都会返回一些意想不到的随机内容。
这就是我想要的回报:
[
{
_id: new ObjectId("659417678ea29bb72b667144"),
sender: new ObjectId("659010d3df83767d3ccf7ef8"),
receiver: new ObjectId("6591d954aeb1253a9a00111b"),
text: 'Last message from a to b',
type: 'message',
isForwarding: false,
isEdited: false,
status: 'unread',
createdAt: 2024-01-02T14:02:15.975Z,
updatedAt: 2024-01-02T14:02:15.975Z,
__v: 0
},
{
_id: new ObjectId("659417678ea29bb72b66713f"),
sender: new ObjectId("659010d3df83767d3ccf7ef8"),
receiver: new ObjectId("65934563c5cc0035755d1bcc"),
text: 'Last message from a to c',
type: 'message',
isForwarding: false,
isEdited: false,
status: 'unread',
createdAt: 2024-01-02T14:02:15.773Z,
updatedAt: 2024-01-02T14:02:15.773Z,
__v: 0
}
]
也许这个:
db.collection.aggregate([
{
$group: {
_id: { sender: "$sender", receiver: "$receiver" },
messages: {
$top: {
sortBy: { createdAt: -1 },
output: "$$ROOT"
}
}
}
},
{ $replaceWith: "$messages" },
])
$top
是在 MongoDB 5.2 版本中引入的。如果您运行旧版本,请尝试以下操作:
db.collection.aggregate([
{ $sort: { createdAt: -1 } },
{
$group: {
_id: { sender: "$sender", receiver: "$receiver" },
messages: { $first: "$$ROOT" }
}
},
{ $replaceWith: "$messages" },
])