簡體   English   中英

MongoDB 更新(聚合管道)使用來自嵌套嵌套 Arrays 的值

[英]MongoDB Update (Aggregation Pipeline) using values from nested nested Arrays

我正在嘗試根據嵌套的嵌套數組中的值更新我的文檔中的字段(totalPrice)(addOns > 從 arrays 的 x 個數中獲取匹配數組 > 在匹配數組中獲取 int [總是在 pos 2] )。

這是一個包含 2 個 arrays 嵌套在 addOns 中的文檔示例:

{
   "_id": ObjectID('.....'),
   "addOns": [
                ["appleId", "Apples", 2],
                ["bananaID", "Bananas", 1]
             ],
   "totalPrice": 5.7
}

假設香蕉的價格上漲了 20 美分,所以我需要查找其插件中包含香蕉的所有文檔,然后根據購買的香蕉數量增加這些文檔的 totalPrice。 我計划使用一個聚合管道來使用 updateMany() 查詢,它應該大致類似於下面的示例。 這??? 應該是購買的香蕉數量,但我不確定如何通過 go 檢索該值。 到目前為止,我一直在考慮使用 $unwind、$filter 和 $arrayElemAt,但不確定如何將它們一起使用。 將不勝感激任何幫助!

db.collection('orders').updateMany(
     { $elemMatch: { $elemMatch: { $in: ['bananaID'] } } },
     [
          { $set: {'totalPrice': { $add: ['$totalPrice', { $multiply: [{$toDecimal: '0.2'}, ???] } ] } } }
     ]

我不確定我的 mongo 版本是什么,但我知道我可以使用聚合管道,因為我還有其他 updateMany() 調用也使用管道沒有任何問題,所以它應該是(版本> = 4.2) .

**編輯:為???想到這一點,隨着文檔的更新,過濾步驟似乎有點工作,但值是 null 而不是更新后的價格。 不知道為什么

  1. 過濾 '$addOns' 數組以返回匹配的嵌套數組。
  2. 對於條件,使用 $eq 檢查 [0] ('$$this.0') 處的元素是否與字符串 'bananaID' 匹配,如果它確實返回此嵌套數組。
  3. 使用 $arrayElemAt 和 position [0] 獲取從步驟 1 返回的數組。
  4. 在第 3 步中的數組上再次使用 $arrayElemAt,位置為 [2],因為它是數量元素的索引
{ $arrayElemAt: [{ $arrayElemAt: [ { $filter: { input: "$addOns", as:'this', cond: { $eq: ['$$this.0', 'bananaID'] } } } , 0 ] }, 2 ] }

設法自己解決了這個問題 - 雖然只有在你不介意問題評論中喬所說的 updateMany() 風險的情況下才使用它。 它與我最初在 ** Edit中共享的內容非常相似,只是您不能使用$$this.0訪問數組中的元素。

把這個插入到哪里??? 是並且它會起作用,在這個代碼塊下面是解釋:

{ $arrayElemAt: [{ $arrayElemAt: [ { $filter: { input: "$addOns", as:'this', cond: { $eq: [{$arrayElemAt:['$$this', 0]}, 'bananaID'] } } } , 0 ] }, 2 ] }
  1. 我們的數組如下所示: [["appleId", "Apples", 2], ["bananaID", "Bananas", 1]]
  2. 使用 $filter 來返回我們數組的一個子集,它只包含與我們的條件匹配的元素——在這種情況下,我們想要香蕉的數組。 $$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]]
  1. 因為嵌套的香蕉數組總是第一個元素,所以我們在第 2 步的結果中使用 $arrayElemAt 來檢索 position 0 處的元素。
// How it looks like after step 3: ["bananaID", "Bananas", 1]
  1. 最后一步是再次使用 $arrayElemAt,除了這次我們要檢索 position 2 處的元素(購買的香蕉數量)
  2. 這是評估步驟 1-4 后最終 updateMany() 查詢的樣子。
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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM