Updating/adding to nested object with new key/value pairs

4,004 views
Skip to first unread message

Wilatai

unread,
Dec 15, 2010, 4:36:23 AM12/15/10
to mongodb-user

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. :-)

Eliot Horowitz

unread,
Dec 15, 2010, 7:35:48 AM12/15/10
to mongod...@googlegroups.com
Your last version is the correct way of doing it.
So { "$set" : { "pairs.a" : ... , "pairs.b" : ... } }

> --
> You received this message because you are subscribed to the Google Groups "mongodb-user" group.
> To post to this group, send email to mongod...@googlegroups.com.
> To unsubscribe from this group, send email to mongodb-user...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/mongodb-user?hl=en.
>
>

Wilatai

unread,
Dec 15, 2010, 8:36:34 AM12/15/10
to mongodb-user

Ok, then I'll use a loop in the Python code to prepend the 'pairs.'
part to each key in the Python dictionary before calling update with
$set. It's certainly not a deal breaker since usually it will be less
than 50 items or so.
Reply all
Reply to author
Forward
0 new messages