MongoDB :更新集合的所有文档中的特定字段,给定一个具有目标字段和新值的特定数组

时间:2021-03-05 17:27:01

标签: mongodb

对 MongoDB 相当陌生,我正在搜索用于更新创建的集合的命令,例如:

db.students.insertMany([
   { "_id": 1, "fld1": "11", "fld2": "12", "fld3": "13" },
   { "_id": 2, "fld1": "21", "fld2": "22", "fld3": "23" },
   { "_id": 3, "fld1": "31", "fld2": "32", "fld3": "33" }
])

updated with : 
[
  { "fld1": "11-new" }, { "fld1": "21-new" }, {"fld1": "31-new" }
]

giving the result: 
[
   { "_id": 1, "fld1": "11-new", "fld2": "12", "fld3": "13" },
   { "_id": 2, "fld1": "21-new", "fld2": "22", "fld3": "23" },
   { "_id": 3, "fld1": "31-new", "fld2": "32", "fld3": "33" }
]

我似乎在 MongoDB 文档中找不到这种确切的更新类型。
db.collection.findAndModify ? db.collection.update() db.collection.updateMany() ?

这会被视为批量操作吗?
提供一个

[
{updateOne:{"filter":{"_id":1},"update":{$set:{"fld1":"11-new"}}},
{updateOne:{"filter":{"_id":2},"update":{$set:{"fld1":"21-new"}}},
{updateOne:{"filter":{"_id":3},"update":{$set:{"fld1":"31-new"}}}
]

让我测试一下。任何其他更简单的方法来实现这一目标?谢谢

1 个答案:

答案 0 :(得分:0)

由于您尝试使用不同的 _id 更新多个文档,我建议您使用 bulkWrite() 函数,该函数将要执行的操作列表作为参数集合。

在这种情况下,所有操作都是 updateOne 查询,您必须为其指定 filter 以标识相关文档,并且必须指定 update对该文档执行。

您可以在 Mongo Shell 中发送此命令,如下所示:

try {
    db.students.bulkWrite([
        { 
            updateOne : {
                "filter": {"_id": "1"}, 
                "update": {"$set":{"fld1":"11-new"}}
            }
         },
         { 
            updateOne : {
                "filter": {"_id": "2"}, 
                "update": {"$set":{"fld1":"21-new"}}
            }
         },
         { 
            updateOne : {
                "filter": {"_id": "3"}, 
                "update": {"$set":{"fld1":"31-new"}}
            }
         }
    ]);
}
catch(e) { print(e); }

如果您不关心操作的执行顺序,您还可以将可选参数 ordered 传递给函数并将其设置为 false,这样可以加快执行时间。

{ ordered : false }

脚本选项

答案的第二部分可能与您的情况无关,但是如果要执行的操作数量非常多(例如您必须更改数百个文档的字段,手动编写所有操作将令人难以置信昂贵。在这种情况下,脚本可能适合您。

这是一个 Python 示例,它执行以下操作:

  • 连接到 mongo 数据库并提取 students 集合,
  • 定义了一个函数,它带有两个参数:fieldnew_values,表示要更新的字段和要为该字段设置的新值的有序列表。
  • 该函数收集集合中当前存在的所有 _ids,并通过遍历 ID 和新值来构建 operations 列表。
  • 最后发送bulkwrite查询,返回一个总结所执行操作的结果对象。

from pymongo import MongoClient, UpdateOne
client = MongoClient(your_host)
db = client["database_name"]
students = db["students"]
    
def updateCollection(field, new_values):
        
    operations = [] 
    _ids = students.distinct("_id")
    
    for _id, new_value in zip(_ids, new_values):
        operations.append(UpdateOne({"_id": _id}, {"$set":{field : new_value}}))
    
    return students.bulk_write(operations, ordered=False)

按照您自己的示例,该函数的调用方式如下:

updateCollection("fld1", ["11-new", "21-new", "31-new"])
相关问题