Replace
ReplaceOne
You can replace a single document entirely by using the ReplaceOne method on an IMongoCollection<T>.
IMongoCollection<T>
.ReplaceOne(FilterDefinition<T> filter, T document)The sample replaces the first document with a new one.
var collection = database
.GetCollection<User>(Constants.UsersCollection);
// this is the new document - demo only
var newUser = RandomData.GenerateUsers(1).First();
// replace the first document in the collection
var replaceOneResult = await collection
.ReplaceOneAsync(Builders<User>.Filter.Empty, newUser);var bsonCollection = database
.GetCollection<BsonDocument>(Constants.UsersCollection);
// this is the new document - demo only
var newUser = RandomData.GenerateUsers(1).First();
var bsonReplaceOneResult = await bsonCollection
.ReplaceOneAsync(new BsonDocument(),
newUser.ToBsonDocument());db.users.replaceOne({},
{
"gender" : 1,
"firstName" : "Chris",
"lastName" : "Sakellarios",
"userName" : "Elsie.VonRueden72",
"avatar" : "https://s3.amazonaws.com/uifaces/faces/twitter/miguelmendes/128.jpg",
"email" : "Elsie.VonRueden@yahoo.com",
"dateOfBirth" : ISODate("1965-08-26T15:55:31.907+02:00"),
"address" : {
"street" : "8902 Baumbach Burg",
"suite" : "Apt. 717",
"city" : "West Carlieton",
"state" : "South Carolina",
"zipCode" : "85642-3703",
"geo" : {
"lat" : -69.6681,
"lng" : -116.3583
}
},
"phone" : "(222) 443-5341 x35825",
"website" : "https://github.com/chsakell",
"company" : {
"name" : "Abshire Inc",
"catchPhrase" : "Function-based mission-critical budgetary management",
"bs" : "monetize holistic eyeballs"
},
"salary" : 2482,
"monthlyExpenses" : 2959,
"favoriteSports" : [
"Basketball",
"Baseball",
"Table Tennis",
"Ice Hockey",
"Handball",
"Formula 1",
"American Football"
],
"profession" : "Model"
})
---------------------------
// sample update result
{
"acknowledged" : true,
"matchedCount" : 1,
"modifiedCount" : 1
}public class User
{
[BsonId]
[BsonIgnoreIfDefault] // required for replace documents
public ObjectId Id { get; set; }
public Gender Gender { get; set; }
public string FirstName {get; set; }
public string LastName {get; set; }
public string UserName {get; set; }
public string Avatar {get; set; }
public string Email {get; set; }
public DateTime DateOfBirth {get; set; }
public AddressCard Address {get; set; }
public string Phone {get; set; }
[BsonIgnoreIfDefault]
public string Website {get; set; }
public CompanyCard Company {get; set; }
public decimal Salary { get; set; }
public int MonthlyExpenses { get; set; }
public List<string> FavoriteSports { get; set; }
public string Profession { get; set; }
}The identifier field _id on the new document must fulfill one of the following conditions:
If specified, must be equal to the current document's value
Not specified at all. MongoDB will create a new one automatically
⚠️ In case you do set a value for the identifier _id field and it's different than the current one, you will get the exception:After applying the update, the (immutable) field '_id' was found to have been altered to _id: <new-id>
One common scenario where you need to replace documents is when you want to move fields inside the documents. Consider that you have the following document.
{
"_id" : ObjectId("5ea55f572109b8cadfc146e9"),
"username" : "chsakell",
"friends" : [
"John",
"Maria",
"Catherine"
],
"blocked" : [
"Jake",
"Helen"
]
}The following sample moves friends and blocked top level fields in a new embedded document field named relationships.
var socialAccountAfter = new SocialAccount
{
Username = username,
RelationShips = new RelationShips
{
Friends = friends,
Blocked = blocked
}
};
await socialNetworkCollection
.ReplaceOneAsync(Builders<SocialAccount>.Filter
.Eq(ac => ac.Username, username), socialAccountAfter);
{
"_id" : ObjectId("5ea55f572109b8cadfc146e9"),
"username" : "chsakell",
"relationShips" : {
"friends" : [
"John",
"Maria",
"Catherine"
],
"blocked" : [
"Jake",
"Helen"
]
}public class SocialAccount
{
[BsonIgnoreIfDefault]
public ObjectId Id { get; set; }
public string Username { get; set; }
public RelationShips RelationShips { get; set; }
}
public class RelationShips
{
public List<string> Friends { get; set; }
public List<string> Blocked { get; set; }
}Upsert
If the filter in the ReplaceOne operation fails to match a document then nothing happens in the database. You can change this behavior by passing a replace options argument to the replace operation and setting upsert = true.
IMongoCollection<T>
.ReplaceOne(FilterDefinition<T> filter,
T document,
ReplaceOptions options)The sample tries to replace a user document that has company name "Microsoft Corp". If it finds a match then it will replace it with the microsoftCeo document but if it doesn't, it will insert it.
var collection = database
.GetCollection<User>(Constants.UsersCollection);
// this is the new document - demo only
var microsoftCeo = RandomData.GenerateUsers(1).First();
microsoftCeo.FirstName = "Satya";
microsoftCeo.LastName = "Nadella";
microsoftCeo.Company.Name = "Microsoft";
// replace the first document in the collection
var addOrReplaceSatyaNadellaResult = await collection
.ReplaceOneAsync<User>(u => u.Company.Name == "Microsoft Corp",
microsoftCeo, new ReplaceOptions()
{
IsUpsert = true
});var bsonCollection = database
.GetCollection<BsonDocument>(Constants.UsersCollection);
// this is the new document - demo only
// this is the new document - demo only
var microsoftCeo = RandomData.GenerateUsers(1).First();
microsoftCeo.FirstName = "Satya";
microsoftCeo.LastName = "Nadella";
microsoftCeo.Company.Name = "Microsoft";
var bsonAddOrReplaceSatyaNadellaUser = await bsonCollection
.FindOneAndReplaceAsync(
Builders<BsonDocument>.Filter.Eq("company.name", "Microsoft Corp"),
microsoftCeo.ToBsonDocument(),
new FindOneAndReplaceOptions<BsonDocument>()
{
IsUpsert = true,
ReturnDocument = ReturnDocument.After
});db.users.replaceOne({ "company.name": "Microsoft Corp"},
{
"gender" : 1,
"firstName" : "Chris",
"lastName" : "Sakellarios",
"userName" : "Elsie.VonRueden72",
"avatar" : "https://s3.amazonaws.com/uifaces/faces/twitter/miguelmendes/128.jpg",
"email" : "Elsie.VonRueden@yahoo.com",
"dateOfBirth" : ISODate("1965-08-26T15:55:31.907+02:00"),
"address" : {
"street" : "8902 Baumbach Burg",
"suite" : "Apt. 717",
"city" : "West Carlieton",
"state" : "South Carolina",
"zipCode" : "85642-3703",
"geo" : {
"lat" : -69.6681,
"lng" : -116.3583
}
},
"phone" : "(222) 443-5341 x35825",
"website" : "https://github.com/chsakell",
"company" : {
"name" : "Abshire Inc",
"catchPhrase" : "Function-based mission-critical budgetary management",
"bs" : "monetize holistic eyeballs"
},
"salary" : 2482,
"monthlyExpenses" : 2959,
"favoriteSports" : [
"Basketball",
"Baseball",
"Table Tennis",
"Ice Hockey",
"Handball",
"Formula 1",
"American Football"
],
"profession" : "Model"
}, { upsert: true })
---------------------------
// sample update result
{
"acknowledged" : true,
"matchedCount" : 0,
"modifiedCount" : 0,
"upsertedId" : ObjectId("5e99f20346296441706dfb4d")
}public class User
{
[BsonId]
[BsonIgnoreIfDefault] // required for replace documents
public ObjectId Id { get; set; }
public Gender Gender { get; set; }
public string FirstName {get; set; }
public string LastName {get; set; }
public string UserName {get; set; }
public string Avatar {get; set; }
public string Email {get; set; }
public DateTime DateOfBirth {get; set; }
public AddressCard Address {get; set; }
public string Phone {get; set; }
[BsonIgnoreIfDefault]
public string Website {get; set; }
public CompanyCard Company {get; set; }
public decimal Salary { get; set; }
public int MonthlyExpenses { get; set; }
public List<string> FavoriteSports { get; set; }
public string Profession { get; set; }
}FindOneAndReplaceOne
IMongoCollection<T> contains a FindOneAndReplaceOne method that behaves exactly the same as the ReplaceOne except that the returned result is of type T instead of a ReplaceOneResult, in other words it returns the updated or upserted document itself. This can be quite convenient when you want to keep working with the new document after replacing it.
IMongoCollection<T>
.FindOneReplaceOne(FilterDefinition<T> filter,
T document,
FindOneAndReplaceOptions options)The sample replaces the first document with a new one and gets back the entire document.
var collection = database
.GetCollection<User>(Constants.UsersCollection);
var firstDbUser = await collection.
Find(Builders<User>.Filter.Empty)
.FirstOrDefaultAsync();
// this is the new document - demo only
var newUser = RandomData.GenerateUsers(1).First();
newUser.Id = firstDbUser.Id;
newUser.FirstName = "Chris";
newUser.LastName = "Sakellarios";
newUser.Website = "https://github.com/chsakell";
// replace the first document in the collection
var firstUser = await collection
.FindOneAndReplaceAsync(
Builders<User>.Filter.Eq(u => u.Id, firstDbUser.Id),
newUser,
new FindOneAndReplaceOptions<User>
{ReturnDocument = ReturnDocument.After});var bsonCollection = database
.GetCollection<BsonDocument>(Constants.UsersCollection);
// this is the new document - demo only
var newUser = RandomData.GenerateUsers(1).First();
newUser.Id = firstDbUser.Id;
newUser.FirstName = "Chris";
newUser.LastName = "Sakellarios";
newUser.Website = "https://github.com/chsakell";
var bsonFirstUser = await bsonCollection.FindOneAndReplaceAsync(
Builders<BsonDocument>.Filter.Eq("_id", firstDbUser.Id),
newUser.ToBsonDocument(),
new FindOneAndReplaceOptions<BsonDocument>
{ ReturnDocument = ReturnDocument.After });public class User
{
[BsonId]
[BsonIgnoreIfDefault] // required for replace documents
public ObjectId Id { get; set; }
public Gender Gender { get; set; }
public string FirstName {get; set; }
public string LastName {get; set; }
public string UserName {get; set; }
public string Avatar {get; set; }
public string Email {get; set; }
public DateTime DateOfBirth {get; set; }
public AddressCard Address {get; set; }
public string Phone {get; set; }
[BsonIgnoreIfDefault]
public string Website {get; set; }
public CompanyCard Company {get; set; }
public decimal Salary { get; set; }
public int MonthlyExpenses { get; set; }
public List<string> FavoriteSports { get; set; }
public string Profession { get; set; }
}FindOneAndReplaceOptions
When using the FindOneAndReplace method you have two options for the returned result:
Return the updated document - you need to set
ReturnDocument = ReturnDocument.Afterin theFindOneAndReplaceOptionsReturn the document before being updated - you need to set
ReturnDocument = ReturnDocument.Beforein theFindOneAndREplaceOptionsor leave it as is since it's the default value
Last updated