gpt4 book ai didi

javascript - Mongoose 数据流

转载 作者:可可西里 更新时间:2023-11-01 10:01:47 29 4
gpt4 key购买 nike

我构建了一个简单的 MERN 应用程序,用户可以在其中对电话号码进行评分。用户只需填写电话号码,选择评级(1 - 5 星评级)、城市和短文本。该应用程序具有带过滤和排序选项的搜索功能。这一切都足够好 ATM 但我认为当多个并发用户使用该网站时它可能会中断,因为我在提交评级(messageSchema)后更新了电话号码模型(mobileSchema) - 使用 Mongoose 中间件(post hooks)。

例如,我需要计算电话号码的评分数 (messagesCount)。为此,我使用了 Message.countDocuments({ mobile: mobile._id })。但是,我还需要更新电话号码的其他属性(mobileSchema - lastMessageDate、globalRating、averageRating),以便操作需要一些时间。我相信当 2 个用户同时提交评分时评分数量可能不正确 - 它会将评分数量 (messagesCount) 增加 1 而不是 2。

有更好的方法吗?是否可以在前一个 post hook 完成后触发 post hook?

示例代码:

const mobileSchema = new Schema({
number: { type: String, required: true },
plan: { type: String, required: true },
date: { type: Date, default: Date.now, required: true, index: 1 },
messagesCount: { type: Number, default: 0, index: 1 },
lastMessageDate: { type: Date, index: 1 },
// normal mean
globalRating: { type: Number, default: 0, index: 1 },
// weighted mean
averageRating: { type: Number, default: 0, index: 1 }
});

const messageSchema = new Schema({
comment: { type: String, required: true },
city: { type: Schema.Types.ObjectId, ref: 'City', required: true, index: 1 },
rating: { type: Number, required: true, index: 1 },
date: { type: Date, default: Date.now, required: true, index: 1 },
mobile: { type: Schema.Types.ObjectId, ref: 'Mobile', required: true },
user: { type: Schema.Types.ObjectId, ref: 'User', required: true }
});

messageSchema.post('save', function (message, next) {
const messageModel = this.constructor;
return updateMobile(messageModel, message, next, 1);
});

const updateMobile = (messageModel, message, next, addMessage) => {
const { _id } = message.mobile;
const cityId = message.city._id;
const lastMessageDate = message.date;
let mobile;
hooks.get(Mobile, { _id })
.then(mobileRes => {
mobile = mobileRes;
return Message.countDocuments({ mobile: mobile._id })
})
.then(messagesCount => {
if (messagesCount <= 0) {
const deleteMobile = Mobile.findOneAndDelete({ _id: mobile._id })
const deleteSeen = SeenMobile.findOneAndDelete({ mobile: mobile._id, user: message.user._id })
const cityMobile = updateCityMobile(messageModel, mobile, cityId)
Promise.all([deleteMobile, deleteSeen, cityMobile])
.then(() => {
return next();
})
.catch((err) => {
console.log(err);
return next();
})
}
else {
if (addMessage === -1) lastMessageDate = mobile.lastMessageDate;
const ratings = hooks.updateGlobalRating(mobile, messageModel)
.then(() => hooks.updateAverageRating(mobile, messageModel))
.then(() => {
return new Promise((resolve, reject) => {
mobile.set({
messagesCount,
lastMessageDate
});
mobile.save((err, mobile) => {
if (err) return reject(err);
resolve();
});
})
})
const cityMobile = updateCityMobile(messageModel, mobile, cityId)
Promise.all([ratings, cityMobile])
.then(([ratings, cityMobile]) => {
return next();
})
.catch(err => console.log(err))
}
})
.catch(err => {
console.log(err);
})
}

最佳答案

我认为您的方法总是会遇到异步问题。我不相信您可以“同步” Hook ;似乎与 MongoDB 的所有真实情况背道而驰。但是,在较高级别上,您可能会在运行时更成功地获取总计/摘要,而不是试图让它们始终保持同步。例如,如果您需要给定移动设备的消息总数,为什么不:

Messages.find({mobile: mobile._id})

然后统计结果?这将节省您存储摘要并保持更新的时间。但是,我也认为您当前的方法可行,但您可能需要废弃“countDocuments”。一些更异步友好的东西,比如:

Mobile.aggregation([
{ $match: { _id: mobile._id } },
{ $add: [ "$mobile.messagesCount", 1 ] }
]);

最终我认为,如果您将 Messages 存储为 Mobile 中的数组,那么您的设计会得到加强,因此您可以将消息推送到它上面。但要直接回答这个问题,聚合应该使一切保持整洁。

关于javascript - Mongoose 数据流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53508827/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com