0

I'm trying to update an array inside a mongo document by using pymongo but it is not working, but copy same query to robomongo does works. (it returns {'n': 1, 'nModified': 0, 'ok': 1.0, 'updatedExisting': True})

roboMongo:

db.my_collection.updateMany(
    {'start_time': 1501700400.0},
    {'$pull': {'related': {'$in': [{'KEY': '1', 'TYPE': 'my_type'}]}}},
    {upsert:true}
)

pymongo code:

query_document = {'start_time': 1501700400.0}
update_command = {'$pull': {'related': {'$in': [{'KEY': '1', 'TYPE': 'my_type'}]}}}
_client[db][collection].update_many(query_document, update_command, True)

document:

{
    "_id" : ObjectId("598570c4ffd387293e368c8d"),
    "related" : [ 
        {
            "KEY" : "6",
            "TYPE" : "my_type"
        }, 
        {
            "KEY" : "2",
            "TYPE" : "my_type"
        }, 
        {
            "KEY" : "3",
            "TYPE" : "my_type"
        }, 
        {
            "KEY" : "5",
            "TYPE" : "my_type"
        }, 
        {
            "KEY" : "8",
            "TYPE" : "my_type"
        }
    ],
    "end_time" : 1501621200.0,
    "start_time" : 1501700400.0
}

I'm thinking maybe it is related to " and ' ?

any advice?

Thanks

Md. Rezwanul Haque
  • 2,882
  • 7
  • 28
  • 45
Shai M.
  • 1,284
  • 4
  • 17
  • 30
  • What is the result of pymongo call? Is it an error? Or it runs ok but updates nothing? – bagrat Aug 05 '17 at 14:36
  • The result is : `{'n': 1, 'nModified': 0, 'ok': 1.0, 'updatedExisting': True}` – Shai M. Aug 05 '17 at 15:58
  • 1
    So the query matches the document, but does not change the document? Is it because your are trying to `$pull` and array element from `related` that is not there (`"KEY": "1", ...`)? What exactly happens when you do that in robomongo and are you sure both queries operate on the exact same version of the document? – guessimtoolate Aug 05 '17 at 22:16
  • 1
    @guessimtoolate That's exactly the reason. If there is nothing to actually update, this is what MongoDB reports. This is by design. Problem is the first statement "executed in the shell" already removed the item from the array. If you expect something to actually "update" you need to specify something that actually presently "exists" in the array. Change to `"KEY": "2"` and the item will be pulled. – Neil Lunn Aug 05 '17 at 22:48
  • Guys, of course I reinserted the document before running the code – Shai M. Aug 06 '17 at 05:36

1 Answers1

1

The {'KEY': '1', 'TYPE': 'my_type'} should be ordered, therefore I force the order by doing:

ordered_relateds = []
for ptr in ptrs_to_remove:
    ordered_ptrs.append(collections.OrderedDict(sorted(related.items(), key=lambda t: t[0])))

update_command = {"$pull": {"related": {"$in": ordered_related}}}

This way KEY will alway be the first element in the hash and TYPE will be the second one.

Shai M.
  • 1,284
  • 4
  • 17
  • 30