gpt4 book ai didi

MongoDB 集合更新 : initialize a document with default values

转载 作者:IT老高 更新时间:2023-10-28 13:27:58 25 4
gpt4 key购买 nike

我正在尝试使用 MongoDB 处理 时间序列。社区采用的常见解决方案是使用子文档来存储不同粒度级别的信息(参见Schema Design for Time Series Data in 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
]
}

该文档按分钟信息进行索引,并包含一个子文档,该子文档存储每秒更详细的信息。

到目前为止一切顺利。这种方法需要优化才能正常工作:

Another optimization [..] is preallocating all documents for the upcoming time period; This never causes an existing document to grow or be moved on disk.

要实现上述优化,可以在 update 方法上使用 $setOnInsert 属性。

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 }
)

问题是不可能在两个不同的操作中在同一个更新中使用同一个字段。上述更新指令产生如下错误:

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

此问题在此 issue 上进行跟踪.

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

提前致谢。

最佳答案

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

请记住,MongoDB 保证对单个文档的操作的原子性。考虑到这一事实,我们可以通过以下方式进行操作:

  1. 尝试更新文档,在指定的时间 block 正确递增计数器。不要做任何 upsert,只是一个老式的更新操作。请记住,更新语句的执行会返回写入的文档数。如果写入的文档数量大于零,那么您就完成了。
  2. 如果更新写入的文档数为零,则表示要更新的相关文档尚未出现在集合中。尝试为指定的标签插入整个文档。将所有计数器(字段值)置零。此外,插入语句的执行会返回写入的文档数。如果它返回零或抛出异常,请不要介意:这意味着其他进程已经为相同的标签插入了文档。
  3. 再次执行上述相同的更新。

代码应该类似于以下代码片段。

// 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. 的插入才会正确失败。

关于MongoDB 集合更新 : initialize a document with default values,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41552405/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com