我有一个MostRecentMessage
模型,定义为
const MostRecentMessage = new Schema({
to: {
type: mongoose.Schema.Types.ObjectId,ref: "user"
},from: {
type: mongoose.Schema.Types.ObjectId,conversation: {
type: mongoose.Schema.Types.ObjectId,ref: "conversation"
},date: {
type: Date,default: Date.now
}
});
每当用户A向用户B发送消息时,都会创建一个文档(如果该文档不存在)。每次用户A向用户B发送消息时,都会使用新的conversation
和date
更新此文档。文件的示例是
_id: ObjectId(5dc46521cf670a0017d2434d)
to: ObjectId(5dc464ce2fd75700178c1ad4) // User B
from: ObjectId(5dc464fc2fd75700178c1ad5) // User A
conversation: ObjectId(5dc465c6cf670a0017d24363)
date: 2019-11-07T18:40:33.242+00:00
__v: 0
想法是,这将有助于跟踪所有最近发给特定用户的消息。
同样,用户B可以向用户A发送消息。与上面类似,将创建一个新文档,
_id: ObjectId(5dc46521cf670a0017d2434d)
to: ObjectId(5dc464fc2fd75700178c1ad5) // User A
from: ObjectId(5dc464ce2fd75700178c1ad4) // User B
conversation: ObjectId(5dc465c6cf670a0017d24363)
date: 2019-11-07T18:40:33.242+00:00
__v: 0
此文档将随着用户B发送给用户A的每条新消息而更新。
现在,下面是我的聚合查询..但问题是它只返回一个对话。可能有10个用户与用户A交谈,但仍只返回一个文档。
const { id } = req.user;
try {
await MostRecentMessages.aggregate(
[
{
$match: {
$or: [
{ from: mongoose.Types.ObjectId(id) },{ to: mongoose.Types.ObjectId(id) }
]
}
},{ $project: { _id: 1,from: 1,to: 1,conversation: 1,date: 1 } },{ $sort: { date: -1 } },{
$group: {
_id: null,from: { $first: "$from" },to: { $first: "$to" },date: { $first: "$date" },conversation: { $first: "$conversation" }
}
},{
$lookup: {
from: "conversations",localField: "conversation",foreignField: "_id",as: "conversation"
}
},{ $unwind: { path: "$conversation" } },{
$lookup: {
from: "users",localField: "to",as: "to"
}
},{ $unwind: { path: "$to" } },localField: "from",as: "from"
}
},{ $unwind: { path: "$from" } }
],function(err,docs) {
if (err) {
console.log(err);
} else {
return res.json(docs);
}
}
);
} catch (err) {
console.log(err);
return res.status(500).send("Server error");
}
我在这里做什么错了?
编辑:我现在所拥有的:
使用此代码,如果
User A messages User B,'Test1'
User B messages User A,'Test2'
User A messages User B,'Test3'
然后,两个用户都只会显示Test2
消息。如何让“ Test3”同时显示给两个用户?
await MostRecentMessages.aggregate(
[
{
$match: {
$or: [
{ from: mongoose.Types.ObjectId(id) },{ to: mongoose.Types.ObjectId(id) }
]
// deletedBy: { $ne: id }
}
},{
$group: {
_id: {
userConcerned: {
$cond: {
if: {
$eq: ["$to",mongoose.Types.ObjectId(id)]
},then: "$to",else: "$from"
}
},interlocutor: {
$cond: {
if: {
$eq: ["$to",then: "$from",else: "$to"
}
}
},docs) {
if (err) {
console.log(err);
} else {
return res.json(docs);
}
}