Docs Menu
Docs Home
/ / /
C#/.NET Driver
/ / /

Bulk Write Operations

On this page

  • Overview
  • Sample Data
  • Define the Write Operations
  • Insert Operations
  • Update Operations
  • Replace Operations
  • Delete Operations
  • Perform the Bulk Operation
  • Customize Bulk Write Operations
  • Return Value
  • Handling Exceptions
  • Additional Information

In this guide, you can learn how to use the .NET/C# Driver to perform bulk write operations. By using a bulk write operation, you can perform multiple write operations in fewer calls to the database.

Consider a situation that requires you to insert documents, update documents, and delete documents for the same task. If you use the individual write methods to perform each type of operation, each write accesses the database separately. You can use a bulk write operation to optimize the number of calls your application makes to the server.

You can use the IMongoCollection.BulkWrite() or IMongoCollection.BulkWriteAsync() method to perform bulk write operations on a single collection. Each method takes a list of WriteModel<TDocument> instances that describe the write operations to perform.

The examples in this guide use the sample_restaurants.restaurants collection from the Atlas sample datasets. To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see the Quick Start tutorial.

For each write operation you want to perform, create an instance of one of the following WriteModel<TDocument> classes:

  • DeleteManyModel<TDocument>

  • DeleteOneModel<TDocument>

  • InsertOneModel<TDocument>

  • ReplaceOneModel<TDocument>

  • UpdateManyModel<TDocument>

  • UpdateOneModel<TDocument>

The following sections show how to create and use instances of the preceding classes to perform the corresponding write operation in a bulk write operation.

Tip

Bulk Write Operations with POCOs

The examples in this guide use the BsonDocument type for the TDocument type in all generic classes. You can also use a Plain Old CLR Object (POCO) for these classes. To do so, you must define a class that represents the documents in your collection. The class must have properties that match the fields in your documents. For more information, see POCOs.

To perform an insert operation, create an InsertOneModel<TDocument> instance and specify the document you want to insert.

The following example creates an instance of the InsertOneModel<BsonDocument> class. This instance directs the driver to insert a document in which the "name" field is "Mongo's Deli" into the restaurants collection.

var insertOneModel = new InsertOneModel<BsonDocument>(
new BsonDocument{
{ "name", "Mongo's Deli" },
{ "cuisine", "Sandwiches" },
{ "borough", "Manhattan" },
{ "restaurant_id", "1234" }
}
);

To insert multiple documents, create an instance of InsertOneModel<TDocument> for each document.

Important

Duplicate Key Error

When performing a bulk operation, the InsertOneModel<TDocument> cannot insert a document with an _id that already exists in the collection. In this situation, the driver throws a MongoBulkWriteException.

To update a single document, create an instance of UpdateOneModel<TDocument> and pass the following arguments:

  • Query filter that specifies the criteria used to match documents in your collection. To learn more about specifying a query, see Query and Projection Operators in the MongoDB Server manual.

  • Update document that describes the update to perform. To learn more about specifying an update, see Update Operators in the MongoDB Server manual.

An UpdateOneModel<TDocument> instance specifies an update for the first document that matches your query filter.

In the following code example, the UpdateOneModel<BsonDocument> object represents an update operation on the restaurants collection. The operation matches the first document in the collection where the value of the name field is "Mongo's Deli". It then updates the value of the cuisine field in the matched document to "Sandwiches and Salads".

var updateOneModel = new UpdateOneModel<BsonDocument>(
Builders<BsonDocument>.Filter.Eq("name", "Mongo's Deli"),
Builders<BsonDocument>.Update.Set("cuisine", "Sandwiches and Salads")
);

To update multiple documents, create an instance of UpdateManyModel<TDocument> and pass the same arguments as for UpdateOneModel<TDocument>. The UpdateManyModel<TDocument> class specifies updates for all documents that match your query filter.

In the following code example, the UpdateManyModel<BsonDocument> object represents an update operation on the restaurants collection. The operation matches all documents in the collection where the value of the name field is "Mongo's Deli". It then updates the value of the cuisine field to "Sandwiches and Salads".

var updateManyModel = new UpdateManyModel<BsonDocument>(
Builders<BsonDocument>.Filter.Eq("name", "Mongo's Deli"),
Builders<BsonDocument>.Update.Set("cuisine", "Sandwiches and Salads")
);

A replace operation removes all fields and values of a specified document and replaces them with new fields and values that you specify. To perform a replace operation, create an instance of ReplaceOneModel<TDocument> and pass a query filter and the fields and values you want to replace the matching document with.

In the following example, the ReplaceOneModel<BsonDocument> object represents a replace operation on the restaurants collection. The operation matches the document in the collection where the value of the restaurant_id field is "1234". It then removes all fields other than _id from this document, and sets new values in the name, cuisine, borough, and restaurant_id fields.

var replaceOneModel = new ReplaceOneModel<BsonDocument>(
Builders<BsonDocument>.Filter.Eq("restaurant_id", "1234"),
new BsonDocument{
{ "name", "Mongo's Pizza" },
{ "cuisine", "Pizza" },
{ "borough", "Brooklyn" },
{ "restaurant_id", "5678" }
}
);

To replace multiple documents, you must create an instance of ReplaceOneModel<TDocument> for each document.

To delete a document, create an instance of DeleteOneModel<TDocument> and pass a query filter specifying the document you want to delete. A DeleteOneModel<TDocument> instance provides instructions to delete only the first document that matches your query filter.

In the following code example, the DeleteOneModel<BsonDocument> object represents a delete operation on the restaurants collection. The operation matches and deletes the first document where the value of the restaurant_id field is "5678".

var deleteOneModel = new DeleteOneModel<BsonDocument>(
Builders<BsonDocument>.Filter.Eq("restaurant_id", "5678")
);

To delete multiple documents, create an instance of DeleteManyModel<TDocument> and pass a query filter specifying the documents you want to delete. An instance of DeleteManyModel<TDocument> provides instructions to remove all documents that match your query filter.

In the following code example, the DeleteManyModel<BsonDocument> object represents a delete operation on the restaurants collection. The operation matches and deletes all documents where the value of the name field is "Mongo's Deli".

var deleteManyModel = new DeleteManyModel<BsonDocument>(
Builders<BsonDocument>.Filter.Eq("name", "Mongo's Deli")
);

After you define a WriteModel instance for each operation that you want to perform, create an instance of a class that implements the IEnumerable interface. Add your WriteModel objects to this IEnumerable, then pass the IEnumerable to the BulkWrite() or BulkWriteAsync() method. By default, these methods run the operations in the order they're defined in the list.

Tip

IEnumerable

Array and List are two common classes that implement the IEnumerable interface.

Select from the following tabs to view how to use the synchronous BulkWrite() method and the asynchronous BulkWriteAsync() method to perform a bulk write operation on the restaurants collection:

var models = new List<WriteModel<BsonDocument>>
{
new InsertOneModel<BsonDocument>(
new BsonDocument{
{ "name", "Mongo's Deli" },
{ "cuisine", "Sandwiches" },
{ "borough", "Manhattan" },
{ "restaurant_id", "1234" }
}
),
new InsertOneModel<BsonDocument>(
new BsonDocument{
{ "name", "Mongo's Deli" },
{ "cuisine", "Sandwiches" },
{ "borough", "Brooklyn" },
{ "restaurant_id", "5678" }
}
),
new UpdateManyModel<BsonDocument>(
Builders<BsonDocument>.Filter.Eq("name", "Mongo's Deli"),
Builders<BsonDocument>.Update.Set("cuisine", "Sandwiches and Salads")
),
new DeleteOneModel<BsonDocument>(
Builders<BsonDocument>.Filter.Eq("restaurant_id", "1234")
)
};
var results = collection.BulkWrite(models);
Console.WriteLine(results);
var models = new List<WriteModel<BsonDocument>>
{
new InsertOneModel<BsonDocument>(
new BsonDocument{
{ "name", "Mongo's Deli" },
{ "cuisine", "Sandwiches" },
{ "borough", "Manhattan" },
{ "restaurant_id", "1234" }
}
),
new InsertOneModel<BsonDocument>(
new BsonDocument{
{ "name", "Mongo's Deli" },
{ "cuisine", "Sandwiches" },
{ "borough", "Brooklyn" },
{ "restaurant_id", "5678" }
}
),
new UpdateManyModel<BsonDocument>(
Builders<BsonDocument>.Filter.Eq("name", "Mongo's Deli"),
Builders<BsonDocument>.Update.Set("cuisine", "Sandwiches and Salads")
),
new DeleteOneModel<BsonDocument>(
Builders<BsonDocument>.Filter.Eq("restaurant_id", "1234")
)
};
var results = await collection.BulkWriteAsync(models);
Console.WriteLine(results);

The preceding code examples produce the following output:

MongoDB.Driver.BulkWriteResult1+Acknowledged[MongoDB.Bson.BsonDocument]

Note

When the driver runs a bulk operation, it uses the write concern of the target collection. The driver reports all write concern errors after attempting all operations, regardless of execution order.

When you call the BulkWrite() or BulkWriteAsync() method, you can pass an instance of the BulkWriteOptions class. The BulkWriteOptions class contains the following properties, which represent options you can use to configure the bulk write operation:

Property
Description

BypassDocumentValidation

Specifies whether the operation bypasses document-level validation. For more information, see Schema Validation in the MongoDB Server manual.
Defaults to False.

Comment

A comment to attach to the operation, in the form of a BsonValue. For more information, see the delete command fields guide in the MongoDB Server manual.

IsOrdered

If True, the driver performs the write operations in the order provided. If an error occurs, the remaining operations are not attempted.

If False, the driver performs the operations in an arbitrary order and attempts to perform all operations. If any of the write operations in an unordered bulk write fail, the driver reports the errors only after attempting all operations.
Defaults to True.

Let

A map of parameter names and values, in the form of a BsonDocument. Values must be constant or closed expressions that don't reference document fields. For more information, see the let statement in the MongoDB Server manual.

The following code examples use a BulkWriteOptions object to perform an unordered bulk write operation:

var models = new List<WriteModel<BsonDocument>>
{
new DeleteOneModel<BsonDocument>(
Builders<BsonDocument>.Filter.Eq("restaurant_id", "5678")
)
};
var options = new BulkWriteOptions
{
IsOrdered = false,
};
collection.BulkWrite(models, options);
var models = new List<WriteModel<BsonDocument>>
{
new DeleteOneModel<BsonDocument>(
Builders<BsonDocument>.Filter.Eq("restaurant_id", "5678")
)
};
var options = new BulkWriteOptions
{
IsOrdered = false,
};
await collection.BulkWriteAsync(models, options);

The BulkWrite() and BulkWriteAsync() methods return a BulkWriteResult object that contains the following properties:

Property
Description

IsAcknowledged

Indicates whether the server acknowledged the bulk write operation. If the value of this property is False and you try to access any other property of the BulkWriteResult object, the driver throws an exception.

DeletedCount

The number of documents deleted, if any.

InsertedCount

The number of documents inserted, if any.

MatchedCount

The number of documents matched for an update, if applicable.

ModifiedCount

The number of documents modified, if any.

IsModifiedCountAvailable

Indicates whether the modified count is available.

Upserts

A list that contains information about each request that resulted in an upsert operation.

RequestCount

The number of requests in the bulk operation.

If any of the operations in a bulk write operation fail, the .NET/C# Driver throws a BulkWriteError and does not perform any further operations.

A BulkWriteError object contains the Index property that describes the index of the request that resulted in an error.

To learn how to perform individual write operations, see the following guides:

To learn more about any of the methods or types discussed in this guide, see the following API documentation:

Back

Delete