当前位置:  开发笔记 > 数据库 > 正文

MongoDB Collection更新:使用默认值初始化文档

如何解决《MongoDBCollection更新:使用默认值初始化文档》经验,为你挑选了1个好方法。

我正在尝试使用MongoDB 处理时间序列.社区采用的通用解决方案是使用子文档以不同的粒度级别存储信息(请参阅 MongoDB中的时间序列数据的模式设计).

例如,请查看以下文档:

{
  timestamp_minute: ISODate("2013-10-10T23:06:00.000Z"),
  type: “memory_used”,
  values: [
    999999,   // 1 second
    …
    1000000,  // nth second
    1500000,  // n+1th second
    … 
    2000000   // 60th
  ]
}

该文档由分钟信息编制索引,并包含一个子文档,该子文档存储每秒的更详细信息.

到现在为止还挺好.这种方法需要优化才能正常工作:

另一个优化[..]正在为即将到来的时间段预分配所有文件; 这永远不会导致现有文档在磁盘上增长或移动.

要实现上述优化,可以使用$setOnInsertupdate方法的属性.

db.getCollection('aCollection').update(
    {
      timestamp_minute: ISODate("2013-10-10T23:06:00.000Z"),
      type: “memory_used”
    },
    {
      $setOnInsert: { values: {'0': 0, '1': 0, '2': 0}},
      $inc: {"values.30": 1}
    },
    { upsert: true }
)

问题是在两个不同的操作中不可能在同一更新中使用相同的字段.以上更新istruction会生成以下错误:

Cannot update 'values' and 'values.30' at the same time

在此问题上跟踪此问题.

我的问题是:有没有解决方法?我的前缀是我不能使用任何预先分配空文档的批处理,因为我无法先验地知道索引字段的值(在上面的例子中,字段的值type.

提前致谢.



1> riccardo.car..:

我和我的同事找到了解决方法.我们可以称之为三步初始化.

请记住,MongoDB保证了单个文档的操作原子性.考虑到这一点,我们可以通过以下方式运作:

    尝试更新文档,在指定的时间块正确递增计数器.不要做任何upsert,只是一个老式的更新操作.请记住,update语句的执行会返回写入的文档数.如果写入的文档数大于零,那么就完成了.

    如果更新写入的文档数为零,则表示要更新的相关文档尚未出现在集合中.尝试为指定的标记插入整个文档.将所有计数器(字段值)置于零.插入语句的执行也返回写入的文档数.如果它返回零或抛出异常,请不要介意:这意味着其他一些进程已经为相同的标记插入了文档.

    再次执行相同的上述更新.

代码看起来应该类似于以下代码片段.

// Firt of all, try the update
var result = db.test.update(
  {timestamp_minute: ISODate("2013-10-10T23:06:00.000Z"), type: “memory_used”},
  {$inc: {"values.39": 1}},
  {upsert: false}
);
// If the update do not succeed, then try to insert the document
if (result.nModified === 0) {
  try {
    db.test.insert(/* Put here the whole document */);
  } catch (err) {
    console.log(err);
  }
  // Here we are sure that the document exists.
  // Retry to execute the update statement
  db.test.update(/* Same update as above */);
}

如果前提条件成立,则上述过程有效:_id值应从文档中的其他字段派生.在我们的例子中,_id价值将是'2013-10-10T23:06:00.000Z-memory_used.仅使用此技术,第2点处的插入将正确失败.

推荐阅读
小妖694_807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有