2012-02-10 53 views
17

我想向集合添加新字段,并将新字段的值设置为现有字段的值。将新字段添加到具有现有字段值的集合

具体来说,我想从这个去:

# db.foo.findOne() 
    { 
     "_id"  : ObjectId("4f25c828eb60261eab000000"), 
     "created" : ISODate("2012-01-29T16:28:56.232Z"), 
     "..."  : ... 
    } 

这样:

# db.foo.findOne() 
    { 
     "_id"  : ObjectId("4f25c828eb60261eab000000"), 
     "created" : ISODate("2012-01-29T16:28:56.232Z"), 
     "event_ts" : ISODate("2012-01-29T16:28:56.232Z"), #same as created 
     "..."  : ... 
    } 

(这个集合不都有这种奇特的冗余新文档,但我想为我的现有文件做这个)

+0

所以这是一次你需要做的事情? – ggreiner 2012-02-10 08:44:51

+0

对,只需要做一次准备这个数据 – Purrell 2012-02-12 02:35:31

回答

38
function addEventTsField(){ 
    db.foo.find().forEach(function(doc){ 
     db.foo.update({_id:doc._id}, {$set:{"event_ts":doc.created}}); 
    }); 
} 

运行:(_idcreated在你的情况下,如果性能是一个问题,你可以只加载specific fields):

addEventTsField(); 
+2

虽然不是原子操作。这是两个独立的操作,可能会在两者之间进行数据更改。 (尽管在他的情况下他可能是安全的,因为他似乎在做一次,离线) – UpTheCreek 2013-02-18 20:23:27

2

不,这是不可能的。只有两步你可能知道:

  1. 加载文件,阅读栏。 (通过使用加载created字段设置event_ts)从控制台
  2. 的文件原子更新
+0

甚至没有与db.foo.find()。forEach()的东西? – Purrell 2012-02-10 08:40:18

+1

@Purrell:'forEach'实际载入所有找到的文件,并且成为两步更新... – 2012-02-10 08:44:56

-1

因为你的代码已经知道如何处理event_ts你为什么需要复制数据?也可以重命名字段:

{ $rename : { old_field_name : new_field_name } } 

http://www.mongodb.org/display/DOCS/Updating

+4

您正在做出一个假设,即'创建'在文档中也不需要。 – Purrell 2012-06-24 07:18:24

-1

如果是一次性的事情,它没有什么大不了的。运行一个查询,如“db.foo.find();”在你的mongo shel中粘贴整个输出到一个像Textpad或Sublime text这样的编辑器,做一个列块(在sublime文本中它是Ctrl +滚轮点击& Drag),粘贴它将扩展到另一个域,重新命名按照你想要的方式粘贴列,一旦完成,做一个正则表达式编辑整个一堆作为“^”与“db.foo.insert({”和在“$”作为“});”

它就像下面的步骤。

  1. 您粘贴等 输出{ 'field1的':值, 'FIELD2':值2, '字段3':VALUE4};
    1. 复制最后一组并使用编辑器列块 {'field1':value,'field2':value2,'field3':value4};
    2. 现在插入适当的单词,使其看起来像mongo的命令。 db.foo.insert({'field1':value,'field2':value2,'field3':value4});
    3. 现在将它们全部复制并粘贴到您的mongo外壳中,只需按照您的要求为您完成整个任务即可。测试一次,并在清理集合后重做整个事情,否则它会插入重复项。还要删除输出中的“_id”字段,因为当您尝试再次插入时它将会发生冲突!

现在,在编辑器中每一行显示了可粘贴到你的shell中插入一个新的文件到您的收藏有效蒙戈命令。所以测试一次,它工作正常,清理整个集合,如“db.foo.remove({});”并从编辑器中粘贴整个命令,这将在giffy中完成。

当你第一次尝试时可能很难,但如果你做对了,它会是一个方便的东西,让你随时随地工作.... !!

+0

这个答案甚至没有意义,因为它很容易出错,不能自动化,不能测试,不能编写脚本......为什么你会想在编辑器中做这个操作,使用简单的函数和forEach()可以轻松完成这项工作吗? – 2015-11-16 06:00:43

+0

也是-1,因为它在操作过程中需要'db.foo.remove({})',这会使任何期望现有数据仍然存在的东西搞砸。 – David 2016-01-26 09:05:47

+0

问题发布的意图是一次性工作。另外,在编辑器中进行编辑会使需要编辑的内容,要评论的内容或要删除的内容变得更加容易。当然,使用foreach的解决方案更好,但这并不是很糟糕,因为当我们处于测试过程中时,它非常方便,我们需要频繁插入数据,删除它们,然后再次添加它们,并在这里进行一些更改。当你只是在命令行中运行相同的脚本文件时,它也可以被自动化。 – Param 2016-01-26 10:33:44

相关问题