在没有 for 循环的情况下更新多个文档 MongoDB

Posted

技术标签:

【中文标题】在没有 for 循环的情况下更新多个文档 MongoDB【英文标题】:Update multiple documents without for loop MongoDB 【发布时间】:2021-11-12 21:40:54 【问题描述】:

我想将多个Tags 的给定数组中每个Tag 的标记号加1。

我指定Tag 可能不存在,因此当它不存在时,我需要创建“标签”字段,并为数组中的每个单独标签提供正确的值(此处为json["tags"])。

我想用 MongoDB 在一个查询中执行此操作,如下所示:

tags_collection.update_many(
            
                "tag": "$in": json["tags"],
            ,
            
                "$set": "tag": "<value of the tag found>",
                "$inc": "num": 1
            ,
            upsert=True
        )

我只是想避免带有许多 update_one 的 for 循环,这当然可以工作,但在我的情况下会进行 50 次查询...

编辑

假设我按照评论中的建议将上述查询拆分为 2 个查询:

tags_collection.update_many("tag": "$in": json["tags"], "$inc": "num": 1)

和:

tags_collection.update_many("tag": "$exists": False, "$set": "tag": "<value of the tag found>", upsert=True)

那么问题来了:

我怎么知道&lt;value of the tag found&gt;?换句话说,我如何在一个请求中创建包含第一次查询未更新的所有标签的新文档?

如果可能的话,我想避免先读取数据库,但如果我别无选择,我会这样做。

【问题讨论】:

【参考方案1】:

如果tag 不存在于文档中,则无法对其值进行过滤。 您可以将查询拆分为:

tags_collection.update_many("tag": "$in": json["tags"], "$inc": "num": 1)
tags_collection.update_many("tag": "$exists": False, "$set": "tag": "<value of the tag found>", upsert=True)

观看 mongodb here 上的文档

【讨论】:

感谢您的回答!但是,我如何知道从第一个查询中未更新的标签以设置正确的“”?除了在您的第二个查询中,似乎不需要 update_many ,因为我只能一一做对吗?我需要为每个 Tag 写 1 个文档 我不明白你的第一个问题,你能详细说明第一个查询和第二个查询是什么吗?是的,你可以一个一个地做,但它更喜欢执行一个操作 - 所以组织你想要插入的数组并使用insert_many 我已经编辑了这个问题,如果这足够清楚,请告诉我。第一个和第二个查询实际上是根据您的回答提出的。确实,我正在考虑insert_many,但这需要先读取数据库才能获取现有标签吗?为了organize the array,但我宁愿避免这样做,除非我别无选择 我认为你不能一次完成。是的,你必须阅读你有什么标签,但你可以用一个交易来包装它,这样你就可以确定一切都完成了。 请注意,您始终只有三个查询 - 一个用于读取 (find),一个用于更新现有标签 (update_many),另一个用于插入新标签 (insert_many)。如果你真的坚持,也许你可以找到aggreagte$unwindjson["tags"]的东西

以上是关于在没有 for 循环的情况下更新多个文档 MongoDB的主要内容,如果未能解决你的问题,请参考以下文章

R:在没有预分配的情况下动态更新矩阵时的效率问题

在没有 for 循环的情况下应用用户定义的函数

如何在从列表更新路径的for循环中读取多个json? [复制]

如何使用 C# 驱动程序在 MongoDB 中更新和更新多个文档

如何在 For 循环中为多个类别有条件地更新值

如何在没有 for 循环的情况下生成 n 个随机数