2012-04-18 189 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