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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9224841/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 12:28:40  来源:igfitidea点击:

Add a new field to a collection with value of an existing field

mongodb

提问by Purrell

I'd like to add a new field to a collection, with the value of the new field set to the value of an existing field.

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

Specifically, I'd like to go from this:

具体来说,我想从这个开始:

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

to this:

对此:

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

(New documents in this collection won't all have this peculiar redundancy, but I want to do this for my existing documents)

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

回答by driangle

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

Run from console:

从控制台运行:

addEventTsField();

回答by Andrew Orsich

No, it is not possible. Only two steps thats you've probably know:

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

  1. Load document, read field. (you can load only specific fields: _id, and createdin your case if performance is an issue)
  2. Atomic update of document (set event_tsby using loaded createdfield)
  1. 加载文档,读取字段。(您只能加载特定字段: _id,并且created在您的情况下,如果性能是一个问题)
  2. 文档的原子更新(event_ts通过使用加载的created字段设置)

回答by Xavier Guihot

Starting Mongo 4.2, db.collection.update()can accept an aggregation pipeline, finally allowing the creation of a field based on another field:

开始Mongo 4.2db.collection.update()可以接受聚合管道,最后允许基于另一个字段创建一个字段:

// {
//   "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"),
//   "..." : "..."
// }
  • The first part {}is the match query, filtering which documents to update (here we keep all documents).

  • The second part [{ $set: { event_ts: "$created" } }]is the update aggregation pipeline (note the squared brackets signifying the use of an aggregation pipeline). $setis a new aggregation operator and an alias for $addFields, which allows including a new field to the document.

  • 第一部分{}是匹配查询,过滤要更新的文档(这里我们保留所有文档)。

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

回答by Vitaly Kushner

since your code already knows how to handle event_ts why do you need to copy the data? you can rename the field instead:

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

{ $rename : { old_field_name : new_field_name } }

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

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

回答by Param

If it is a one time thing to do, its no big deal. Run a query like "db.foo.find();" in your mongo shel and paste the entire output to a editor like Textpad or Sublime text, do a column block ( In sublime text it is Ctrl + scroll wheel click & Drag ) , , paste it which will extend to another field, rename the newly pasted column as you want it, once done, do a regex to just edit the whole bunch as "^" with "db.foo.insert({" and at the "$" as "});"

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

It is like the following steps.

就像下面的步骤。

  1. You pasted the output like { 'field1' : value, 'field2' : value2 , 'field3' : value4 };
    1. copy the last set and extend using the editor column block { 'field1' : value, 'field2' : value2 , 'field3' : value4 };
    2. Now insert the appropriate words to make it look like a command for mongo db.foo.insert({ 'field1' : value, 'field2' : value2 , 'field3' : value4 });
    3. Now copy them all and paste it in your mongo shell which will just do the whole thing for you as you want it. Test it once and redo the whole thing just after you cleanup the collection otherwise it will insert duplicates. Also remove the "_id" fields in the output since it will conflict when you attempt to insert again !!
  1. 您将输出粘贴为 { 'field1' : value, 'field2' : value2 , 'field3' : value4 };
    1. 复制最后一组并使用编辑器列块扩展 { 'field1' : value, 'field2' : value2 , 'field3' : value4 };
    2. 现在插入适当的词,使其看起来像 mongo db.foo.insert({ 'field1' : value, 'field2' : value2 , 'field3' : value4 });
    3. 现在将它们全部复制并粘贴到您的 mongo shell 中,它会根据您的需要为您完成所有操作。测试一次并在清理集合后重做整个事情,否则它会插入重复项。还要删除输出中的“_id”字段,因为它会在您尝试再次插入时发生冲突!!

Now, every single line in your editor shows a valid mongo command that can be pasted to your shell to insert a new document to your collection. so test it once and it works fine, clean up your entire collection like "db.foo.remove({});" and paste the entire command from the editor which will do it in a giffy.

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

It may be difficult when you attempt for the first time, but if you get it right its gonna be a handy thing for you to work along whenever you want it.... !!

第一次尝试时可能会很困难,但如果你做对了,它会是一件很方便的事情,让你随时随地工作......!