2014-11-06 27 views
2

我有像這樣的結構在MongoDB中的文檔集合(有多個容器文件,每份含Sessions,每個會話包含1個訂單,每個訂單包含多個項目):如何使用C#驅動程序更新MongoDB中數組子文檔中包含的數組子文檔中的字段?

{ 
    "Sessions" : [{ 
     "ID" : "1882a092-d395-45d1-b36b-e2fa3df81b95", 
     "Order" : { 
     "Items" : [{ 
      "_id" : "a9c94a5e-10ef-433d-9c63-f4555eb7c2a7", 
      "Title" : "UPDATE THIS", 
      }] 
     } 
    }], 
    "_id" : "1b640bc4-fdb4-49b1-9c60-e4c6f1bd0405" 
} 

我想在會話訂單中更新指定ItemTitle在明知該項目的_id(我也知道會話的ID是否有幫助):

我曾嘗試以下:

col.Update(Query.EQ("Sessions.ID", sessionID), 
       Update.Set("Sessions.$.Order.Items.Title", newTitle)); 

col.Update(Query.EQ("Sessions.Order.Items._id", id), 
       Update.Set("Sessions.Order.Items.$.Title", newTitle)); 

兩者都拋出異常WriteConcern detected an error 'cannot use the part (Sessions of Sessions.Order.Items.0.Status) to traverse the element ...。我還嘗試了使用Query.And的組合查詢的不同組合,這些組合可能沒什麼意義,所以不值得在這裏發佈。

如何使用C#驅動程序更新包含在文檔數組中的子文檔中的字段?

我意識到這不能與位置操作符單獨完成(位置操作符不會神奇地匹配內部數組)。

我正在尋找開箱即用的解決方案,如何在不更改架構的情況下完成此類更新。

回答

3

回答幫我找到了一個解決方案。它在我的代碼庫中傳播多個領域,但我想與可能有類似問題的其他人分享基本要點。

這些步驟如下:

  • 鎖定給定的順序,不要讓物品被添加進去(應用層)。
  • 或者,也可以使用其他WriteCount字段的組合和使用findAndModify來自動更新文檔(僅當它在此期間尚未更新時)(「如果當前更新」)。

然後,對於給定的項目更新Title時:

  • 使用存儲WriteCount
  • 確定項目索引
  • 結合使用的項目索引與位置運算符:$識別會話的,一個整數index目標的項目,同時採用「更新如果當前」策略使用WriteCount字段。然後

更新部分變爲:

"Sessions.$.Order.Items." + index + ".Title" 
+0

更好的答案可以在這裏找到:https://stackoverflow.com/questions/31804925/update-field-in-array-mongodb-c-sharp -driver – 2017-10-03 16:47:08

5

您沒有更新子文檔的子文檔。 您正在更新位於父數組的子文檔中的數組子文檔的一個字段。

您可以通過代碼打擊

col.Update(Query.EQ("Sessions.ID", sessionID), 
       Update.Set("Sessions.$.Order.Items.0.Title", newTitle)); 

用一個簡單的更新查詢更新第一元素,你不能更新所有元素稱號。 此鏈接可以幫助你(通過自定義JavaScript的更新查詢)從@Disposer

How to multi update of a nested array in MondoDB?

相關問題