我尝试执行以下操作,从特定用户的chat
集合中获取聊天列表,并将message
集合中发送的最后一条消息添加到每个聊天的列表中。
现在,我有两种方法,如下所述
第一种方法使用聊天成员ID获取聊天列表,第二种方法使用聚合查找每个聊天的最后一条消息,然后将消息与聊天的ID进行匹配
收藏聊天:
type Chat struct {
ID string `json:"id" bson:"id"`
Participants []string `json:"participants" bson:"participants"`
LastMessage *Message `json:"last_message,omitempty" bson:"last_message"`
...
}
P.S. LastMessage
-始终为空,我只需要它来为用户编写响应。
采集message
:
type Message struct {
ID string `json:"id" bson:"id"`
ChatID string `json:"chat_id" bson:"chat_id"`
FromID string `json:"from_id" bson:"from_id"`
CreateDate int64 `json:"create_date" bson:"create_date"`
Body string `json:"body" bson:"body"`
UpdateAt int64 `json:"update_at" bson:"update_at"`
...
}
- 第一种方法:**我需要使用此方法来获取特定聊天参与者的活动聊天列表。
func ActiveChats(ctx context.Context, uid string) ([]*Chat, error) {
...
filter := bson.D{primitive.E{Key: "participants", Value: uid}}
cursor, err := r.col.Find(ctx, filter, nil)
if err != nil {...}
var ch []*chat
if err = cursor.All(ctx, &ch); err != nil {...}
if err = cursor.Close(ctx); err != nil {...}
...
}
- 第二种方法**:我需要这个方法来获取每次聊天的最后一条消息,输入是一个聊天ID数组,对于每个聊天ID,我搜索最后一条消息(如果有的话)。
func LastMessages(ctx context.Context, chatIds []string) (map[string]*Message, error) {
matchStage := bson.D{
primitive.E{
Key: "$match", Value: bson.D{
primitive.E{
Key: "chat_id", Value: bson.D{
primitive.E{Key: "$in", Value: chatIds},
},
},
},
}}
sortStage := bson.D{primitive.E{Key: "$sort", Value: bson.D{primitive.E{Key: "created", Value: -1}}}}
groupStage := bson.D{primitive.E{
Key: "$group", Value: bson.D{
primitive.E{
Key: "_id", Value: bson.D{
primitive.E{Key: "chat_id", Value: "$chat_id"},
},
},
primitive.E{
Key: "message", Value: bson.D{
primitive.E{Key: "$first", Value: "$$ROOT"},
},
},
},
}}
cursor, err := r.colMessage.Aggregate(ctx, mongo.Pipeline{matchStage, groupStage, sortStage})
if err != nil {...}
var res []*aggregationResultGenerated
if err = cursor.All(ctx, &res); err != nil {...}
...
}
我知道这是一个非常糟糕的解决方案,但这是我目前所能想到的,非常遗憾(不起作用)。
db.chat.aggregate([
{
$match: {
participants: "participant_id",
},
{
$lookup: {
from: "message", // other table name
localField: "id", // name of chat table field
foreignField: "chat_id", // name of message table field
as: "msg",
}
},
{
$unwind: "$msg",
},
{
$match: {
chat_id : {
$in: ["$$ROOT._id"],
},
},
},
{
$sort: {
"created": -1,
},
},
{
$group: {
"_id": {
"chat_id": "$chat_id"
},
"doc": {
"$last": "$$ROOT"
}
}
},
{
$project: {
last_message: "$msg",
}
}
])
我的问题是:如何使用聚合来获取特定用户的聊天列表,并为每个聊天从集合message
中添加对象chat
的last_message字段中的最后一条消息?
{
"chats": [
{
"id": "4hWsHam3ZZpoyIw44q3D",
"title": "Chat example",
"create-date": 1674476855918,
"participants": [
"63ce54460aeee5e72c778d90",
"63ce54460aeee5e72c778d92"
],
"owner_id": "63ce54460aeee5e72c778d90",
"last_message": {
"id": "tzwekCiCLSXJ4tfdQuHH",
"chat_id": "4hWsHam3ZZpoyIw44q3D",
"from_id": "63ce54460aeee5e72c778d92",
"create_date": 1674557062031,
"body": "text",
"update_at": 0,
"viewed": false
},
"unread": 5
},
{
"id": "Anjrr9RCWFzq030Cwz7S",
"title": "New chat One",
"create-date": 1674476909054,
"participants": [
"63ce54460aeee5e72c778d90",
"63ce54460aeee5e72c778d96"
],
"owner_id": "63ce54460aeee5e72c778d90",
"last_message": {
"id": "7YqhhS1-EfMRSZtGCH0Z",
"chat_id": "Anjrr9RCWFzq030Cwz7S",
"from_id": "63ce54460aeee5e72c778d96",
"create_date": 1674575017115,
"body": "text",
"update_at": 0,
},
"unread": 1
},
]
}
1条答案
按热度按时间oymdgrw71#
您可以简单地在
$lookup
的子管道中执行$sort
+$limit
方法。执行$unwind
以将查找结果转换到last_message
字段。最后,执行$merge
以更新回chat
集合。Mongo Playground