英文:
MongoDB (Java): efficient update of multiple documents to different(!) values
问题
我有一个MongoDB数据库,我正在编写的程序旨在更改集合中所有文档的单个字段的值。现在,如果我想让它们都更改为单个值,比如字符串值"mask",那么我知道updateMany
可以完成这个任务,并且它非常高效。
但是,我想要的是一种高效的解决方案,用于更新不同的新值,实际上,我想要从列表中为该字段的每个文档选择要更新的新值,例如一个ArrayList。但是,像这样的东西:
collection.updateMany(new BasicDBObject(),
new BasicDBObject("$set", new BasicDBObject(fieldName,
listOfMasks.get(random.nextInt(size)))));
这样不会起作用,因为updateMany
不会重新计算字段应该设置为的值,它只计算参数
listOfMasks.get(random.nextInt(size))
一次,然后将其用于所有文档。所以我认为没有办法实际使用updateMany
来解决这个问题,因为它的灵活性不够。
但我想知道是否有人对至少使它比简单地遍历所有文档并每次使用updateOne
更新为来自ArrayList的新值(以随机顺序,但这只是一个细节)的想法有任何想法?
// 循环直到MongoCursor为空(直到搜索完成)
try {
while (cursor.hasNext()) {
// 选择一个随机的mask
String mask = listOfMasks.get(random.nextInt(size));
// 更新此文档
collection.updateOne(cursor.next(), Updates.set("test_field", mask));
}
} finally {
cursor.close();
}
英文:
I have a MongoDB database and the program I'm writing is meant to change the values of a single field for all documents in a collection. Now if I want them all to change to a single value, like the string value "mask", then I know that updateMany
does the trick and it's quite efficient.
However, what I want is an efficient solution for updating to different new values, in fact I want to pick the new value for the field in question for each document from a list, e.g. an ArrayList. But then something like this
collection.updateMany(new BasicDBObject(),
new BasicDBObject("$set",new BasicDBObject(fieldName,
listOfMasks.get(random.nextInt(size)))));
wouldn't work since updateMany
doesn't recompute the value that the field should be set to, it just computes what the argument
listOfMasks.get(random.nextInt(size))
would be once and then it uses that for all the documents. So I don't think there's a solution to this problem that can actually employ updateMany
since it's simply not versatile enough.
But I was wondering if anyone has any ideas for at least making it faster than simply iterating through all the documents and each time do updateOne
where it updates to a new value from the ArrayList (in a random order but that's just a detail), like below?
// Loop until the MongoCursor is empty (until the search is complete)
try {
while (cursor.hasNext()) {
// Pick a random mask
String mask = listOfMasks.get(random.nextInt(size));
// Update this document
collection.updateOne(cursor.next(), Updates.set("test_field", mask));
}
} finally {
cursor.close();
}```
</details>
# 答案1
**得分**: 0
MongoDB提供了批量写入API,用于批量更新。这对于你的示例很合适,例如针对每个文档将字段的值设置为随机值(在客户端上确定)。
或者,如果对所需更改有模式,你可以考虑使用[查找和修改操作](https://docs.mongodb.com/manual/reference/method/db.collection.findAndModify/)以及可用的[更新运算符](https://docs.mongodb.com/manual/reference/operator/update/#id1)。
<details>
<summary>英文:</summary>
MongoDB provides the [bulk write API](https://stackoverflow.com/questions/35846474/how-to-perform-a-bulk-update-of-documents-in-mongodb-with-java) to batch updates. This would be appropriate for your example of setting the value of a field to a random value (determined on the client) for each document.
Alternatively if there is a pattern to the changes needed you could potentially use [find and modify operation](https://docs.mongodb.com/manual/reference/method/db.collection.findAndModify/) with the available [update operators](https://docs.mongodb.com/manual/reference/operator/update/#id1).
</details>
专注分享java语言的经验与见解,让所有开发者获益!
评论