I migrated from 1.9 to 2.2 and reading the documentation I was surprised to discover that is not possible to upsert during a bulk operation anymore, since operations don't allow options.
bulkOps.Add(new UpdateOneModel<BsonDocument>(filter, update));
collection.BulkWrite(bulkOps);
Should be
options.isUpsert = true;
bulkOps.Add(new UpdateOneModel<BsonDocument>(filter, update, options));
collection.BulkWrite(bulkOps);
Is this work in progress, intended, or I'm missing something? Thank you.
In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.
" " C is a computer programming language. That means that you can use C to create lists of instructions for a computer to follow. C is one of thousands of programming languages currently in use.
C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...
C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.
Set the IsUpsert
property of the UpdateOneModel
to true to turn the update into an upsert.
var bulkOps = new List<WriteModel<BsonDocument>>();
// Create and add one or more write models to list
var upsertOne = new UpdateOneModel<BsonDocument>(filter, update) { IsUpsert = true };
bulkOps.Add(upsertOne);
// Write all changes as a batch
collection.BulkWrite(bulkOps);
given mongo collection
IMongoCollection<T> collection
and enumerable of records to insert where T has Id field.
IEnumerable<T> records
this snippet will do a bulk upsert (the filter condition may be changed according to the situation):
var bulkOps = new List<WriteModel<T>>();
foreach (var record in records)
{
var upsertOne = new ReplaceOneModel<T>(
Builders<T>.Filter.Where(x => x.Id == record.Id),
record)
{ IsUpsert = true };
bulkOps.Add(upsertOne);
}
collection.BulkWrite(bulkOps);
Here is an extension method based on @Aviko response
public static BulkWriteResult<T> BulkUpsert<T>(this IMongoCollection<T> collection, IEnumerable<T> records)
{
string keyname = "_id";
#region Get Primary Key Name
PropertyInfo[] props = typeof(T).GetProperties();
foreach (PropertyInfo prop in props)
{
object[] attrs = prop.GetCustomAttributes(true);
foreach (object attr in attrs)
{
BsonIdAttribute authAttr = attr as BsonIdAttribute;
if (authAttr != null)
{
keyname = prop.Name;
}
}
}
#endregion
var bulkOps = new List<WriteModel<T>>();
foreach (var entry in records)
{
var filter = Builders<T>.Filter.Eq(keyname, entry.GetType().GetProperty(keyname).GetValue(entry, null));
var upsertOne = new ReplaceOneModel<T>(filter, entry){ IsUpsert = true };
bulkOps.Add(upsertOne);
}
return collection.BulkWrite(bulkOps);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With