As long as you are OK with creating a copy of the data, the aggregation framework can be used as an alternative here. You also have the option to do more to the data if you wish using other operators, but the only one you need is $project
. It's somewhat wasteful in terms of space, but may be faster and more appropriate for some uses. To illustrate, I'll first insert some sample data into the foo
collection:
db.foo.insert({ 'lat': 1, 'lon': 2, someotherdata : [1, 2, 3] })
db.foo.insert({ 'lat': 4, 'lon': 1, someotherdata : [4, 5, 6] })
Now, we just use $project
to rework the lat
and lon
fields, then send them to the newfoo
collection:
db.foo.aggregate([
{$project : {_id : "$_id", "coords.lat" : "$lat", "coords.lon" : "$lon", "someotherdata" : "$someotherdata" }},
{ $out : "newfoo" }
])
Then check newfoo
for our altered data:
db.newfoo.find()
{ "_id" : ObjectId("544548a71b5cf91c4893eb9a"), "someotherdata" : [ 1, 2, 3 ], "coords" : { "lat" : 1, "lon" : 2 } }
{ "_id" : ObjectId("544548a81b5cf91c4893eb9b"), "someotherdata" : [ 4, 5, 6 ], "coords" : { "lat" : 4, "lon" : 1 } }
Once you are happy with the new data, you can then use the renameCollection()
command to drop the old data and use the new data under the old name:
> db.newfoo.renameCollection("foo", true)
{ "ok" : 1 }
> db.foo.find()
{ "_id" : ObjectId("544548a71b5cf91c4893eb9a"), "someotherdata" : [ 1, 2, 3 ], "coords" : { "lat" : 1, "lon" : 2 } }
{ "_id" : ObjectId("544548a81b5cf91c4893eb9b"), "someotherdata" : [ 4, 5, 6 ], "coords" : { "lat" : 4, "lon" : 1 } }
One last note - until SERVER-7944 is completed you can't do the equivalent of a snapshot by hinting the _id
index as suggested in this answer and so you can end up hitting a document more than once if activity elsewhere causes it to move. Since you are inserting the _id
field in this example, any such occurrence would cause a unique key violation, so you will not end up with dupes, but you might have an "old" version of a document. As always, check your data thoroughly before dropping it, and preferably take a backup.