Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to flatten MongoDB result query?

I have a deeply nested collection in my MongoDB collection.

When I run the following query:

db.countries.findOne({},{'data.country.neighbor.name':1,'_id':0}) 

I end up with this nested result here:

{"data" : {   "country" : [     {       "neighbor" : [         {           "name" : "Austria"         },         {           "name" : "Switzerland"         }       ]     },     {       "neighbor" : {         "name" : "Malaysia"       }     },     {       "neighbor" : [         {           "name" : "Costa Rica"         },         {           "name" : "Colombia"         }       ]     }   ] }} 

Now, this is what I want:

['Austria', 'Switzerland', 'Malaysia', 'Costa Rica', 'Colombia'] 

or this:

{'name':['Austria', 'Switzerland', 'Malaysia', 'Costa Rica', 'Colombia']} 

or anything else similar... Is this possible?

like image 314
Marsellus Wallace Avatar asked Nov 08 '12 02:11

Marsellus Wallace


People also ask

What is unwind in MongoDB?

Definition. $unwind. Deconstructs an array field from the input documents to output a document for each element. Each output document is the input document with the value of the array field replaced by the element.

What is $project in MongoDB?

The $project takes a document that can specify the inclusion of fields, the suppression of the _id field, the addition of new fields, and the resetting of the values of existing fields. Alternatively, you may specify the exclusion of fields. The $project specifications have the following forms: Form. Description.

Which function is used in MongoDB to search for a result?

Find() Method. In MongoDB, find() method is used to select documents in a collection and return a cursor to the selected documents. Cursor means a pointer that points to a document, when we use find() method it returns a pointer on the selected documents and returns one by one.


2 Answers

You can use $project & $unwind & $group of aggregation framework to get the result closer to your requirement.

> db.countries.aggregate({$project:{a:'$data.country.neighbor.name'}},                          {$unwind:'$a'},                          {$unwind:'$a'},                          {$group:{_id:'a',res:{$addToSet:'$a'}}})   {     "result" : [         {             "_id" : "a",             "res" : [                 "Colombia",                 "Malaysia",                 "Switzerland",                 "Costa Rica",                 "Austria"             ]         }     ],     "ok" : 1 } 

$unwind used twice since the name array is nested deep. And It will only work if the neighbor attribute is an array. In your example one neighbor field (Malaysia) is not an array

like image 60
RameshVel Avatar answered Sep 28 '22 23:09

RameshVel


Done it much simpler way, maybe it is recent

db.countries.aggregate({$unwind:'$data.country.neighbor.name'}) 
like image 36
wadouk Avatar answered Sep 28 '22 21:09

wadouk