MongoDB 字段必须是数组

MongoDB field must be an array

目前我有一个 collection 包含以下文件:

[
    {
        "_id": ObjectId("628e6bd640643f97d6517c75"),
        "company": "bau",
        "current_version": 0,
        "form_name": "don't know",
        "history": [],
        "id": "23421123-24a9-4a45-a12f-27a330152ax3",
        "is_active": True,
        "user_id": "999",
    },
    {
        "_id": ObjectId("628eaffe4b8ae2ccdeb9305c"),
        "company": "vrau",
        "current_version": 0,
        "form_name": "exemplo",
        "history": [
            {
                "content": [
                    {
                        "field_id": 0,
                        "label": "insira um texto",
                        "placeholder": "qualquer texto",
                        "type": "text",
                    }
                ],
                "layout": [
                    {"field_id": 0, "h": 10, "type": "text", "w": 100, "x": 0, "y": 0}
                ],
                "responses": [
                    {
                        "client_id": 100,
                        "response_date": "2020-01-02",
                        "values": [{"field_id": 0, "value": "um texto"}],
                    },
                    {
                        "client_id": 2,
                        "response_date": "2020-01-01",
                        "values": [{"field_id": 0, "value": "roi"}],
                    },
                ],
                "version": 0,
            }
        ],
        "id": "33b66684-24a9-4a45-a12f-27a330152ac8",
        "is_active": True,
        "user_id": "1",
    },
]

我想更改来自 client_id = '2' 的响应,因为我收到以下错误:

pymongo.errors.WriteError: The field 'history.0.responses.1' must be an array but is of type object in document {_id: ObjectId('628eaffe4b8ae2ccdeb9305c')}, full error: {'index': 0, 'code': 2, 'errmsg': "The field 'history.0.responses.1' must be an array but is of type object in document {_id: ObjectId('628eaffe4b8ae2ccdeb9305c')}"}

我不知道我做错了什么,这个错误对我来说没有意义,因为响应是一个数组。

我当前的查询:

collection.update_many(
    {"id": "33b66684-24a9-4a45-a12f-27a330152ac8", "history.version": 0},
    {
        "$push": {
            "history.$[h].responses.$[r]": {
                "client_id": 2,
                "response_date": "2020-01-01",
                "values": [{"field_id": 0, "value": "roi"}],
            }
        }
    },
    array_filters=[{"h.version": 0}, {"r.client_id": "2"}],
)

还有别的吗?

这是因为您还在 r 上执行过滤,它已经解析到 responses 数组中的对象级别。

如果你只想推送到 responses 数组,你可以简单地放弃 r arrayFilter。

collection.update_many(
    {"id": "33b66684-24a9-4a45-a12f-27a330152ac8", "history.version": 0},
    {
        "$push": {
            "history.$[h].responses": {
                "client_id": 2,
                "response_date": "2020-01-01",
                "values": [{"field_id": 0, "value": "roi"}],
            }
        }
    },
    array_filters=[{"h.version": 0}],
)

这里是Mongo playground供您参考。 (以原生 js 语法)


如果您想更新条目而不是添加条目,则应使用 $set 而不是 $push。在您给出的示例中, client_id 是 int 而您的 arrayFilter 是字符串。如果不是故意的,它可能会导致问题。

collection.update_many(
    {"id": "33b66684-24a9-4a45-a12f-27a330152ac8", "history.version": 0},
    {
        "$set": {
            "history.$[h].responses.$[r]": {
                "client_id": 2,
                "response_date": "2020-01-01",
                "values": [{"field_id": 0, "value": "roi"}],
            }
        }
    },
    array_filters=[{"h.version": 0}, {"r.client_id": 2}],
)

这里是Mongo playground供您参考。 (以原生 js 语法)