2014-02-20 61 views
1

如果我有一个文件,看起来像这样比如:烙领域

{ 
    "a" : "val", 
    "b" : "another val" 
} 

怎样才能使结果看起来像

{ 
    "b" : "val", 
    "a" : "another val" 
} 

我已经试过我不停地翻转指定字段db.collection.update({}, {$rename:{'a':'b', 'b':'a'}})但我得到错误Field name duplication not allowed with modifiers

回答

3

这是一个经典的硬币洗牌问题。上面可能缺少的是你试图在1步骤中尝试形成此更新时指定的field相冲突。你将不得不做,在多个步骤,所以逻辑:

db.collection.update({}, {$rename: { 'a': 'c' }}) 
db.collection.update({}, {$rename: { 'b': 'a' }}) 
db.collection.update({}, {$rename: { 'c': 'b' }}) 

但我们可以做的更好,避免在两个步骤

db.collection.update({}, {$rename:{ 'a': 'c', 'b': 'd' }}) 
db.collection.update({}, {$rename:{ 'c': 'b', 'd': 'a' }}) 

碰撞当然,这不是一个操作,它是不容易和您不能引用另一个字段的值并将其更新为另一个字段。

当然,只有在确实需要更改您的字段名称时才这样做。手册页$rename涵盖用例。如果您只是看到事情的方式,简单地$project形式你想要的:

db.collection.aggregate([{$project: { a: "$b", b: "$a" }}]) 
-1

值得注意的是,随着新的批量更新操作MongoDB中2.6未来有可能做到这一点的重命名在单个服务器端操作中。截至本帖发布时,2.6仍处于预发布阶段;你可以检查MongoDB download page的可用性。检查release notes以获取更改和新功能的完整列表。

这里是在一个单一的服务器端的命令做这个领域的重命名蒙戈shell语法:

var bulk = db.c.initializeOrderedBulkOp(); 
bulk.find({}).update({$rename: {a:'tmp'}}) 
bulk.find({}).update({$rename: {b:'a'}}) 
bulk.find({}).update({$rename: {tmp:'b'}}) 
bulk.execute() 
+0

看不出这有助于这个问题。这是指定的单个文档更新。也许这个** note **属于别的地方。 –

+0

对于这里提出的具体问题,优点确实很简单 - 一次往返服务器和两次。对于可能使用此处介绍的解决方案的其他应用程序来说,重命名每个字段的往返服务器的节省可能是有意义的。 –