QuartZ QuartZ - 13 days ago 6
Python Question

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": "user@user.com"
}


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": "user@user.com",
"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": "user@user.com",
"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_list
in the second index of the array using
$set
. But nothing change after I run it. What is wrong with my code?

Answer

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": "user@user.com", 
    "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