You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在pymongo中实现字典列表类型字段的更新或新增操作

实现方案

你可以通过MongoDB 4.2+支持的更新聚合管道实现原子操作,无需先查询再修改,能避免并发冲突,完全适配你给出的场景。


前置说明

默认你的test_field数组中每个元素都是单key字典,输入的待操作字典也为单key结构,和示例一致。
我们假设待操作目标文档的_id为1,待写入的字典为input_dict。


方法1:原子更新聚合管道(推荐)

MongoDB Shell 示例

// 定义待操作的字典
const inputDict = { "key1": "test_value" };
const inputKey = Object.keys(inputDict)[0];

db.collection.updateOne(
  { _id: 1 },
  [
    {
      $set: {
        test_field: {
          $cond: {
            // 第一步:判断test_field中是否已存在对应key
            if: {
              $in: [
                inputKey,
                { $map: { input: "$test_field", in: { $first: { $objectToArray: "$$this" } }.k } }
              ]
            },
            // 存在则遍历数组,更新对应key的字典
            then: {
              $map: {
                input: "$test_field",
                in: {
                  $cond: {
                    if: { $eq: [{ $first: { $objectToArray: "$$this" } }.k, inputKey] },
                    then: inputDict,
                    else: "$$this"
                  }
                }
              }
            },
            // 不存在则追加新字典到数组末尾
            else: { $concatArrays: [ "$test_field", [ inputDict ] ] }
          }
        }
      }
    }
  ]
)

Python PyMongo 示例

from pymongo import MongoClient

client = MongoClient("mongodb://localhost:27017/")
db = client.test_database
col = db.test_collection

# 定义待操作的字典
input_dict = {"test_key": "test_value2"}
input_key = next(iter(input_dict.keys()))

col.update_one(
    {"_id": 1},
    [
        {
            "$set": {
                "test_field": {
                    "$cond": {
                        "if": {
                            "$in": [
                                input_key,
                                {"$map": {
                                    "input": "$test_field",
                                    "in": {"$first": {"$objectToArray": "$$this"}}["k"]
                                }}
                            ]
                        },
                        "then": {
                            "$map": {
                                "input": "$test_field",
                                "in": {
                                    "$cond": {
                                        "if": {"$eq": [{"$first": {"$objectToArray": "$$this"}}["k"], input_key]},
                                        "then": input_dict,
                                        "else": "$$this"
                                    }
                                }
                            }
                        },
                        "else": {"$concatArrays": ["$test_field", [input_dict]]}
                    }
                }
            }
        }
    ]
)

方法2:低版本MongoDB兼容方案(先查后改)

如果你的MongoDB版本低于4.2,不支持更新聚合管道,可以用先查询后修改的方式实现,注意如果有并发修改需求,需要加乐观锁或者事务保证数据一致性:

# 查询目标文档
doc = col.find_one({"_id": 1}, {"test_field": 1})
input_dict = {"key1": "test_value"}
input_key = next(iter(input_dict.keys()))

new_test_field = []
key_existed = False
for item in doc["test_field"]:
    item_key = next(iter(item.keys()))
    if item_key == input_key:
        new_test_field.append(input_dict)
        key_existed = True
    else:
        new_test_field.append(item)
#  key不存在则追加
if not key_existed:
    new_test_field.append(input_dict)

# 写回数据库
col.update_one({"_id": 1}, {"$set": {"test_field": new_test_field}})

内容的提问来源于stack exchange,提问作者Ratery

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 21:18:02