0

I have document like this,

{
    "_id": {
        "$oid": "5f33aca82b2fcf5324290ae1"
    },
    "active": true,
    "addresses": [
        {
            "country": "IN",
            "formatted": "xyz",
            "locality": "San Francisco",
            "postalCode": "7656",
            "primary": true,
            "region": "CA",
            "streetAddress": "abc",
            "type": "work"
        },
        {
            "country": "US",
            "formatted": "xyz",
            "locality": "fdfdf",
            "postalCode": "91608",
            "primary": true,
            "region": "CA",
            "streetAddress": "def",
            "type": "other"
        }
    ]
}

The address attribute is multivalued , i want to update "streetAddress" of all address entries where "type"=="work".

But when i try this query below, "streetAddress" of all entries are getting updated.

mongo.db.test.update_one({'_id': ObjectId('5f33aca82b2fcf5324290ae1'), 'addresses.type':'work'}, {"$set":{'addresses.$[].streetAddress': "mno"}},upsert=True)

the result is,

{
    "_id": {
        "$oid": "5f33aca82b2fcf5324290ae1"
    },
    "active": true,
    "addresses": [
        {
            "country": "IN",
            "formatted": "xyz",
            "locality": "San Francisco",
            "postalCode": "7656",
            "primary": true,
            "region": "CA",
            "streetAddress": "mno",
            "type": "work"
        },
        {
            "country": "US",
            "formatted": "xyz",
            "locality": "fdfdf",
            "postalCode": "91608",
            "primary": true,
            "region": "CA",
            "streetAddress": "mno",
            "type": "other"
        }
    ]
}

as you can see both entries are getting modified.

I am using flask-pymongo library.

2 Answers 2

1

$[] will update elements of the arrays

But $[<identifier>] will update only elements that match the filter

You can read more here

I think something like this should work :

mongo.db.test.update_one({'_id': ObjectId('5f33aca82b2fcf5324290ae1')}, 
{"$set":{'addresses.$[addr].streetAddress': "mno"}},
{arrayFilters: [ { "elem.type": 'work' } ]},
upsert=True)
Sign up to request clarification or add additional context in comments.

Comments

0
Actual working code on widows 10 Mongo client
//data prep before:
db.test12.insert({
    "active": true,
    "addresses": [
        {
            "country": "IN",
            "formatted": "xyz",
            "locality": "San Francisco",
            "postalCode": "7656",
            "primary": true,
            "region": "CA",
            "streetAddress": "mno",
            "type": "work"
        },
        {
            "country": "US",
            "formatted": "xyz",
            "locality": "fdfdf",
            "postalCode": "91608",
            "primary": true,
            "region": "CA",
            "streetAddress": "mno",
            "type": "other"
        }
    ]
});

--
//data changes post update, you need to use $ to access array elements in the address array
> db.test12.updateOne({"addresses.type":"work"},{$set:{"addresses.$.streetAddress":"St Johns road"}});
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.test12.find().pretty();
{
        "_id" : ObjectId("5f492467e551d4c998f3c9ca"),
        "active" : true,
        "addresses" : [
                {
                        "country" : "IN",
                        "formatted" : "xyz",
                        "locality" : "San Francisco",
                        "postalCode" : "7656",
                        "primary" : true,
                        "region" : "CA",
                        "streetAddress" : "St Johns road",
                        "type" : "work"
                },
                {
                        "country" : "US",
                        "formatted" : "xyz",
                        "locality" : "fdfdf",
                        "postalCode" : "91608",
                        "primary" : true,
                        "region" : "CA",
                        "streetAddress" : "mno",
                        "type" : "other"
                }
        ]
}
>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.