卓越飞翔博客卓越飞翔博客

卓越飞翔 - 您值得收藏的技术分享站
技术文章35702本站已运行399

如何在一个查询中根据 Mongo 中的不同键更新多条记录?

如何在一个查询中根据 mongo 中的不同键更新多条记录?

在使用MongoDB时,有时我们需要根据不同的键来更新多条记录,这个问题可能会让人感到困惑。不过,幸好在MongoDB中,我们可以使用Bulk Write操作来实现这个目标。Bulk Write是一种批量写入操作,可以在单个操作中执行多个更新、插入或删除操作。在这篇文章中,我将向大家介绍如何使用Bulk Write来根据Mongo中的不同键更新多条记录。

问题内容

如果我有类似于以下内容的内容...

collection.insertmany(context.todo(), []interface{}{
   bson.m{ "_id" : 1, "member" : "abc123", "status" : "p" },
   bson.m{ "_id" : 2, "member" : "xyz123", "status" : "a" },
   bson.m{ "_id" : 3, "member" : "lmn123", "status" : "p" },
   bson.m{ "_id" : 4, "member" : "pqr123", "status" : "d" },
   bson.m{ "_id" : 5, "member" : "ijk123", "status" : "p" },
   bson.m{ "_id" : 6, "member" : "cde123", "status" : "a" },
} )

是否可以在一个 insertmany 查询中应用以下更新?

[{"_id" : "1", "status" : "P0-A0"},
 {"_id" : "2", "status" : "P0-A1"},
 {"_id" : "3", "status" : "P0-A2"},
 {"_id" : "4", "status" : "P0-A3"},
 {"_id" : "5", "status" : "P0-A4"},
 {"_id" : "6", "status" : "P0-A5"}]

如果是这样,用 golang 会如何完成?

具体来说,使用 collection.updatemany(context.todo(), filter, update),我的 filterupdate 会有什么?

感谢您的帮助。

解决方法

你不能用一个来做到这一点collection.updatemany() 调用,因为您无法对不同的匹配文档应用不同的更新文档。您必须多次调用 collection.updatemany(),每个不同的更新文档一次。

如果您想通过一次调用高效地完成此操作,您可以使用 collection.bulkwrite()。您必须准备一个不同的 mongo.writemodel每个文档更新。

它可能是这样的:

wm := []mongo.writemodel{
    mongo.newupdateonemodel().setfilter(bson.m{"_id": "1"}).setupdate(bson.m{"$set": bson.m{"status": "p0-a0"}}),
    mongo.newupdateonemodel().setfilter(bson.m{"_id": "2"}).setupdate(bson.m{"$set": bson.m{"status": "p0-a1"}}),
    mongo.newupdateonemodel().setfilter(bson.m{"_id": "3"}).setupdate(bson.m{"$set": bson.m{"status": "p0-a2"}}),
    mongo.newupdateonemodel().setfilter(bson.m{"_id": "4"}).setupdate(bson.m{"$set": bson.m{"status": "p0-a3"}}),
    mongo.newupdateonemodel().setfilter(bson.m{"_id": "5"}).setupdate(bson.m{"$set": bson.m{"status": "p0-a4"}}),
    mongo.newupdateonemodel().setfilter(bson.m{"_id": "6"}).setupdate(bson.m{"$set": bson.m{"status": "p0-a5"}}),
}

上面的切片文字中有太多“重复”,您可以使用辅助函数捕获它们:

create := func(id, newstatus string) *mongo.updateonemodel {
    return mongo.newupdateonemodel().
        setfilter(bson.m{"_id": id}).
        setupdate(bson.m{"$set": bson.m{"status": newstatus}})
}

wm := []mongo.writemodel{
    create("1", "p0-a0"),
    create("2", "p0-a1"),
    create("3", "p0-a2"),
    create("4", "p0-a3"),
    create("5", "p0-a4"),
    create("6", "p0-a5"),
}

此外,如果更新中有可以轻松定义的逻辑,请使用循环而不是列出所有元素:

var wm []mongo.writemodel
for i := 1; i <= 6; i++ {
    newstatus := fmt.sprintf("p0-a%d", i-1)
    wm = append(wm, mongo.newupdateonemodel().
        setfilter(bson.m{"_id": strconv.itoa(i)}).
        setupdate(bson.m{"$set": bson.m{"status": newstatus}}),
    )
}

您可以通过一次调用执行所有更新,如下所示:

res, err := coll.BulkWrite(ctx, wm)

查看相关内容:mongodb 更新文档数组并替换为替换文档数组

卓越飞翔博客
上一篇: 文件系统中的两个文件夹作为站点地址(Go 中的 Web 服务器)路径中的一个虚拟文件夹
下一篇: 返回列表
留言与评论(共有 0 条评论)
   
验证码:
隐藏边栏