I'm a bit unsure currently on what would be the best approach to
accomplish what I want,
which I guess is somewhat similar to what is asked here:
$addToSet / $push for key/value-pair
http://groups.google.com/group/mongodb-user/browse_thread/thread/64505ffaf3ffed74/
What I want to do is update a nested object/array with new data, which
in my application is a incoming Python dictionary, in an efficient
way.
The test collection:
> db.t.find()
{ "_id" : ObjectId("4d07611f0d9955dbf992a3b6"), "pairs" : { "a" :
"b" } }
Then I want to update/upsert this table with a Python dictionary, e.g.
{"c": "d", "e" : "f"}
This in such a way that I end up with:
{ "_id" : ObjectId("4d07611f0d9955dbf992a3b6"), "pairs" : { "a": "b",
"c": "d", "e": "f" } }
And after another update, with e.g. Python dictionary {"a": "z"}, I
want to end up with
{ "_id" : ObjectId("4d07611f0d9955dbf992a3b6"), "pairs" : { "a": "z",
"c": "d", "e": "f" } }
Thus:
- updating pairs if they already exist
- keeping existing pairs if they are not mentioned in the update
(existing pairs are not available anymore when a second update is done
and I'd rather not query/fetch it again for each update.)
- keys are always/should be unique
If I've got this:
{ "_id" : ObjectId("4d07611f0d9955dbf992a3b6"), "pairs" : { "a" : "c",
"b" : "d" } }
and do a set like this:
db.t.update({ "_id" : ObjectId("4d07611f0d9955dbf992a3b6")}, {$set:
{'pairs': {'a':'b'}}})
I only have left:
{ "_id" : ObjectId("4d07611f0d9955dbf992a3b6"), "pairs" : { "a" :
"b" } }
Logical, but not quite what I need :-)
Of course I can do:
db.t.update({ "_id" : ObjectId("4d07611f0d9955dbf992a3b6")}, {$set:
{'pairs.a':'c', 'pairs.b':'d'}})
and get:
{ "_id" : ObjectId("4d07611f0d9955dbf992a3b6"), "pairs" : { "a" : "c",
"b" : "d" } }
Which can be accomplished by just iterating over the incoming
dictionary in Python, generating a 'set' statement with one or more
new pairs and then doing the update.
But I guess I'm just wondering if there's a (combination) of Mongo
command(s) that makes it possible to update the collection in the way
mentioned above in a more direct way, without having to do some extra
'pre-processing' /looping to compose the query statement.
Many thanks for your insights. :-)