How to update a field in an array subdocument contained in an array subcomplex in MongoDB using a C # driver?

I have a collection of documents in MongoDB with a structure like this (there are several container documents, each of which contains Sessions , each session contains 1 order, each order contains several elements):

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

I would like to update the Title this Item within the order in the session, knowing the _id item (I also know the session identifier if this helps):

I tried the following:

 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)); 

Both throw an exception WriteConcern detected an error 'cannot use the part (Sessions of Sessions.Order.Items.0.Status) to traverse the element ... I also tried different combinations of combined queries using Query.And , which probably make so little sense that they should not be published here.

How to update a field in a sub-folder contained in an array of documents using a C # driver?

I understand that this cannot be done only with the help of the positioning operator (and the positioning operator will not magically match the internal array).

I am looking from ready-made solutions how to perform this type of update without changing the scheme.

+2
source share
2 answers

The answer from @Disposer helped me find a solution to this. It spreads several areas in my code base, but I would like to share the main point with others who may have a similar problem.

These are the following steps:

  • Block this order and prevent elements from being added to it (at the application level).
  • Alternatively, use a combination of the WriteCount extra field and use findAndModify to atomically update the document only if it was not updated at the same time ("update if current").

Then, when updating the Title for this item:

  • use saved WriteCount
  • determine element index
  • use the element index in conjunction with the positioning operator: $ to identify the session, an integer index to target the element, using the "update if current" strategy using the WriteCount field.

Then the update part becomes:

 "Sessions.$.Order.Items." + index + ".Title" 
+3
source

You are not updating a subdocument of a subdocument. You are updating one field of a sub-document of an array that is inside a sub-parent of the parent array.

You can update the first element with the blow code

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

with a simple update request, you cannot update the all header. This link may help you (with custom JavaScript update request)

How to repeatedly update a nested array in MondoDB?

+5
source

All Articles