# Replace

## *ReplaceOne*

You can replace a single document entirely by using the `ReplaceOne` method on an `IMongoCollection<T>`.

{% tabs %}
{% tab title="Syntax" %}

```csharp
IMongoCollection<T>
    .ReplaceOne(FilterDefinition<T> filter, T document)
```

{% endtab %}
{% endtabs %}

The sample replaces the first document with a new one.

{% tabs %}
{% tab title="C#" %}
{% code title="ReplaceDocuments.cs" %}

```csharp
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);
```

{% endcode %}
{% endtab %}

{% tab title="Bson" %}

```csharp
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());
```

{% endtab %}

{% tab title="Shell" %}

```javascript
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
}
```

{% endtab %}

{% tab title="User" %}

```csharp
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; }
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
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

:warning: 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>`**
{% endhint %}

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.

```javascript
{
        "_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.*

{% tabs %}
{% tab title="C#" %}
{% code title="ReplaceDocuments.cs" %}

```csharp
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);
        
```

{% endcode %}
{% endtab %}

{% tab title="Result" %}

```javascript
{
        "_id" : ObjectId("5ea55f572109b8cadfc146e9"),
        "username" : "chsakell",
        "relationShips" : {
                "friends" : [
                        "John",
                        "Maria",
                        "Catherine"
                ],
                "blocked" : [
                        "Jake",
                        "Helen"
                ]
        }
```

{% endtab %}

{% tab title="Models" %}

```csharp
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; }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
When replacing a document make sure to be precise 🎯 on your filter, otherwise you might get a **`E11001 duplicate key on update`** error. For example, in the previous sample if the *socialAccountAfter* object already contained the **\_*****id*** value and there were more than one documents with username *"chsakell"* you would get the error. Why? Because MongoDB would try to set in more than one documents the same ***\_id*** unique identifier value.
{% endhint %}

## 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`.&#x20;

{% tabs %}
{% tab title="Syntax" %}

```csharp
IMongoCollection<T>
    .ReplaceOne(FilterDefinition<T> filter, 
                T document, 
                ReplaceOptions options)
```

{% endtab %}
{% endtabs %}

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.

{% tabs %}
{% tab title="C#" %}
{% code title="ReplaceDocuments.cs" %}

```csharp
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
        });
```

{% endcode %}
{% endtab %}

{% tab title="Bson" %}

```csharp
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
    });
```

{% endtab %}

{% tab title="Shell" %}

```javascript
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")
}
```

{% endtab %}

{% tab title="User" %}

```csharp
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; }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
When no match found, the update result will be the following:

```javascript
{
	"acknowledged" : true,
	"matchedCount" : 0, // no match found
	"modifiedCount" : 0, // so nothing modified
	"upsertedId" : ObjectId("5e99f20346296441706dfb4d")
}
```

:owl: Since you set **`upsert = true`** a new document inserted with *\_id* equal to the *upsertedId*&#x20;
{% endhint %}

## *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.&#x20;

{% tabs %}
{% tab title="Syntax" %}

```csharp
IMongoCollection<T>
    .FindOneReplaceOne(FilterDefinition<T> filter, 
                T document, 
                FindOneAndReplaceOptions options)
```

{% endtab %}
{% endtabs %}

The sample replaces the first document with a new one and gets back the entire document.

{% tabs %}
{% tab title="C#" %}
{% code title="ReplaceDocuments.cs" %}

```csharp
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});
```

{% endcode %}
{% endtab %}

{% tab title="Bson" %}

```csharp
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 });
```

{% endtab %}

{% tab title="User" %}

```csharp
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; }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}

### FindOneAndReplaceOptions

When using the `FindOneAndReplace` method you have two options for the returned result:

1. Return the updated document - you need to set **`ReturnDocument = ReturnDocument.After`** in the `FindOneAndReplaceOptions`
2. Return the document before being updated - you need to set **`ReturnDocument = ReturnDocument.Before`** in the `FindOneAndREplaceOptions` or leave it as is since it's the default value
   {% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://chsakell.gitbook.io/mongodb-csharp-docs/crud-basics/update-documents/replace.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
