只要你可以创建数据副本,聚合框架就可以作为替代方案使用。您也可以选择使用其他运算符对数据进行更多操作,但您唯一需要的是
$project
。这在空间上有些浪费,但在某些情况下可能更快,更适合使用。为了说明,我将首先向
foo
集合插入一些示例数据:
db.foo.insert({ 'lat': 1, 'lon': 2, someotherdata : [1, 2, 3] })
db.foo.insert({ 'lat': 4, 'lon': 1, someotherdata : [4, 5, 6] })
现在,我们只需使用$project
重新处理lat
和lon
字段,然后将它们发送到newfoo
集合:
db.foo.aggregate([
{$project : {_id : "$_id", "coords.lat" : "$lat", "coords.lon" : "$lon", "someotherdata" : "$someotherdata" }},
{ $out : "newfoo" }
])
然后检查newfoo
以获取我们修改过的数据:
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 } }
一旦您对新数据满意,您可以使用renameCollection()
命令删除旧数据,并在旧名称下使用新数据:
> 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 } }
最后一点注意事项 - 在 SERVER-7944 完成之前,您不能像这个答案中建议的那样通过提示 _id
索引来执行快照操作,因此如果其他地方的活动导致文档移动,则可能会多次访问文档。 由于在此示例中插入了 _id
字段,任何这种情况都会导致唯一键冲突,因此您不会得到重复项,但可能会有一个“旧”版本的文档。 始终在删除数据之前仔细检查数据,并最好备份。