【发布时间】:2011-12-17 14:22:05
【问题描述】:
我正在使用 MongoDB 2,我想更新多个文档并插入一个像 processed:true 这样的值
进入收藏。但是 MongoDB c# api 只允许我们更新多条记录或 Upsert 一条记录。
如何使用 C# api 解决这个问题?
【问题讨论】:
我正在使用 MongoDB 2,我想更新多个文档并插入一个像 processed:true 这样的值
进入收藏。但是 MongoDB c# api 只允许我们更新多条记录或 Upsert 一条记录。
如何使用 C# api 解决这个问题?
【问题讨论】:
你不能在一个声明中做到这一点。
你有两个选择
1) 遍历所有对象并执行 upserts
2) 找出哪些对象需要更新,哪些需要插入,然后进行批量插入和多次更新
【讨论】:
UpdateFlags 是 C# 驱动程序中的一个枚举,可让您同时指定两者。就像任何其他标志枚举一样,您可以通过位“或”来执行此操作。
var flags = UpdateFlags.Upsert | UpdateFlags.Multi;
您可以在此处 (http://msdn.microsoft.com/en-us/library/cc138362.aspx) 阅读有关枚举的文档,特别注意枚举类型作为位标志的部分
【讨论】:
尝试先从集合中删除所有要插入的项目,然后调用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 ");
}
});
})
【讨论】:
在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.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);
【讨论】:
BulkWriteAsync 需要一个 IEnumerable,所以我将其修改为:var models = items.Select(item => new ReplaceOneModel<T>(new ExpressionFilterDefinition<T>(doc => doc.Id == item.Id), item) { IsUpsert = true });
使用 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();
}
【讨论】: