22

I have a document with an array field, similar to this:

{ 
  "_id" : "....",
  "Statuses" : [
    { "Type" : 1, "Timestamp" : ISODate(...) },
    { "Type" : 2, "Timestamp" : ISODate(...) },
    //Etc. etc.
  ]
}

How can I update a specific Status item's Timestamp, by specifying its Type value?

Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
Redth
  • 5,464
  • 6
  • 34
  • 54

2 Answers2

28

From mongodb shell you can do this by

db.your_collection.update(
    { _id: ObjectId("your_objectid"), "Statuses.Type": 1 },
    { $set: { "Statuses.$.Timestamp": "new timestamp" } }
)

so the c# equivalent

var query = Query.And(
    Query.EQ("_id", "your_doc_id"),
    Query.EQ("Statuses.Type", 1)
);

var result = your_collection.Update( 
    query, 
    Update.Set("Statuses.$.Timestamp", "new timestamp", UpdateFlags.Multi,SafeMode.True)
); 

This will update the specific document, you can remove _id filter if you wanted to update the whole collection

G-Wiz
  • 7,370
  • 1
  • 36
  • 47
RameshVel
  • 64,778
  • 30
  • 169
  • 213
9

Starting with MongoDB 3.6, the $[<identifier>] positional operator may be used. Unlike the $ positional operator — which updates at most one array element per document — the $[<identifier>] operator will update every matching array element. This is useful for scenarios where a given document may have multiple matching array elements that need to be updated.

db.yourCollection.update(
  { _id: "...." },
  { $set: {"Statuses.$[element].Timestamp": ISODate("2021-06-23T03:47:18.548Z")} },
  { arrayFilters: [{"element.Type": 1}] }
);

The arrayFilters option matches the array elements to update, and the $[element] is used within the $set update operator to indicate that only array elements that matched the arrayFilter should be updated.

M. Justin
  • 14,487
  • 7
  • 91
  • 130