Scenario
I have a conversation document in mongodb , I have to add messages to a messages array and update the last sent date , see schema below.
{
"_id" : NumberInt(5),
"CurrentOwnerId" : NumberInt(9),
"LastSent" : ISODate("2019-06-21T11:57:32.861+0000"),
"Messages" : [
{
"_id" : BinData(3, "nuC1iYTKtkGzSuv7pVHsKg=="),
"MessageContent" : "Hi There",
"Status" : "Pending",
"DateSent" : ISODate("2019-06-21T11:57:32.861+0000"),
"Method" : "Slack"
}
]
}
My question
Would it be more efficient to simply read out the whole document (using the BsonId
) and update the document via c# as a whole ie pushing my message to the array and setting the last sent day and then updating the document as a whole using the driver OR do two calls to the database using $set and $push operators to achieve what I want to do.
As Eduardo Hitek said, you can set multiple properties in a single query. So you can update the entity without actually having to retrieve it from the database first like this:
//Build an Id Filter
var idFilter = Builders<Chat>.Filter.Eq(x => x.Id, "1");
var message = new Message() { MessageContent = "Hey!", Method = "Slack" };
//Build an update definition to add the message
var addMessage = Builders<Chat>.Update.AddToSet(x => x.Messages, message);
//Build an update definition to set the LastSent property
var setLastSent = Builders<Chat>.Update.Set(x => x.LastSent, DateTime.Now);
//Combine both update definitions
var combinedUpdate = Builders<Chat>.Update.Combine(addMessage, setLastSent);
//Execute the query.
db.GetCollection<Chat>("ChatCollection").UpdateOne(idFilter, combinedUpdate);
The added benefit from updating an entity like this is that it's done atomically.