Javascript 如何在单个mongo db更新操作中更新一个数组的多个对象?

Javascript 如何在单个mongo db更新操作中更新一个数组的多个对象?,javascript,node.js,mongodb,Javascript,Node.js,Mongodb,我有一份结构如下的订单文件 "order" : { "id": 999, "products" : [ { "id": 1, "price": 12.344746 }, { "id": 2, "price&

我有一份结构如下的订单文件

"order" : {
    "id": 999, 
    "products" : [ 
        {
            "id": 1,
            "price": 12.344746
        },
        {
            "id": 2,
            "price": 45.688755
        },
        {
            "id": 3,
            "price": 89.5667574
        }
    ],
    "total": 151.7965567
}
我正在编写一个脚本,使用toFixed()修复price字段的小数位。 为了更新所有产品,我正在循环产品并对每个产品id调用update()

order.products.forEach((product) => {
   var updatedPrice = product.price.toFixed(2);
   db.orders.updateOne({
        id: 999,
        products: {
            $elemMatch: {
                id: product.id
            }
        }
   }, {
        $set: {
            "products.$.price": updatedPrice
        }
    })
})
var updatedTotal = order.total.toFixed(2);
db.orders.updateOne({
    id: 999
},
{
    $set: {
        total: updatedTotal
    }
})
所以,为了更新一条记录,我做了4个单独的更新操作

是否可以在一次操作中更新所有内容

附言:除了产品和道达尔,还有许多其他领域。为了简单起见,我只使用了两个。另外,我不希望设置每个字段。

您可以只使用支持过滤器的函数。

您可以只使用支持过滤器的函数。

一种可能的方法是(参考Mykola Borysuk对问题的评论)只更新产品数组和内存中的总数,只需一次查询,同时更新它们

const order = await db.collection("orders").findOne({
    _id: 999 //ObjectID of whatever order you want updated
})

order.products.forEach((product) => {
   product.price = parseFloat(product.price.toFixed(2));
})

const updatedTotal = parseFloat(product.total.toFixed(2));

db.collection("orders").updateOne({
    id: 999
},
{
    $set: {
        products: order.products,
        total: updatedTotal
    }
})
注意:函数
.toFixed()
返回一个字符串,而不是一个数字,根据您描述的数据模型,要更新的字段是浮点数,因此,除非您想更改这些字段的类型,您应该通过
parseFloat

运行它们,一种可能的方法是(参考Mykola Borysuk对问题的评论)只更新产品数组和内存中的总数,只需一次查询,就可以同时更新它们

const order = await db.collection("orders").findOne({
    _id: 999 //ObjectID of whatever order you want updated
})

order.products.forEach((product) => {
   product.price = parseFloat(product.price.toFixed(2));
})

const updatedTotal = parseFloat(product.total.toFixed(2));

db.collection("orders").updateOne({
    id: 999
},
{
    $set: {
        products: order.products,
        total: updatedTotal
    }
})

注意:函数
.toFixed()
返回一个字符串,而不是一个数字,根据您描述的数据模型,要更新的字段是浮点数,因此,除非您想更改这些字段的类型,您应该通过
parseFloat

运行它们。请详细说明updateMany()如何解决我的问题?请详细说明updateMany()如何解决我的问题?是否还有更多订单?我不能很好地理解你的json。可能包括一个指向更完整代码段的链接。请注意Neil Lunn答案中的引用:。希望这有助于您只想获取一份订单并更新该产品的所有
products
total
属性,对吗?我写了这个,还没有,`db.collection.updateOne({id:999},[{$set:{“products”:{$map:{input:$products”,as:'p',in:{$trunc:[$p.price],2]}}}])`@AnujPancholi hi:-)
$map
专门用于聚合,但现在(4.2+)在
更新中允许使用一些聚合运算符。请仔细考虑我的建议,我不能再谈了。还有订单吗?我不能很好地理解你的json。可能包括一个指向更完整代码段的链接。请注意Neil Lunn答案中的引用:。希望这有助于您只想获取一份订单并更新该产品的所有
products
total
属性,对吗?我写了这个,还没有,`db.collection.updateOne({id:999},[{$set:{“products”:{$map:{input:$products”,as:'p',in:{$trunc:[$p.price],2]}}}])`@AnujPancholi hi:-)
$map
专门用于聚合,但现在(4.2+)在
更新中允许使用一些聚合运算符。请仔细考虑我的建议,我不能再进一步了