How do I rename fields when performing search/projection in MongoDB?

themiurgo picture themiurgo · May 21, 2014 · Viewed 40.2k times · Source

Is it possible to rename the name of fields returned in a find query? I would like to use something like $rename, however I wouldn't like to change the documents I'm accessing. I want just to retrieve them differently, something that works like SELECT COORINATES AS COORDS in SQL.

What I do now:

db.tweets.findOne({}, {'level1.level2.coordinates': 1, _id:0})
{'level1': {'level2': {'coordinates': [10, 20]}}}

What I would like to be returned is: {'coords': [10, 20]}

Answer

Neil Lunn picture Neil Lunn · May 21, 2014

So basically using .aggregate() instead of .find():

db.tweets.aggregate([
    { "$project": {
        "_id": 0,
        "coords": "$level1.level2.coordinates"
    }}
])

And that gives you the result that you want.

MongoDB 2.6 and above versions return a "cursor" just like find does.

See $project and other aggregation framework operators for more details.


For most cases you should simply rename the fields as returned from .find() when processing the cursor. For JavaScript as an example, you can use .map() to do this.

From the shell:

db.tweets.find({},{'level1.level2.coordinates': 1, _id:0}).map( doc => {
  doc.coords = doc['level1']['level2'].coordinates;
  delete doc['level1'];
  return doc;
})

Or more inline:

db.tweets.find({},{'level1.level2.coordinates': 1, _id:0}).map( doc => 
  ({ coords: doc['level1']['level2'].coordinates })
)

This avoids any additional overhead on the server and should be used in such cases where the additional processing overhead would outweigh the gain of actual reduction in size of the data retrieved. In this case ( and most ) it would be minimal and therefore better to re-process the cursor result to restructure.