我有 2 個收藏。
Collection Name: chats
Chat {
_id : Object(Id)
mssg : string
room : Object Ref (room _id)
creationDate: DateTimeStamp
}
Collection Name: rooms
Room {
_id : Object(Id)
chatMssgs: [Object Ref (Chat_id_1), Object Ref (Chat_id_2), Object Ref (Chat_id_x)]
roomName: string
creationDate: DateTimeStamp
}
我正在嘗試使用貓鼬聚合管道按最新聊天訊息的順序對房間進行排序。為此,我正在執行以下操作:
- 按最新聊天訊息排序(使用創建日期)
- 使用 Lookup 獲取聊天訊息的參考房間
- 展開結果的房間陣列
- 使用 replaceRoot 將房間陣列結果作為陣列中的主要物件。
- 回傳唯一的房間串列,而不會丟失最新聊天訊息日期的排序。
到目前為止,以下代碼一直有效到第 4 點。
await Chat.aggregate([
{$sort: {creationDate: -1}},
{$lookup: {
from: "rooms",
localField: "room",
foreignField: "_id",
as: "chat_room"
}
},
{$unwind: "$chat_room"},
{$replaceRoot: {newRoot: "$chat_room"}},
])
這就是我迷路的地方。如果我保持當前聚合代碼不變,它可以作業,但我的房間 ID 有重復。這是因為一個房間可以有多個聊天訊息。如果我在 replaceRoot 之后使用 $group,我的排序就會消失,并且最新聊天訊息的順序也會丟失。
理想情況下,我正在嘗試按最后的聊天訊息對房間進行排序。我使用聚合是因為我還需要使用 addField 對房間后記執行一些計數,并且我為此查詢使用分頁,因此需要偏移和限制以保持查詢相對較快。
按降序回傳包含最新聊天訊息的房間的最佳方式是什么?所以房間 1 將有最新的 mssg,房間 2,... 等直到房間 x 顯示最早發布的 mssg。
更新:在第一次回復中嘗試了建議的解決方案后,我得到:
[
{
"_id": 3,
"creationDate": ISODate("2014-01-03T08:00:00Z"),
"mssg": "ghi",
"room": 2
},
{
"_id": 2,
"creationDate": ISODate("2014-01-02T08:00:00Z"),
"mssg": "def",
"room": 1
}
]
這也是我在使用方法時遇到的問題。如何讓輸出看起來像這樣?
[
{
"_id": 2,
"roomName": "room 2"
"creationDate": ISODate("2014-01-01T08:00:00Z"),
"chatMssgs": [3 ],
},
{
"_id": 1,
"roomName": "room 1"
"creationDate": ISODate("2014-01-01T08:00:00Z"),
"chatMssgs": [1,2 ],
}
]
uj5u.com熱心網友回復:
找到最大日期,然后過濾它。
db.chats.aggregate([
{
"$match": {
_id: {
"$in": [
1,
2,
3
]
}
}
},
{
"$group": {
"_id": "$room",
"latestMsgDate": {
"$max": "$creationDate"
},
"Msg": {
$push: "$$ROOT"
}
}
},
{
"$set": {
"Msg": {
"$filter": {
"input": "$Msg",
"as": "m",
"cond": {
"$eq": [
"$$m.creationDate",
"$latestMsgDate"
]
}
}
}
}
},
{
"$replaceRoot": {
"newRoot": {
"$first": "$Msg"
}
}
},
{
"$sort": {
creationDate: -1
}
}
])
mongoplayground
uj5u.com熱心網友回復:
行。感謝玉婷的回答,我能夠得到我想要的東西(請參閱有問題的更新部分)。對于任何有興趣的人:
db.chats.aggregate([
{$lookup: {
from: "rooms",
localField: "room",
foreignField: "_id",
as: "chat_room",
},
},
{ $group: {
_id: "$chat_room",
latestMsgDate: { $max: "$creationDate" },
},
},
{$sort: { latestMsgDate: -1 }},
{$unwind: "$_id"},
{$replaceRoot: { newRoot: "$_id" }}
])
您可以在mongoplayground中進行測驗。輸出是:
[
{
"_id": 2,
"chatMssgs": [
3
],
"creationDate": ISODate("2014-01-01T08:00:00Z"),
"roomName": "room 2"
},
{
"_id": 1,
"chatMssgs": [
1,
2
],
"creationDate": ISODate("2014-01-01T08:00:00Z"),
"roomName": "room 1"
}
]
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/417235.html
標籤:
