let cart = req.body.params.cart // array of objects that needs to be updated if exists in db, if not upsert it.
let userid = req.body.params.uid
for (let i = 0; i < cart.length; i++) {
Cart.updateOne({ user: userid, 'cart.product': cart[i].product._id },
{
$set: {
'cart.$.quantity': cart[i].quantity
}
},
{ upsert: true }// works without this line of code, updates the objects if exists
)
}
我的购物车型号:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const CartSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: 'users'
},
cart: [{
product: {
type: Schema.Types.ObjectId,
ref: 'productlist'
},
quantity: {
type: Number
},
date: {
type: Date,
default: Date.now
}
}]
})
module.exports = Cart = mongoose.model('cart', CartSchema)
我正在尝试使用购物车数组中的新商品更新用户的购物车。我需要检查产品是否存在,如果是,则更新数量,如果没有,则将其推入用户的购物车。不知何故,它与$ upsert不兼容。如果用户购物车中存在对象ID,则没有$ upsert文档的文档将被更新。
工作版本充满混乱。我觉得有一种更好的方法可以像我上面试图做的那样。我会尽量提供帮助,以减少混乱。
Cart.find({ user: req.body.params.uid })
.then(userCart => {
if (userCart[0].cart.length === 0) {
for (let i = 0; i < cart.length; i++) {
Cart.updateOne({ user: req.body.params.uid }, {
$push: {
cart: {
product: cart[i].product._id,
quantity: cart[i].quantity
}
}
}).catch(err => console.log(err))
}
}
else {
cart.reduce((acc, element) => {
let index = userCart[0].cart.findIndex(val => val.product._id == element.product._id)
if (index !== -1) {
Cart.findOneAndUpdate({ user: req.body.params.uid, 'cart.product': element.product._id },
{
$set: {
'cart.$.quantity': element.quantity
}
},
{ new: true }
).then(a => console.log(a))
}
else {
Cart.updateOne({ user: req.body.params.uid }, {
$push: {
cart: {
product: element.product._id,
quantity: element.quantity
}
}
}).catch(err => console.log(err))
}
acc.push(element)
return acc
}, [])
}
})
阵列购物车中的样本值
product: {
_id: '5eaf8eeac436dbc9b7d75f35',
name: 'Strawberry',
category: 'organic',
image: '/productImages/australian.jpg',
price: '9.65'
},
quantity: 6
db中的示例购物车:
_id: 5ec12ea36ccf646ff5aeef0c,
user: 5ec11a8f69ccf46e0e19c5ef,
cart: [
{
date: 2020-05-18T10:26:38.751Z,
_id: 5ec262de5829f081b1ea96d7,
product: 5eaf8eeac436dbc9b7d75f35,
quantity: 8
},
{
date: 2020-05-18T12:11:57.168Z,
_id: 5ec27b8dd2949886308bebd6,
product: 5eaf8f61c436dbc9b7d75f36,
quantity: 6
}
]
答案 0 :(得分:0)
我认为最好的解决方案是先在node.js代码中匹配旧购物车和新购物车,然后对其进行更新,以下是步骤和代码。
现在,您有两个单独的数组,仅在2个查询中即可轻松更新它们,而无需在代码中使用循环或多个查询。我还尝试在代码注释中对此进行解释。
// First get all the new cart productid and quantity in an array
var cartArray = cart.map(obj => {
return {product: obj.product._id, quantity: obj.quantity}
})
Cart.findOne({ user: req.body.params.uid })
.then(userCart => {
var productIds = userCart.cart.map(obj => obj.product)
// array of products id and quantity which are already there in old cart
var productsOld = cartArray.filter(obj => {
return productIds.includes(obj.product)
})
// array of products id and quantity which are not there in old cart
var productsNew = cartArray.filter(obj => {
return !productIds.includes(obj.product)
})
//First, we will add the all new products which are in the new cart
Cart.findOneAndUpdate({ user: req.body.params.uid }, {
$push: {
cart: {
$each: productsNew
}
}
}, {
new: true
}).then(function(updatedUserCart){
// Here we are getting now the updated cart with new products added
// Now we need to update quantity of old products
// Instead of running query in loop, we will update the quantity in array map
// and replace the whole cart in the document
var newCart = updatedUserCart.cart.map(obj => {
var matchProduct = productsOld.filter(oldObj => {
return oldObj.product == obj.product
})
if (matchProduct.length > 0) {
obj.quantity = parseInt(obj.quantity) + parseInt(matchProduct[0].quantity)
return obj
} else {
return obj
}
})
Cart.updateOne({ user: req.body.params.uid }, {
$set: {
cart: newCart
}
})
}).catch(err => console.log(err))
})
免责声明:我没有尝试在系统上运行代码,因此可能存在拼写错误或语法错误,但是希望您能理解流程和逻辑