MongoDB(Java):多个文档的高效更新至不同值。

huangapple 未分类评论50阅读模式
英文:

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>



huangapple
  • 本文由 发表于 2020年4月5日 01:02:17
  • 转载请务必保留本文链接:https://java.coder-hub.com/61031643.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定