2012-02-10 93 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

相關問題