【发布时间】:2020-11-04 00:35:29
【问题描述】:
我正在尝试根据嵌套、嵌套数组中的值更新文档中的字段 (totalPrice) (addOns > 从 x 个数组中获取匹配数组 > 在匹配数组中获取 int[总是在位置 2])。
这是一个文档示例,其中包含嵌套在 addOns 中的 2 个数组:
{
"_id": ObjectID('.....'),
"addOns": [
["appleId", "Apples", 2],
["bananaID", "Bananas", 1]
],
"totalPrice": 5.7
}
假设香蕉的价格上涨了 20 美分,所以我需要查找其 addOns 中包含香蕉的所有文档,然后根据购买的香蕉数量增加这些文档的 totalPrice。我计划使用一个聚合管道来使用 updateMany() 查询,它应该大致类似于下面的示例。这 ???应该是购买的香蕉数量,但我不确定如何检索该值。到目前为止,我一直在考虑使用 $unwind、$filter 和 $arrayElemAt,但不知道如何一起使用它们。非常感谢任何帮助!
db.collection('orders').updateMany(
{ $elemMatch: { $elemMatch: { $in: ['bananaID'] } } },
[
{ $set: {'totalPrice': { $add: ['$totalPrice', { $multiply: [{$toDecimal: '0.2'}, ???] } ] } } }
]
我不确定我的 mongo 版本是什么,但我确实知道我可以使用聚合管道,因为我还有其他 updateMany() 调用也使用管道没有任何问题,所以应该是(版本> = 4.2)。
**编辑:为 ??? 考虑了这一点,随着文档的更新,过滤步骤似乎有些工作,但值为 null 而不是更新后的价格。不知道为什么
- 过滤“$addOns”数组以返回匹配的嵌套数组。
- 对于条件,使用 $eq 来检查 [0] 处的元素 ('$$this.0') 是否与字符串 'bananaID' 匹配,是否返回此嵌套数组。
- 使用 $arrayElemAt 和位置 [0] 获取第 1 步返回的数组。
- 在第 3 步中的数组上再次使用 $arrayElemAt,位置为 [2],因为它是数量元素的索引
{ $arrayElemAt: [{ $arrayElemAt: [ { $filter: { input: "$addOns", as:'this', cond: { $eq: ['$$this.0', 'bananaID'] } } } , 0 ] }, 2 ] }
【问题讨论】:
-
我建议重新计算整个价格,而不是仅仅调整。如果在中途发生某些事情中断了您的 updateMany,那么重新同步所有文档将是一个很大的挑战。
-
这是否意味着我必须检索所有文档,计算新价格,然后为每个文档调用 updateOne() 并使用相应的 ObjectId 和更新价格?
-
我想这取决于价格的存储方式。
-
是的,这样会很复杂,rip
标签: node.js arrays mongodb aggregation-framework