我想從 NodeJS 和 MongoDB 的不同集合中檢索用戶與相應用戶的聊天。
NodeJS 的本質給我一種不好的感覺,即運行以下代碼會阻塞或降低我的應用程式的性能。我可以復制一些資料,但我想了解更多關于 NodeJS 的資訊。
請讓我知道我的代碼是否正常并且不會降低性能。
在這里,我獲取 20 個聊天記錄。我也需要他們對應的用戶。然后我得到并對該集合userIds執行另一個查詢。User現在我兩者都有,但我應該使用Array.map.
我不使用$lookup,因為我的收藏是分片的。
$查找
對同一資料庫中的未分片集合執行左外連接,以過濾來自“已連接”集合的檔案以進行處理。對于每個輸入檔案,$lookup 階段添加一個新的陣列欄位,其元素是“加入”集合中的匹配檔案。$lookup 階段將這些重新調整的檔案傳遞到下一個階段。 https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/#mongodb-pipeline-pipe.-lookup
let chats = await Chat.find({ active: true }).limit(20);
/*
[
{_id: ..., userId: 1, title: 'Chat A'},
...
]
*/
const userIds = chats.map(item => item.userId);
/*
[1, ...]
*/
const users = await User.find({ _id: { $in: userIds }});
/*
[
{_id: 1, fullName: 'Jack'},
...
]
*/
chats = chats.map(item => {
item.user = users.find(user => user._id === item.userId);
return item;
});
/*
[
{
_id: ...,
userId: 1,
user: {_id: 1, fullName: 'Jack'}, // <-------- added
title: 'Chat A'
},
...
]
*/
uj5u.com熱心網友回復:
這不是你應該這樣做的。MongoDB 有一個叫做聚合框架和$lookup 管道的東西,只需 1 個 MongoDB 查詢就可以自動為您完成。
但是由于您使用的是 Mongoose,因此此查詢變得更加簡單,因為您可以使用populate()Mongoose 的方法。所以你的整個代碼可以用這樣的一行替換:
const chats = await Chat.find({ active: true }).populate('userId;).limit(20);
console.log(chats)
注意:如果你的集合是分片的,在我看來你已經以最好的方式實作了邏輯。
uj5u.com熱心網友回復:
您正在使用 async/await,因此您的代碼將等待每次使用的回應await
// Wait to finish here
let chats = await Chat.find({ active: true }).limit(20);
/*
[
{_id: ..., userId: 1, title: 'Chat A'},
...
]
*/
// Wait to finish here too
const users = await User.find({ _id: { $in: userIds }});
/*
[
{_id: 1, fullName: 'Jack'},
...
]
*/
因此,如果您有太多資料并且您的集合中沒有任何索引,那么完成這些查詢將太長。在這種情況下,您應該使用 chat.userId = user._idref在您的收藏Chat中創建收藏User
然后,當您呼叫查詢聊天時,您可以填寫populate欄位userId,因此您不必映射const userIds = chats.map(item => item.userId);和chats = chats.map...
聊天模式示例
const { Schema, model } = require("mongoose");
const chatSchema = new Schema({
active: Boolean,
userId: {
type: "ObjectId",
ref: "User",
},
title: String,
message: String
// another property
});
const userSchema = new Schema({
username: String,
email: String
// another property
})
// query for chat
const chatModel = new model('chat', chatSchema)
let chats = await chatModel.find({ active: true }).populate('userId').limit(20);
/*
[
{
_id: ...,
userId: {_id: 1, fullName: 'Jack'}, // <-------- already have
title: 'Chat A'
},
...
]
*/
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/450018.html
標籤:javascript 节点.js mongodb 表示 猫鼬
