0

Consider this mongodb document:

 {
"_id:"0,
"firstname":"Tom",
"profiles" : [
               {
                    "profile_name": "tom",
                    "reward_programs:[
                                        {
                                            'program_name':'American',
                                            'username':'tomdoe',
                                        },
                                        {
                                            'program_name':'Delta',
                                            'username':'tomdoe',
                                        }
                                      ]

                    "settings": {
                                    'auto_update': "False"
                                }
               },
               {
                    "profile_name": "harry",
                    "reward_programs:[
                                        {
                                            'program_name':'American',
                                            'username':'car',
                                            'account':'train',
                                        },
                                        {
                                            'program_name':'Delta',
                                            'username':'harrydoe',
                                        }
                                      ]

                    "settings": {
                                    'auto_update': "False"
                                }
               }
            ]

}

How would I retrieve just the 'settings' dictionary for a particular profile name? Let's use 'harry' in the example. I have tried:

result = users.find_one({'_id': request._id, 'profiles.profile_name': 'harry'}, {'_id': 0,  'profiles.$.settings': 1})

But this retrieves the entire dictionary of profile_name:'harry'

  {
    'profiles':
               {
                    "profile_name": "harry",
                    "reward_programs:[
                                        {
                                            'program_name':'American',
                                            'username':'car',
                                            'account':'train',
                                        },
                                        {
                                            'program_name':'Delta',
                                            'username':'harrydoe',
                                        }
                                      ]

                    "settings": {
                                    'auto_update': "False"
                                }
               }
 }

I would prefer getting the result as

 {
"profiles" : [
               {
                    "settings": {
                                    'auto_update': "False"
                                }
               }
            ]

}

And if simple enough I would even prefer:

               {
                    "settings": {
                                    'auto_update': "False"
                                }
               }

I obviously have my projection messed up but I don't know how to fix it. Suggestions?

2 Answers 2

1

You need to use aggregation framework for this. Something like this will give what you want -

result = db.users.aggregate( [ 
                     { $unwind : "$profiles"}, 
                     { $match : { "profiles.profile_name" : "harry"}}, 
                     { $project : { settings : "$profiles.settings" } }
                     ] )

If you don't want '_id' field then you can hide it like this -

 result = db.users.aggregate( [ 
                         { $unwind : "$profiles"}, 
                         { $match : { "profiles.profile_name" : "harry"}}, 
                         { $project : { '_id' : 0, settings : "$profiles.settings" } }
                         ] )

The result variable will have -

{ "settings" : { "auto_update" : "False" } }
Sign up to request clarification or add additional context in comments.

1 Comment

I was hoping not to use the aggregation framework. But if that is the only way so be it. Do you know what would be faster, using the aggregation framework or just doing what I did and pull out 'settings' manually from the result dict?
0

I guess mongodb has added some functionality since the question was answered. Just adding an answer for being current. In the projection you could just give the key from the embedded document and get the required embedded document alone.

result = users.find_one({'_id': request._id, 'profiles.profile_name': 'harry'},{'_id': 0,'settings': 1})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.