QuartZ
QuartZ

Reputation: 164

Update document in array in the collection using $set and positional $ operator

Collection :

{
    "shopping_list": [
        {
            "date": 22,
            "drinks": [1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000],
            "year": 2016,
            "month": 11
        },
        {
            "date": 23,
            "drinks": [1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000],
            "year": 2016,
            "month": 11
        }
    ],
    "password": "user",
    "date_signup": "10-11-2016",
    "name": "User",
    "email": "[email protected]"
}

The code I made :

data_1 = [1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000]
data_2 = [2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000]
con.update({"email": "[email protected]",
            "shopping_list.date": 23,
            "shopping_list.month": 11,
            "shopping_list.year": 2016},
           {"$set": {"shopping_list.$.drinks": data_2}})

Tried this too (didn't work) :

con.update({"email": "[email protected]",
            "shopping_list.date": {"$eq": 23},
            "shopping_list.month": {"$eq": 11},
            "shopping_list.year": {"$eq": 2016}},
           {"$set": {"shopping_list.$.drinks": data_2}})

With my code I'm targeting the shopping_listin the second index of the array using $set. But nothing change after I run it. What is wrong with my code?

Upvotes: 2

Views: 137

Answers (1)

Sede
Sede

Reputation: 61225

This is because you get the query expression wrong.

With you query expression the $ positional update operator which identify the document to update does not know what to do. You need to use the $elemMatch operator if you need to specify multiple criteria on the embedded document.

con.update_one({
    "email": "[email protected]", 
    "shopping_list": { "$elemMatch": {
        "date": 23,             
         "month": 11,             
         "year": 2016}
    }}, 
    {"$set": {"shopping_list.$.drinks": data_2}})

Also note that update() is deprecated in MongoDB 3.2, 3.0 actually. You should use the update_one() method

Upvotes: 1

Related Questions