Mongodb:我们什么时候需要到期购物车?

时间:2017-04-10 14:37:23

标签: mongodb express shopping-cart

我正在通过ExpressJs + Mongodb建立一个电子商务网站,我一直坚持这个问题: 我们什么时候需要使购物车过期(取出购物车并将产品退回库存)?每当用户访问购物车?还是我需要一份cron工作?

我已经关注了这篇文章:https://www.infoq.com/articles/data-model-mongodb

这是我的购物车模型的实施:

'use strict';

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const CartItem = new Schema({
    product: { type: Schema.Types.ObjectId, ref: 'Product' },
    quantity: Number
});

const Cart = new Schema({
    userSessionId: String,
    status: {
        type: String,
        enum: [ 'active', 'completed', 'expiring', 'expired' ],
        default: 'active'
    },
    items: [ CartItem ],
    modifiedOn: { type: Date }
});

Cart.static({
    summary: function(params, cb) {
        this.aggregate([
            {
                $match: { userSessionId: params.userSessionId }
            },
            {
                $unwind: {
                    path: '$items'
                }
            },
            {
                $lookup: {
                    from: 'products',
                    localField: 'items.product',
                    foreignField: '_id',
                    as: 'product'
                }
            },
            {
                $unwind: {
                    path: '$product',
                    preserveNullAndEmptyArrays: true
                }
            },
            {
                $group: {
                    _id: { userSessionId: '$userSessionId' },
                    count: { $sum: '$items.quantity' },
                    total: { $sum: { $multiply: [ '$product.price', '$items.quantity' ] } }
                }
            }
        ], (err, results) => cb(err, results[0]));
    },
    addProduct: function(params, cb, test) {
        var d = new Date();

        if (test) {
            d.setMinutes(d.getMinutes() - 10);
        }

        this.findOneAndUpdate(
            { userSessionId: params.userSessionId },
            { $set: { modifiedOn: d } },
            { upsert: true, new: true }, (err, cart) => {
                if (err) {
                    return cb(err);
                }

                const index = cart.items.findIndex((item) => {
                    return item.product.equals(params.productId);
                });

                if (index === -1) {
                    cart.items.push({
                        product: params.productId,
                        quantity: params.quantity
                    });
                } else {
                    cart.items[index].quantity += parseFloat(params.quantity);
                }
                cart.save(cb);
            });
    },
    updateQuantity: function(params, cb) {
        this.findOneAndUpdate(
            { userSessionId: params.userSessionId },
            {},
            { upsert: true, new: true }, (err, cart) => {
                if (err) {
                    return cb(err);
                }

                const index = cart.items.findIndex((item) => {
                    return item.product.equals(params.productId);
                });

                if (index === -1) {
                    return cb(new Error('Can not find product in cart'));
                }
                cart.items[index].quantity = params.quantity;

                cart.save(cb);
            });
    },
    findItem: function(params, cb) {
        this.findOne({ userSessionId: params.userSessionId }).exec((err, cart) => {
            if (err) {
                return cb(err);
            }

            const index = cart.items.findIndex((item) => {
                return item.product.equals(params.productId);
            });

            if (index === -1) {
                return cb(new Error('Can not find product in cart'));
            }

            cb(null, cart.items[index]);
        });
    },
    removeProduct: function(params, cb) {
        this.update(
            { userSessionId: params.userSessionId },
            {
                $pull: { items: { product: params.productId } },
                $set: { modifiedOn: new Date() }
            },
            cb
        );
    },
    getExpiredCarts: function(params, cb) {
        var now = new Date();

        if (typeof params.timeout !== 'number') {
            return cb(new Error('timeout should be a number!'));
        }

        now.setMinutes(now.getMinutes() - params.timeout);

        this.find(
            { modifiedOn: { $lte: now }, status: 'active' }
        ).exec(cb);
    }
});

mongoose.model('Cart', Cart);

1 个答案:

答案 0 :(得分:1)

您应该使用某种分布式会话来存储购物车!

我认为您正在寻找类似:https://www.youtube.com/watch?v=g32awc4HrLA

的内容

它使用expressjs-sessionmongodb然后你有一个分布式缓存,它可以与你的应用程序的多个实例一起使用。