【问题标题】:Is it possible to utilize $addToSet multiple times in the same update?是否可以在同一更新中多次使用 $addToSet ?
【发布时间】:2013-05-18 12:46:00
【问题描述】:

所以我希望我的集合中的文档在结构上看起来像这样:

{
    "_id": "123",
    "systems": [
        {
            "_id": "1338",
            "metrics": [
                "TEST"
            ]
        }
    ]
}

我的目标是能够对系统和/或指标在其各自的数组中存在/不存在的任何实例进行一次更新/插入(使用 upsert=True)。目前我唯一的解决方法是按如下方式更新调用:

if not collection.find_one({"_id": "123", "systems._id": "1338"}):
    collection.update(
        {"_id": "123"}, 
        {"$addToSet": {"systems": {"_id": "1338"}}}, 
        upsert=True)
collection.update(
    {"_id": "123", "systems._id": "1338"}, 
    {"$addToSet": {"systems.$.metrics": "TEST"}}, 
    upsert=True)

谢谢

【问题讨论】:

    标签: python mongodb sql-update pymongo


    【解决方案1】:

    cannot apply the positional operator without a corresponding query field containing an array,但您需要位置运算符知道系统数组中 $addToSet {"metrics": ["TEST"]} 的索引。您也不能基于{"systems._id": "1338"} 进行查询,因为该字段可能在文档{"_id": "123"} 中尚不存在。因此,如果我们不能组合多个涉及相同字段的操作,则不可能在单个请求中完成,但我们不能have conflicting mods in update

    最后的希望是如果我们在 update document 语法中有类似于 $where operator 的东西,以允许我们执行任意 JavaScript 来更新文档。我怀疑我们没有(也不会)有这个。

    主要问题是systems 字段上的数组索引。您可以使用 _id 属性作为新索引来重新设计架构以摆脱此索引:

    {
        "_id": "123",
        "systems": {
            "1338": {
                "metrics": [
                    "TEST"
                ]
            }
        }
    }
    

    通过这一更改,您可以在一个操作中完成所有操作:

    db.test.update({_id: "123"}, {$addToSet: {"systems.1338.metrics": "TEST"}}, {upsert: true})
    

    另一种选择是使用以下设计:

    {
        "_id": "123",
        "systems": {
            "metrics": {
                "1338": [
                    "TEST"
                ]
            }
        }
    }
    

    最好的设计取决于你打算做什么。

    编辑:

    您还可以选择在应用程序中本地更新文档,然后将其发送回数据库,但此选项可能无法提供我认为您想要的那种原子性。

    关于您当前的解决方法:您不需要if。您可以按顺序运行这两个查询。但是,如果您有多个客户端访问您的数据库,这是不安全的。

    【讨论】:

      猜你喜欢
      • 2021-06-11
      • 2012-09-24
      • 1970-01-01
      • 2015-07-07
      • 2018-10-31
      • 1970-01-01
      • 2017-10-21
      • 2017-05-27
      • 1970-01-01
      相关资源
      最近更新 更多