Animesh Pandey
Animesh Pandey

Reputation: 6018

Updating a value of dictionary in list of dictionaries in a collection using PyMongo

The collection structure that I have is as follows:

defaultdict(
    lambda: {
        '_id' : None,
        'stuff' : [defaultdict(lambda : 0)]
    })

I am trying to initialise a list of dictionaries that I'll keep on updating in a way that if a dictionary's key already exists then I'll increase its value by 1 otherwise I'll update the list of dictionary with the new key, value pair. e.g. is the value of stuff is [] and I have come across a value val then the value of stuff will be [{'val' : 1}] and further if I get a value val2 then stuff = [{'val' : 1}, {'val2' : 1}] and again if I get val, stuff should be [{'val' : 2}, {'val2' : 1}].

I tried this:

table.update({'_id' : data['_id']}, \
             {'$inc' : {"stuff.$."+keyvalue : 1}})

where, data is a JSON object having an _id and a list of dictionaries stuff. Running this I received an OperationFailure: The positional operator did not find the match needed from the query.

I cannot figure out what to do? I am a Mongo newbie.

Upvotes: 2

Views: 3269

Answers (1)

Sede
Sede

Reputation: 61253

Quoting the documentation

When used with update operations, e.g. db.collection.update() and db.collection.findAndModify(),

  • the positional $ operator acts as a placeholder for the first element that matches the query document, and
  • the array field must appear as part of the query document.

So the stuff array should appear in your query. Now since you are doing conditional update you need to check if your array already has any subdocument with your keyvalue using $exists.

if not table.find_one({ "_id": data['_id'], "stuff": {"$elemMatch": {keyvalue: { "$exists" : True }}}}):
    table.update({ "_id": data['_id'] }, { "$push": { "stuff": { keyvalue: 1 }}})
else:
    table.update({ "_id": data['_id'], "stuff": { "$elemMatch": { keyvalue: { "$exists" : True}}}}, { "$inc": { "stuff.$." + keyvalue: 1}})

Upvotes: 2

Related Questions