2012-04-18 238 views
5

我每天每米有一個文檔。如何在數據數組中添加另一個子文檔並在不存在的情況下創建整個文檔?Mongodb upsert嵌入式文檔

 
{ 
    "key": "20120418_123456789", 
    "data":[ 
    { 
    "Meter": 123456789, 
    "Dt": ISODate("2011-12-29T16:00:00.0Z"), 
    "Energy": 25, 
    "PMin": 11, 
    "PMax": 16 
    } 
    ], 
    "config": {"someparam": 4.5} 
} 

我可以爲此使用upsert嗎?

的結果將是,如果文件存在:提前

 
{ 
    "key": "20120418_123456789", 
    "data":[ 
    { 
    "Meter": 123456789, 
    "Dt": ISODate("2011-12-29T16:00:00.0Z"), 
    "Energy": 25, 
    "PMin": 11, 
    "PMax": 16 
    }, 
    { 
    "Meter": 123456789, 
    "Dt": ISODate("2011-12-29T16:15:00.0Z"), 
    "Energy": 22, 
    "PMin": 13, 
    "PMax": 17 
    } 
    ], 
    "config": {"someparam": 4.5} 
} 

感謝

回答

9

我想你想要什麼$ addToSet命令 - 將只有當它不是一個元素推到一個數組已經存在。我已經簡化你的例子有點爲簡潔:

db.meters.findOne() 
{ 
    "_id" : ObjectId("4f8e95a718bc9c7da1e6511a"), 
    "config" : { 
     "someparam" : 4.5 
    }, 
    "data" : [ 
     { 
      "Meter" : 123456789, 
     } 
    ], 
    "key" : "20120418_123456789" 
} 

現在運行:

db.meters.update({"key" : "20120418_123456789"}, {"$addToSet": {"data" : {"Meter" : 1234}}}) 

而我們得到的更新版本:再次

db.meters.findOne() 
{ 
    "_id" : ObjectId("4f8e95a718bc9c7da1e6511a"), 
    "config" : { 
     "someparam" : 4.5 
    }, 
    "data" : [ 
     { 
      "Meter" : 123456789, 
     }, 
     { 
      "Meter" : 1234 
     } 
    ], 
    "key" : "20120418_123456789" 
} 

運行相同的命令,結果不變。

注意:你很可能會被不斷增長的這些文件,特別是如果該字段是無界的,並通過這種方式更新導致頻繁(相對昂貴的)動作 - 你應該看看這裏就如何緩解這一想法:

http://www.mongodb.org/display/DOCS/Padding+Factor#PaddingFactor-ManualPadding

+0

我必須每天做400000個addToSet ...每個文檔有96個數據。它似乎很慢......有其他方法可以做到嗎? – hotips 2012-04-18 11:22:37

+0

如上所述,您將通過以這種方式增長一組值來觸發多個移動 - 這將導致減速,除非您以某種方式限制數組並且可以預測其最大大小 - 那麼您可以適當地填充它,更新會更快。如果你不能這樣做,那麼也許你應該考慮一個不同的模式,並將數據放在另一個集合中,而不是嵌入式數組。 – 2012-04-18 12:26:52