【发布时间】:2021-05-30 05:36:41
【问题描述】:
我正在构建一个基于 MERN 堆栈的聊天应用程序,需要获取特定用户的所有聊天记录。
这是我的聊天消息架构:
const message = mongoose.Schema({
from: {
type: Schema.Types.ObjectId,
ref: "users",
required: true,
},
to: {
type: Schema.Types.ObjectId,
ref: "users",
required: true,
},
text: { type: String, required: false },
imgLink: { type: String, required: false },
sentAt: { type: Date, required: true },
deliveredAt: { type: Date, required: false },
readAt: { type: Date, required: false },
});
有没有办法获取用户的所有聊天记录并按发送/接收这些聊天记录的人分组。
我使用了这个聚合管道
const fetchChatPipeline = (_id) => {
return [
{
$match: {
$or: [
{
to: mongoose.Types.ObjectId(_id),
},
{
from: mongoose.Types.ObjectId(_id),
},
],
},
},
{
$sort: {
sentAt: 1,
},
},
{
$group: {
_id: "$from",
from: { $first: "$from" },
to: { $first: "$to" },
messages: {
$push: {
text: "$text",
imgLink: "$imgLink",
sentAt: "$sentAt",
deliveredAt: "$deliveredAt",
readAt: "$readAt",
},
},
},
},
{
$lookup: {
from: "users",
localField: "from",
foreignField: "_id",
as: "from",
},
},
{
$unwind: {
path: "$from",
preserveNullAndEmptyArrays: false,
},
},
{
$lookup: {
from: "users",
localField: "to",
foreignField: "_id",
as: "to",
},
},
{
$unwind: {
path: "$to",
preserveNullAndEmptyArrays: false,
},
},
{
$project: {
to: {
_id: 1,
name: 1,
},
from: {
_id: 1,
name: 1,
},
messages: 1,
},
},
];
};
得到如下结果:
{
"chats": [
{
"_id": "60368ee8a4e8494c74ccbeec",
"from": {
"_id": "60368ee8a4e8494c74ccbeec",
"name": "Jaivardhan Singh"
},
"to": {
"_id": "603a637ab356a309dcca9099",
"name": "Jai Singh "
},
"messages": [
{
"text": "hello",
"sentAt": "2021-02-27T16:33:40.335Z"
},
{
"text": "What you upto",
"sentAt": "2021-02-27T16:34:16.852Z"
}
]
},
{
"_id": "603a637ab356a309dcca9099",
"from": {
"_id": "603a637ab356a309dcca9099",
"name": "Jai Singh "
},
"to": {
"_id": "60368ee8a4e8494c74ccbeec",
"name": "Jaivardhan Singh"
},
"messages": [
{
"text": "Hi",
"sentAt": "2021-02-27T16:35:32.343Z"
},
{
"text": "Nothing just chilling",
"sentAt": "2021-02-27T16:35:41.720Z"
},
{
"text": "What you upto",
"sentAt": "2021-02-27T16:35:49.662Z"
}
]
}
]
}
有没有办法可以将这两个聊天合并到结果中,因为它们有共同的参与者。谢谢。
【问题讨论】:
-
只需
$groupbynull,因为您已经在$match阶段过滤了用户:像这样:docs.mongodb.com/manual/reference/operator/aggregation/group/… -
但这样做会将所有消息合并在一起,即使聊天中的参与者不同。在上面的示例中,只有 2 人之间的聊天,但如果我们添加第三人,他的聊天也会合并
-
但是
$matchstage 会过滤所有第三人称。$match将只包括发送者(来自)和接收者(到)对吧? -
如您所见,匹配过滤器中有一个 $or,因此它返回所有由 _id 发送或由 _id 接收的聊天。因此,如果具有 _id 的用户与第三人聊天,他的结果也将包含在分组中
-
好的。如果有帮助,请检查更新的答案。
标签: node.js mongodb mongoose aggregation