如何查询Mongo最后一组出现的文档
How to query documents of last group occurrence in Mongo
从开发人员的角度来看上下文
如果我的 Mongo collection 中的文档共享两个字段(我们称它们为 'group' 和 'subgroup')并且它们是连续的(这些组是实际上是 time-series)。请注意,相同的 'group' 和 'subgroup' 组合有很多实现,它们是不同的组,因为它们不属于相同的 time-series.
是否可以查询最后一个 time-series,也就是说所有文档(按时间戳降序)直到 'group' 或 'subgroup' 最先更改值时间?
真实背景
这是抽象的上下文;也许以真实的方式重新表述上下文可能会有用。我的 collection 中的文档是传感器测量,'group' 和 'subgroup' 识别生产过程的类型。每个生产过程都重复多次但从不连续。
我需要查询上一个生产过程的指标
我目前的解决方案
我知道一个time-series(生产过程)的最大持续时间是n秒所以我查询了最后一个n 秒 python 并使用 pandas.
最后一次出现 'group' + 'subgroup'
如果我们不是在谈论超大规模,您的方法似乎不错,但是如果您在最后 n
秒内可以拥有很多文档,我建议让数据库完成繁重的工作。
这是 nodejs
驱动程序的代码示例:
const nSecondsAgo = new Date(new Date().getTime() - 1000 * n);
// get last document in db
const lastDocument = await db.collection.findOne({
timestamp: {$gt: nSecondsAgo}}, { sort: { timestamp: -1 } });
// get last document in db from a different group/subgroup.
const lastOtherGroupDocument = await db.collection.findOne({
$or: [
{group: {$ne: lastDocument.group}},
{subgroup: {$ne: lastDocument.subgroup}}
],
timestamp: { $gt: nSecondsAgo }
}, {sort: {timestamp: -1}});
// if no "other" document just use last N seconds as your start reference.
const seriesStartTime = lastOtherGroupDocument?.timestamp ?? nSecondsAgo;
//fetch results
const seriesData = await db.collection.find({timestamp: {$gt: seriesStartTime $lte: lastDocument.timestamp})
// or if it's possible data is still coming in:
const seriesData = await db.collection.find({
timestamp: {$gt: seriesStartTime},
group: lastOtherGroupDocument.group,
subgroup: lastOtherGroupDocument.subgroup
},
)
如果您在 timestamp
上构建降序索引并在 group, subgroup, timestamp
上构建复杂索引,它将支持所有这些查询。并且查询时间应该是即时的。
我再说一遍,如果您没有在最后 n
秒内加载数万个文档,那么您当前的方法就可以了。仅当规模变得太大或您开始遇到性能问题时,我建议您切换。
从开发人员的角度来看上下文
如果我的 Mongo collection 中的文档共享两个字段(我们称它们为 'group' 和 'subgroup')并且它们是连续的(这些组是实际上是 time-series)。请注意,相同的 'group' 和 'subgroup' 组合有很多实现,它们是不同的组,因为它们不属于相同的 time-series.
是否可以查询最后一个 time-series,也就是说所有文档(按时间戳降序)直到 'group' 或 'subgroup' 最先更改值时间?
真实背景
这是抽象的上下文;也许以真实的方式重新表述上下文可能会有用。我的 collection 中的文档是传感器测量,'group' 和 'subgroup' 识别生产过程的类型。每个生产过程都重复多次但从不连续。
我需要查询上一个生产过程的指标
我目前的解决方案
我知道一个time-series(生产过程)的最大持续时间是n秒所以我查询了最后一个n 秒 python 并使用 pandas.
最后一次出现 'group' + 'subgroup'如果我们不是在谈论超大规模,您的方法似乎不错,但是如果您在最后 n
秒内可以拥有很多文档,我建议让数据库完成繁重的工作。
这是 nodejs
驱动程序的代码示例:
const nSecondsAgo = new Date(new Date().getTime() - 1000 * n);
// get last document in db
const lastDocument = await db.collection.findOne({
timestamp: {$gt: nSecondsAgo}}, { sort: { timestamp: -1 } });
// get last document in db from a different group/subgroup.
const lastOtherGroupDocument = await db.collection.findOne({
$or: [
{group: {$ne: lastDocument.group}},
{subgroup: {$ne: lastDocument.subgroup}}
],
timestamp: { $gt: nSecondsAgo }
}, {sort: {timestamp: -1}});
// if no "other" document just use last N seconds as your start reference.
const seriesStartTime = lastOtherGroupDocument?.timestamp ?? nSecondsAgo;
//fetch results
const seriesData = await db.collection.find({timestamp: {$gt: seriesStartTime $lte: lastDocument.timestamp})
// or if it's possible data is still coming in:
const seriesData = await db.collection.find({
timestamp: {$gt: seriesStartTime},
group: lastOtherGroupDocument.group,
subgroup: lastOtherGroupDocument.subgroup
},
)
如果您在 timestamp
上构建降序索引并在 group, subgroup, timestamp
上构建复杂索引,它将支持所有这些查询。并且查询时间应该是即时的。
我再说一遍,如果您没有在最后 n
秒内加载数万个文档,那么您当前的方法就可以了。仅当规模变得太大或您开始遇到性能问题时,我建议您切换。