[英]MongoDB Update (Aggregation Pipeline) using values from nested nested Arrays
I'm trying to update a field (totalPrice) in my document(s) based on a value in a nested, nested array (addOns > get matching array from x number of arrays > get int in matching array[always at pos 2]).我正在尝试根据嵌套的嵌套数组中的值更新我的文档中的字段(totalPrice)(addOns > 从 arrays 的 x 个数中获取匹配数组 > 在匹配数组中获取 int [总是在 pos 2] )。
Here's an example of a document with 2 arrays nested in addOns:这是一个包含 2 个 arrays 嵌套在 addOns 中的文档示例:
{
"_id": ObjectID('.....'),
"addOns": [
["appleId", "Apples", 2],
["bananaID", "Bananas", 1]
],
"totalPrice": 5.7
}
Let's say the price of bananas increased by 20cents, so I need to look for all documents that have bananas in its addOns, and then increase the totalPrice of these documents depending on the number of bananas bought.假设香蕉的价格上涨了 20 美分,所以我需要查找其插件中包含香蕉的所有文档,然后根据购买的香蕉数量增加这些文档的 totalPrice。 I plan on using a updateMany() query using an aggregation pipeline that should roughly look like the example below.
我计划使用一个聚合管道来使用 updateMany() 查询,它应该大致类似于下面的示例。 The???
这??? should be the number of bananas bought, but I'm not sure how to go about retrieving that value.
应该是购买的香蕉数量,但我不确定如何通过 go 检索该值。 So far I've thought of using $unwind, $filter, and $arrayElemAt, but not sure how to use them together.
到目前为止,我一直在考虑使用 $unwind、$filter 和 $arrayElemAt,但不确定如何将它们一起使用。 Would appreciate any help!
将不胜感激任何帮助!
db.collection('orders').updateMany(
{ $elemMatch: { $elemMatch: { $in: ['bananaID'] } } },
[
{ $set: {'totalPrice': { $add: ['$totalPrice', { $multiply: [{$toDecimal: '0.2'}, ???] } ] } } }
]
I'm not exactly sure whats my mongo version is, but I do know that I can use the aggregation pipeline because I have other updateMany() calls that also use the pipeline without any issues, so it should be (version >= 4.2).我不确定我的 mongo 版本是什么,但我知道我可以使用聚合管道,因为我还有其他 updateMany() 调用也使用管道没有任何问题,所以它应该是(版本> = 4.2) .
** Edit : Thought of this for the???, the filter step seems to work somewhat as the documents are getting updated, but the value is null instead of the updated price. **编辑:为???想到这一点,随着文档的更新,过滤步骤似乎有点工作,但值是 null 而不是更新后的价格。 Not sure why
不知道为什么
{ $arrayElemAt: [{ $arrayElemAt: [ { $filter: { input: "$addOns", as:'this', cond: { $eq: ['$$this.0', 'bananaID'] } } } , 0 ] }, 2 ] }
Managed to solve it myself - though only use this if you don't mind the risk of updateMany() as stated by Joe in the question's comments.设法自己解决了这个问题 - 虽然只有在你不介意问题评论中乔所说的 updateMany() 风险的情况下才使用它。 It's very similar to what I originally shared in ** Edit , except you cant use
$$this.0
to access elements in the array.它与我最初在 ** Edit中共享的内容非常相似,只是您不能使用
$$this.0
访问数组中的元素。
Insert this into where the???把这个插入到哪里??? is and it'll work, below this code block is the explanation:
是并且它会起作用,在这个代码块下面是解释:
{ $arrayElemAt: [{ $arrayElemAt: [ { $filter: { input: "$addOns", as:'this', cond: { $eq: [{$arrayElemAt:['$$this', 0]}, 'bananaID'] } } } , 0 ] }, 2 ] }
[["appleId", "Apples", 2], ["bananaID", "Bananas", 1]]
[["appleId", "Apples", 2], ["bananaID", "Bananas", 1]]
$$this
represents each element in input, and we check whether the first element of $$this
matches 'bananaID'. $$this
代表输入中的每个元素,我们检查$$this
的第一个元素是否匹配'bananaID'。{ $filter: { input: "$addOns", as:'this', cond: { $eq: [{$arrayElemAt:['$$this', 0]}, 'bananaID'] } } }
// how the result from $filter should look like
// [["bananaID", "Bananas", 1]]
// How it looks like after step 3: ["bananaID", "Bananas", 1]
db.collection('orders').updateMany(
{ $elemMatch: { $elemMatch: { $in: ['bananaID'] } } },
[
{ $set: {'totalPrice': { $add: ['$totalPrice', { $multiply: [{$toDecimal: '0.2'}, 1] } ] } } }
], *callback function code*)
// notice how the ??? is now replaced by the quantity of bananas which is 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.