Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb 将新字段添加到具有现有字段值的集合中_Mongodb - Fatal编程技术网

Mongodb 将新字段添加到具有现有字段值的集合中

Mongodb 将新字段添加到具有现有字段值的集合中,mongodb,Mongodb,我想向集合中添加一个新字段,将新字段的值设置为现有字段的值 具体来说,我想从以下几点开始: # db.foo.findOne() { "_id" : ObjectId("4f25c828eb60261eab000000"), "created" : ISODate("2012-01-29T16:28:56.232Z"), "..." : ... } 为此: # db.foo.findOne() {

我想向集合中添加一个新字段,将新字段的值设置为现有字段的值

具体来说,我想从以下几点开始:

# 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
        "..."      : ...
    }

(此集合中的新文档不会都有这种特殊的冗余,但我想对现有文档执行此操作)

不,这是不可能的。您可能只知道两个步骤:

  • 加载文档,读取字段。(如果性能有问题,您只能加载:
    \u id
    ,以及在您的情况下创建的
  • 文档的原子更新(使用已加载的
    创建的
    字段设置
    事件
  • 从控制台运行:

    addEventTsField();
    

    既然您的代码已经知道如何处理事件,为什么需要复制数据?您可以改为重命名该字段:

    { $rename : { old_field_name : new_field_name } }
    

    如果这是一次性的事情,那没什么大不了的。在mongo shel中运行类似“db.foo.find();”的查询,并将整个输出粘贴到Textpad或Sublime text之类的编辑器中,执行列块(在Sublime text中为Ctrl+滚轮单击并拖动),将其粘贴到扩展到另一个字段,根据需要重命名新粘贴的列,完成后,执行正则表达式以编辑整个列“^”加上“db.foo.insert({”,并在“$”处加上“}”);"

    就像下面的步骤一样

  • 您粘贴了如下输出: {'field1':value,'field2':value2,'field3':value4};
  • 复制最后一个集合并使用编辑器列块进行扩展 {'field1':value,'field2':value2,'field3':value4}
  • 现在插入适当的单词,使其看起来像mongo的命令 insert({'field1':value,'field2':value2,'field3':value4})
  • 现在,将它们全部复制并粘贴到mongo shell中,这将按照您的需要为您完成整个操作。请测试一次,并在清理集合后重新执行整个操作,否则它将插入重复项。此外,请删除输出中的“_id”字段,因为再次尝试插入时会发生冲突
  • 现在,编辑器中的每一行都显示了一个有效的mongo命令,该命令可以粘贴到shell以将新文档插入到集合中;然后从编辑器中粘贴整个命令,该编辑器将以giffy方式完成此操作


    第一次尝试时可能会很困难,但如果你做对了,这将是一件方便的事情,你可以在任何时候都使用它….!!

    启动
    Mongo 4.2
    ,可以接受聚合管道,最终允许基于另一个字段创建字段:

    // {
    //   "created" : ISODate("2012-01-29T16:28:56.232Z"),
    //   "..." : "..."
    // }
    db.collection.updateMany({}, [{ $set: { event_ts: "$created" } }])
    // {
    //   "created" :  ISODate("2012-01-29T16:28:56.232Z"),
    //   "event_ts" : ISODate("2012-01-29T16:28:56.232Z"),
    //   "..." : "..."
    // }
    
    • 第一部分是匹配查询,过滤要更新的文档(这里我们保留所有文档)

    • 第二部分
      [{$set:{event_ts:“$created”}]
      是更新聚合管道(注意方括号表示使用聚合管道)。是一个新的聚合运算符和
      $addFields
      的别名,它允许在文档中包含一个新字段


    即使使用db.foo.find().forEach()也不行?@Purrell:
    forEach
    实际上加载了所有找到的文档,它变成了两步更新…所以这是你需要做的一次性事情?对,只需要做一次就可以准备这个数据。你在做一个假设,文档中也不需要“created”。不过这不是一个原子操作。这是与e数据在这两者之间变化的可能性。(虽然他在他的情况下可能是安全的,因为他似乎只做了一次,离线)这个答案根本没有意义,因为它非常容易出错,无法自动化,无法测试,无法编写脚本…当可以用简单的函数和forEach()轻松完成此操作时,为什么还要在编辑器中执行此操作?也可以是-1,因为它需要
    db.foo.remove({})在操作的中间,它会把现有数据的任何东西都拧在一起。问题是发布的,它是一个一次性的工作。而且,在编辑器中做它使得编辑需要的东西变得容易得多,要注释什么或删除什么。当然,使用FraceH的解决方案更好,这是也不坏,因为它是非常方便的,当我们处于测试当中,我们需要非常频繁地插入数据,删除它们,再将它们添加到这里,在这里没有太多的变化,当您只在命令行中运行相同的脚本文件时,也可以自动化。
    
    // {
    //   "created" : ISODate("2012-01-29T16:28:56.232Z"),
    //   "..." : "..."
    // }
    db.collection.updateMany({}, [{ $set: { event_ts: "$created" } }])
    // {
    //   "created" :  ISODate("2012-01-29T16:28:56.232Z"),
    //   "event_ts" : ISODate("2012-01-29T16:28:56.232Z"),
    //   "..." : "..."
    // }