Using C# To Update MongoDB Documents

Written by devleader | Published 2024/04/01
Tech Story Tags: mongodb | database | databases | dotnet | csharp | coding | software-development | programming

TLDRvia the TL;DR App

Recently I’ve been publishing content on working with MongoDB from C#, and this article continues on that path. If you haven’t already covered how you can perform filtering of documents from MongoDB in C#, I’d highly suggest you get a basic understanding before continuing. In this article, I’ll cover how to update MongoDB documents in C#, but the code examples will assume you know how to filter what you’re interested in!

If you’re looking to incorporate MongoDB into your C# application and want to understand how to update documents, read on!


Basics of MongoDB in C#

To get started with MongoDB in C#, you’ll need to install the MongoDB driver for C#. This driver provides a high-level API for interacting with MongoDB from your C# code, and it’s as simple as getting the NuGet package installed. Once you have the driver installed, you can establish a connection to your MongoDB database and start working with documents.

If you’re using something like MongoDB Atlas and the desktop tool Compass, these should walk you through how you can get your connection string sorted out. However, if you’re using other hosting providers or hosting locally, you’ll need to follow relevant instructions for how to get your connection string set up so that you can connect properly. Unfortunately, I can’t document this for every possibility 🙂

In MongoDB, data is stored in collections, which are analogous to tables in a relational database. Maybe not structurally or how they’re implemented, but conceptually, this is the easiest way to think about them. Each document within a collection is a JSON-like object that can have different fields and values. In SQL databases, we’re used to thinking about rows to update, and a single row spans multiple columns in a table. However, in a document database like MongoDB, the “row” is an entire document, which can be hierarchical data. To update a document in MongoDB, you need to specify the collection and the document you want to update.


Updating Documents in MongoDB Using C#

Before getting ahead of ourselves here with updating, it’s important to make sure we understand how filtering works. This is because to update the correct documents, we need to make sure that we can identify WHICH documents we need to update! If your filter is wrong, you’ll be in for a world of pain — or maybe not pain but a high amount of discomfort as you’re debugging database issues.

If you need a primer on how to filter, you can read this article on filtering MongoDB records from C#. And if that’s not straightforward or aligned with your learning style, you may find this video on using C# to filter MongoDB records of better value:

https://youtu.be/2zXvDW2YFcg?embedable=true


UpdateOne and UpdateOneAsync in MongoDB

The UpdateOne method updates a single document that matches the specified filter criteria. You can use the $set operator to update specific fields within the document, or in C# specifically, by calling the Set() method on the update builder.

It’s important to note here that there’s nothing that forces you to write a filter that will match a single document. In fact, you can write a filter that’s just empty to match EVERY document and call UpdateOne. By doing that, you’re going to match every document but the method call will still only update one document. Is it the document you expect? Probably by definition, no, if you wrote a filter that matches multiple. Try to pay special attention to this!

Here’s a simple example of calling the UpdateOne method, and an important callout that there is an async version as well:

var filter = Builders<MyDocument>.Filter.Eq("fieldName", "fieldValue");
var update = Builders<MyDocument>.Update.Set("fieldName", "newValue");

var result = collection.UpdateOne(filter, update);

// async version
// var result = await collection.UpdateOneAsync(filter, update);

The result that is returned has a matched and modified count that we can investigate. It’s worth noting in all of my experience so far that even if your filter matches MANY items, if you call UpdateOne it will at most show you a matched count of one still. As a result, this does not seem to be a reliable way to tell if your filter would have (or did) match multiple items and still only updated one.


UpdateMany and UpdateManyAsync in MongoDB

Much like the previous example, UpdateMany and UpdateManyAsync have *almost* the same behavior — except for one tiny detail, which you probably figured out already. The “many” part.

UpdateMany will allow you to take that same approach with your filter and update all of the records that match the filter in the way that you’ve defined your update definition. If you truly expect your filter to be able to match multiple, I would advise using this — otherwise, UpdateOne makes more sense.

The code example below shows the sync and async variations:

var filter = Builders<MyDocument>.Filter.Gte("fieldValue", minValue);
var update = Builders<MyDocument>.Update.Set("fieldName", "newValue");

var result = collection.UpdateMany(filter, update);

// async version
//var result = await collection.UpdateManyAsync(filter, update);

Like UpdateOne, the result that we have to work with has the matched and updated counts. However, unlike UpdateOne, the match count will indicate how many items truly did match the filter and not be limited to one at most.


FindOneAndUpdate and FindOneAndUpdateAsync Methods

FindOneAndUpdate and the async variation are very much like UpdateOne method variations. These methods will perform an update on up to one document matching the filter, but the interesting difference is the return value. The return type provides us access to a snapshot of the document that matched the filter BEFORE it was updated.

Here’s a code example of FindOneAndUpdate:

var filter = Builders<MyDocument>.Filter.Gte("fieldValue", minValue);
var update = Builders<MyDocument>.Update.Set("fieldName", "newValue");

var result = collection.FindOneAndUpdate(filter, update);

// async version
//var result = await collection.FindOneAndUpdateAsync(filter, update);

The result that comes back from this method call would provide the matching document where fieldName would still be whatever value existed before it was set to “newValue”. This can be useful in eliminating a full round-trip to the database if you want to know ahead of time which document is going to be updated.

Check out this video on these MongoDB document update features in C#:

https://youtu.be/fnPRmoSlTHE?embedable=true


Wrapping Up How To Update MongoDB Documents in C#

And now you have all of the basics covered on how to update MongoDB documents in C#! In this article, I covered several variations that are all very similar given that they require a proper filter and a proper update definition to be written:

  • UpdateOne: updates up to one single document based on the filter
  • UpdateMany: updates all of the matching documents based on the filter
  • FindOneAndUpdate: updates up to one single document based on the filter and returns the matching document BEFORE it was updated

If you found this useful and you’re looking for more learning opportunities, consider subscribing to my free weekly software engineering newsletter and check out my free videos on YouTube! Meet other like-minded software engineers and join my Discord community!


Also published here.


Written by devleader | Helping software engineers level up! I share content for general software engineering and C#/dotnet development/
Published by HackerNoon on 2024/04/01