社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  MongoDB

MongoDB-找到一个并添加新属性

Elad Dahan • 5 年前 • 902 次点击  

背景:我正在开发一个应用程序,显示库存管理的分析。 它获取一个上传的office EXCEL文件,当文件上传时,应用程序将其转换为一个json数组。然后,它将每个json对象与数据库中的对象合并,根据XLS文件更改其数量,并向包含数量更改的stamps数组添加时间戳。

例如:

{"_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

...
}
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/50866
 
902 次点击  
文章 [ 2 ]  |  最新文章 5 年前
Sridhar
Reply   •   1 楼
Sridhar    6 年前

你可以用猫鼬的 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);
});
chridam
Reply   •   2 楼
chridam    6 年前

你需要在这里做两次手术。第一种方法是从数据库中获取与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)

})()