首页 > 解决方案 > TTL从集合中删除文档后有什么方法可以回调?

问题描述

我的问题是“当用户下单时,邮件会发送到用户的邮箱,内容中有确认订单的链接。此时,订单中的产品数量会减少。24h后,如果用户未通过电子邮件链接确认,订单将被删除,产品数量将返回数据库。”

所以我需要一个回调函数来设置产品的数量吗?还有另一种设置过期的方法吗?

这是我的模型 order.js 代码:

const OrderSchema = new Schema({
    ...
    paid: {           
        type: Boolean,
        default: false
    },
    payment_method: {
        type: String,
        enum: ['local', 'paypal'],
        default: 'local'
    },
    status: {          
        type: Number,
        default: 0
    },
    confirmed: {        // After order, users must confirm order by email link
        type: Boolean,
        default: false,
        index: true
    }
}, {
    timestamps: true
})

const Order = mongoose.model('Order', OrderSchema)

// After 24h, if user doesn't confirm by email link, the order will be delete
 OrderSchema.index({
    createdAt: 1
},{
    expireAfterSeconds: 24*60*60,
    partialFilterExpression : {
        confirmed: false
    }
});

提前致谢。

标签: node.jsmongodbmongoose

解决方案


最后,我通过使用“cron”包找到了解决方案

npm install cron

这是我的控制器 order.js 代码:

const Order = require('../models/Order');
const Product = require('../models/Product');
const CronJob = require('cron').CronJob;
...
const addOrder = async (req, res, next) => {
    ...
    await order.save();

        // After 24h, if user doesn't confirm by email link
        const thisTime = new Date();
        var job = new CronJob(' * * * * *', async() => {
            // Expire time, then stop a job
            var expire = new Date();
            if(expire - thisTime >= 24*60*60*1000){
                await job.stop();
            }
            },async () => {
                const orderNow = await Order.findById(order._id);
                // Check if confirm = false, then delete this order
                if(!orderNow.confirmed){
                    await Order.findByIdAndDelete(order._id);
                    // Update the amount of products in this order
                    for (let item of orderNow.order_list){
                        let productFound = await Product.findById(item.product);
                        if(productFound){
                            productFound.colors.find(i => i._id.toString() === item.color.toString()).amount = productFound.colors.find(i => i._id.toString() === item.color.toString()).amount + item.quantity;
                            await productFound.save();
                        }
                    }
                }
            },
            true, /* Start the job right now */
            'Asia/Ho_Chi_Minh' /* Time zone of this job. */
        );

        return res.status(200).json({ success: true, code: 201, message: 'success', order });
    } catch (error) {
        next(error);
    }
};
...
module.exports = {
    addOrder
}

推荐阅读