我有一个包含数百万Order
个文档的数据库。我用以下方法批量插入它们:
Order.collection.insert([
{:_id=>BSON::ObjectId('5471944843687229cdfb0000'), :status=>"open", :name=> "Benny"},
{:_id=>BSON::ObjectId('5471944843687229cdfc0000'), :status=>"open", :name=> "Allan"}
])
我经常需要更新订单上的status
属性。使用update_attribute
方法单独更新它们会效率低下。
如何批量更新多个MongoDB文档?
所需的解决方案最好用下面的"虚构"代码:
# IMPORTANT: The exemplified upsert method does not exist
Order.collection.upsert([
{:_id=>BSON::ObjectId('5471944843687229cdfb0000'), :status=>"closed"},
{:_id=>BSON::ObjectId('5471944843687229cdfc0000'), :status=>"some_other_status"}
])
Fyi,可能会有类似的问题/答案in this SO post,但老实说,我不会听从答案。
答案 0 :(得分:2)
引用问题中的最佳答案可以简化为
try
{
// ...
var claimsIdentity = (ClaimsIdentity)this.RequestContext.Principal.Identity;
foreach(var claim in claimsIdentity.Claims)
{
// claim.value;
// claim.Type
}
// ...
}
答案 1 :(得分:1)
首先,您需要仅对Orders
的匹配ID进行过滤orders_to_update
。
您可以使用any_in Criteria method过滤它们。然后使用update_all批量更新所有这些内容。
像这样:
orders_to_update = [BSON::ObjectId('5471944843687229cdfb0000'), BSON::ObjectId('5471944843687229cdfc0000')]
Order.any_in(id: orders_to_update).update_all(status: "closed")
答案 2 :(得分:1)
这里真正的问题是更新。更新很慢,因为它需要读取,替换和更改文档。
我已经被同一个问题阻挡了很多天。我在stackoverflow或其他任何网站上都找不到任何解决方案。因此,我写了自己的解决方案。也许你会发现它不是很干净"但是它可以用很好的时间结果。
解决方案包括再次销毁这个文件。 Destroy非常快,并使用批量执行创建新文档" collection.insert"是超级快。
def get_orders(*params)
Order.where(# some conditions).asc(:id)
end
namespace :my_collection_repairer do
desc ""
task update: :environment do
all_orders = get_orders(# some conditions)
while all_orders.count > 0
num_docs = all_orders.count
group_size = 10000
num_groups = (Float(num_docs) / group_size).ceil
puts "#{num_docs} documents found. #{num_groups} groups calculated."
1.upto(num_groups) do |group|
updated_order_list = []
order_group = all_orders.page(group).per(group_size)
puts "group #{group}"
order_group.each do |order|
updated_order = update_order(order) # this represents your custom update method
updated_order_list << updated_order.as_document
order.destroy
end
Order.collection.insert(updated_order_list)
puts "Group #{group} updated."
end
all_orders = get_orders(# some conditions)
end
end
end
答案 3 :(得分:-1)
对于更新或替换操作,将upsert选项设置为true,并具有以下语法:
bulk.find( { status: "closed" } ).update( { $set: { status: "some_other_status" } } );
bulk.execute();
向批量操作列表添加多重更新操作。该方法更新现有文档中的特定字段。
使用 Bulk.find()方法指定确定要更新哪些文档的条件。 Bulk.find.update()方法更新所有匹配的文档。要指定单个文档更新,请参阅 Bulk.find.updateOne()。
var bulk = db.collection.initializeUnorderedBulkOp();
bulk.find( { status: "closed" } ).upsert().update(
{
$set: { status: "some_other_status"}
}
);
bulk.execute();
注意强>:
要为此操作指定upsert:true,请使用 Bulk.find.upsert()。使用 Bulk.find.upsert(),如果没有文档与 Bulk.find()查询条件匹配,则更新操作仅插入单个文档。 希望这会有所帮助。