背景:我正在开发一个显示库存管理分析的应用程序。 它会上传一个Office EXCEL文件,当文件上传时,应用会将其转换为JSON数组。然后,它将每个json对象与数据库中的对象进行映射,根据XLS文件更改其数量,并向包含数量变化的图章数组添加时间戳。
例如:
{"_id":"5c3f531baf4fe3182cf4f1f2",
"sku":123456,
"product_name":"Example",
"product_cost":10,
"product_price":60,
"product_quantity":100,
"Warehouse":4,
"stamps":[]
}
XLS上传后,假设我们售出了10个单位,看起来应该像这样:
{"_id":"5c3f531baf4fe3182cf4f1f2",
"sku":123456,
"product_name":"Example",
"product_cost":10,
"product_price":60,
"product_quantity":90,
"Warehouse":4,
"stamps":[{"1548147562": -10}]
}
现在我找不到适合mongoDB的命令,我正在Node.js和Angular中开发,很想阅读一些想法。
for (let i = 0; i < products.length; i++) {
ProductsDatabase.findOneAndUpdate(
{"_id": products[i]['id']},
//CHANGE QUANTITY AND ADD A STAMP
...
}
答案 0 :(得分:0)
您可以使用猫鼬的findOneAndUpdate更新文档的现有值。
"use strict";
const ids = products.map(x => x._id);
let operations = products.map(xlProductData => {
return ProductsDatabase.find({
_id: {
$in: ids
}
}).then(products => {
return products.map(productData => {
return ProductsDatabase.findOneAndUpdate({
_id: xlProductData.id // or product._id
}, {
sku: xlProductData.sku,
product_name: xlProductData.product_name,
product_cost: xlProductData.product_cost,
product_price: xlProductData.product_price,
Warehouse: xlProductData.Warehouse,
product_quantity: productData.product_quantity - xlProductData.product_quantity,
$push: {
stamps: {
[new Date().getTime()]: -1 * xlProductData.product_quantity
}
},
updated_at: new Date()
}, {
upsert: false,
returnNewDocument: true
});
});
});
});
Promise.all(operations).then(() => {
console.log('All good');
}).catch(err => {
console.log('err ', err);
});
答案 1 :(得分:0)
您需要在此处进行两项操作。首先将是从数据库中获取与JSON数组中的文档匹配的文档数组。从列表中比较'product_quantity'
键,如果有更改,请创建一个具有产品ID和数量变化的新对象数组。
第二个操作将是更新,该更新使用此新阵列并更改每个匹配产品的数量。
借助此一系列新的更新的产品属性,非常适合对此进行批量更新,例如遍历列表并发送 对服务器的每次更新请求都可能在计算上昂贵。
请考虑使用模型上的bulkWrite
方法。这接受一个数组的写操作并执行每个写操作,其中一个典型的更新操作
您的用例将具有以下结构
{ updateOne :
{
"filter" : <document>,
"update" : <document>,
"upsert" : <boolean>,
"collation": <document>,
"arrayFilters": [ <filterdocument1>, ... ]
}
}
因此您的操作将遵循以下模式:
(async () => {
let bulkOperations = []
const ids = products.map(({ id }) => id)
const matchedProducts = await ProductDatabase.find({
'_id': { '$in': ids }
}).lean().exec()
for(let product in products) {
const [matchedProduct, ...rest] = matchedProducts.filter(p => p._id === product.id)
const { _id, product_quantity } = matchedProduct
const changeInQuantity = product.product_quantity - product_quantity
if (changeInQuantity !== 0) {
const stamps = { [(new Date()).getTime()] : changeInQuantity }
bulkOperations.push({
'updateOne': {
'filter': { _id },
'update': {
'$inc': { 'product_quantity': changeInQuantity },
'$push': { stamps }
}
}
})
}
}
const bulkResult = await ProductDatabase.bulkWrite(bulkOperations)
console.log(bulkResult)
})()