如何使用 C# 驱动程序在 MongoDB 中更新和更新多个文档
Posted
技术标签:
【中文标题】如何使用 C# 驱动程序在 MongoDB 中更新和更新多个文档【英文标题】:How to update and upsert multiple documents in MongoDB using C# Drivers 【发布时间】:2011-12-17 14:22:05 【问题描述】:我正在使用 MongoDB 2,我想更新多个文档并插入一个像 processed:true
这样的值
进入收藏。但是 MongoDB c# api 只允许我们更新多条记录或 Upsert 一条记录。
如何使用 C# api 解决这个问题?
【问题讨论】:
C# mongodb driver 2.0 - How to upsert in a bulk operation?的可能重复 【参考方案1】:你不能在一个声明中做到这一点。
你有两个选择
1) 遍历所有对象并执行 upserts
2) 找出哪些对象需要更新,哪些需要插入,然后进行批量插入和多次更新
【讨论】:
【参考方案2】:UpdateFlags 是 C# 驱动程序中的一个枚举,可让您同时指定两者。就像任何其他标志枚举一样,您可以通过位“或”来执行此操作。
var flags = UpdateFlags.Upsert | UpdateFlags.Multi;
您可以在此处 (http://msdn.microsoft.com/en-us/library/cc138362.aspx) 阅读有关枚举的文档,特别注意枚举类型作为位标志的部分
【讨论】:
【参考方案3】:尝试先从集合中删除所有要插入的项目,然后调用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 ");
);
)
【讨论】:
这样做的一个问题是读取集合的客户端可能会在操作期间看到丢失的对象。如果您的客户可以容忍这一点,那么这似乎是一种合理的方法。【参考方案4】:在Mongo 2.6
之后,您可以批量处理Updates/Upserts。下面的示例使用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();
【讨论】:
我们的开发团队使用 -MongoDB 3.0.0 和 -MongoDB C# Driver Version 1.7.0.4714。 MongoDB C# 驱动程序版本 1.7.0.4714 抱怨 InitializeUnorderedBulkOperation() 未定义。 虽然这是公认的答案,但它已经过时了。见***.com/questions/35687470/…【参考方案5】:对于那些使用MongoDB.Driver 2.0 版的用户,您可以使用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);
【讨论】:
这对我有帮助。非常感谢。在我的情况下,我得到一个 IEnumerable 作为要插入的项目。BulkWriteAsync
需要一个 IEnumerable,所以我将其修改为:var models = items.Select(item => new ReplaceOneModel<T>(new ExpressionFilterDefinition<T>(doc => doc.Id == item.Id), item) IsUpsert = true );
【参考方案6】:
使用 mongoose@5.9.9 - 尝试 initializeUnorderedBulkOp():
export const InfoFunc = (Infos: Infos[]) =>
const bulk = InfoResult.collection.initializeUnorderedBulkOp();
Infos.forEach((info: Infos) => bulk.find( "Id": info.Id).upsert().updateOne(info));
bulk.execute();
【讨论】:
以上是关于如何使用 C# 驱动程序在 MongoDB 中更新和更新多个文档的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 C# 驱动程序更新 MongoDB 数组中的子文档
如何使用 C# mongodb 驱动程序防止 SQL 注入?
如何在 MongoDB C# 驱动程序版本 2 中使用 $ 位置运算符