假设我们有一个MongoDB时间序列集合,目前没有 meta字段。
const granularity = "second";
const expireAfterSeconds = 60 * 60 * 24 * 365;
createCollection("test", {
timeseries: {
timeField: "_createdAt",
//metaField: "metadata",
granularity,
},
expireAfterSeconds,
});
我们想知道所考虑的文档和前一个文档之间的时间。由于集合没有 meta字段,我们不能修改文档并在之后添加第二个时间戳。
我们可以运行以下聚合流水线:
collection("test").aggregate([
{
$sort: {
_createdAt: 1
}
},
{
$lookup: {
from: "test",
let: { current_timestamp: "$_createdAt" },
pipeline: [
{
$match: {
$expr: {
$or: [
{ $eq: ["$_createdAt", "$$current_timestamp"] },
{ $lt: ["$_createdAt", "$$current_timestamp"] }
]
}
}
},
{
$sort: {
_createdAt: -1
}
},
{
$limit: 2
}
],
as: "matched_docs"
}
},
{
$addFields: {
prev_doc: { $arrayElemAt: ["$matched_docs", 1] },
}
},
{
$addFields: {
_deltaTms: {
$subtract: ["$_createdAt", "$prev_doc._createdAt"]
},
}
},
{
$project: {
matched_docs: 0,
prev_doc: 0,
}
}
]).toArray();
此解决方案使用_deltaTms字段扩展文档,该字段是最后一个文档之间的时间增量(以毫秒为单位)。
我想知道这是否是正确的解决方案,它看起来有点过于复杂。在查询速度方面,添加一个 meta字段是否更有效,而不是通过添加时间戳和使用元字段来修改最后一个文档?
1条答案
按热度按时间piztneat1#
从mongodb版本5.0开始,你可以使用
$setWindowFields
来实现:了解它在playground example上的工作原理