Reputation: 6018
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
Reputation: 61253
Quoting the documentation
When used with update operations, e.g.
db.collection.update()
anddb.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