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 CSharp
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 CSharp
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:
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 was going to be updated.
Check out this video on these MongoDB document update features in C#:
Wrapping Up How To Update MongoDB Documents in CSharp
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!
Want More Dev Leader Content?
- Follow along on this platform if you haven’t already!
- Subscribe to my free weekly software engineering and dotnet-focused newsletter. I include exclusive articles and early access to videos: SUBSCRIBE FOR FREE
- Looking for courses? Check out my offerings: VIEW COURSES
- E-Books & other resources: VIEW RESOURCES
- Watch hundreds of full-length videos on my YouTube channel: VISIT CHANNEL
- Visit my website for hundreds of articles on various software engineering topics (including code snippets): VISIT WEBSITE
- Check out the repository with many code examples from my articles and videos on GitHub: VIEW REPOSITORY
Top comments (1)
Hi goglides, Your website is really amazing and it helps a lot.