我正在使用MongoDB 2,并且希望更新多个文档并将值 processed:true
插入到集合中。但是MongoDB的C# API只允许我们更新多个记录或插入单个记录。
如何使用C# API解决这个问题?
Mongo 2.6
版本后,您可以使用批量更新/插入操作。以下示例使用c#
驱动程序执行批量更新。
MongoCollection<foo> collection = database.GetCollection<foo>(collectionName);
var bulk = collection.InitializeUnorderedBulkOperation();
foreach (FooDoc fooDoc in fooDocsList)
{
var update = new UpdateDocument { {fooDoc.ToBsonDocument() } };
bulk.Find(Query.EQ("_id", fooDoc.Id)).Upsert().UpdateOne(update);
}
BulkWriteResult bwr = bulk.Execute();
无法仅使用一个语句完成。
您有两个选择:
1)循环所有对象并执行upserts操作
2)找出需要更新的对象和需要插入的对象,然后执行批量插入和多重更新操作
如果您使用的是版本2.0的MongoDB.Driver,您可以使用BulkWriteAsync方法。
<!-- language: c# -->
// our example list
List<Products> products = GetProductsFromSomewhere();
var collection = YourDatabase.GetCollection<BsonDocument>("products");
// initialise write model to hold list of our upsert tasks
var models = new WriteModel<BsonDocument>[products.Count];
// use ReplaceOneModel with property IsUpsert set to true to upsert whole documents
for (var i = 0; i < products.Count; i++){
var bsonDoc = products[i].ToBsonDocument();
models[i] = new ReplaceOneModel<BsonDocument>(new BsonDocument("aw_product_id", products[i].aw_product_id), bsonDoc) { IsUpsert = true };
};
await collection.BulkWriteAsync(models);
var models = items.Select(item => new ReplaceOneModel<T>(new ExpressionFilterDefinition<T>(doc => doc.Id == item.Id), item) { IsUpsert = true });
- F. Fix首先从集合中移除所有要插入的项,然后调用insert方法:
var search = [];
arrayToInsert.forEach(function(v, k) {
search.push(v.hash); // my unique key is hash. you could use _id or whatever
})
collection.remove({
'hash' : {
$in : search
}
}, function(e, docs) {
collection.insert(arrayToInsert, function(e, docs) {
if (e) {
console.log("data failed to update ", e);
}
else {
console.log("data updated ");
}
});
})
UpdateFlags 是 C# 驱动程序中的枚举,它可以让您同时指定两个选项。就像任何其他标志枚举一样,您可以通过按位“或”来实现。
var flags = UpdateFlags.Upsert | UpdateFlags.Multi;
您可以在此处阅读有关枚举的文档(http://msdn.microsoft.com/zh-cn/library/cc138362.aspx),特别注意枚举类型作为位标志的部分。
public interface IProjection
{
Guid Id { get; }
bool IsDeleted { get; }
}
public async Task UpsertManyAsync<TProjection>(IEnumerable<TProjection> replacements, CancellationToken cancellationToken)
where TProjection : IProjection
{
var requests = replacements.Select(replacement => new ReplaceOneModel<TProjection>(
filter: new ExpressionFilterDefinition<TProjection>(projection => projection.Id == replacement.Id),
replacement: replacement) { IsUpsert = true });
await _context
.GetCollection<TProjection>()
.BulkWriteAsync(
requests: requests,
options: new BulkWriteOptions { IsOrdered = false },
cancellationToken: cancellationToken);
}
使用mongoose@5.9.9 - 尝试初始化UnorderedBulkOp():
export const InfoFunc = (Infos: Infos[]) => {
const bulk = InfoResult.collection.initializeUnorderedBulkOp();
Infos.forEach((info: Infos) => bulk.find({ "Id": info.Id}).upsert().updateOne(info));
bulk.execute();
}