Search code examples
mongodbpymongo

MongoDB: Upsert with array filter


I have collection like this:

mc.db.collection.insert_many([
    {"key_array": [1], "another_array": ["a"]},
    {"key_array": [2, 3], "another_array": ["b"]},
    {"key_array": [4], "another_array": ["c", "d"]},    
])

And I'm using this kind of updates:

mc.db.collection.update_one(
    {"key_array": 5},
    {"$addToSet": {"another_array": "f"}},
    upsert=True
)

It works good with updates, but I have trouble when trying to upsert: It creates a document with a non-array key_array field, like this

{
    "_id": ObjectId(...)
    "key_array": 5,
    "another_array": ["f"]
}

while I want to have this one

{
    "_id": ObjectId(...)
    "key_array": [5],
    "another_array": ["f"]
}

Also, I cannot use the {"key_array": [5]} style query, because it won't match the existing array with length > 1.

So, is there any chance to save such behavior on updates, and receive the correct document structure on inserts?

Any help will be appreciated


Solution

  • This should help. https://www.mongodb.com/docs/manual/reference/operator/update/setOnInsert/

    mc.db.collection.update_one(
        {"key_array": 5},
        {
            "$addToSet": {"another_array": "f"},
            "$setOnInsert": {"key_array": [5], ...}
        },
        upsert=True
    )