查找两个日期之间的文档,但包括第一个结果之前和最后一个结果之后的文档



我们有一个集合,其中包含根据给定时间戳排序的多个文档。我们希望在两个时间戳(比如startTime和stopTime(之间聚合文档:这是聚合中的一个简单匹配阶段,它有一个查询,例如timestamp:{$gte:startTime,$lte:stopTime}。然而,我们希望在这一步骤的结果中包括两个额外的文档:startTime之前最接近的文档,无论我们需要查看多远的时间,以及stopTime之后最接近的文件。有没有一种方法可以通过MongoDB中的聚合框架来实现这一点?

$unionWith$sort$limit: 1连锁以使文档超出范围。

db.collection.aggregate([
{
$match: {
datetime: {
$gte: ISODate("2022-10-18"),
$lte: ISODate("2022-10-19")
}
}
},
{
"$unionWith": {
"coll": "collection",
"pipeline": [
{
$match: {
datetime: {
$lt: ISODate("2022-10-18")
}
}
},
{
$sort: {
datetime: -1
}
},
{
$limit: 1
}
]
}
},
{
"$unionWith": {
"coll": "collection",
"pipeline": [
{
$match: {
datetime: {
$gt: ISODate("2022-10-19")
}
}
},
{
$sort: {
datetime: 1
}
},
{
$limit: 1
}
]
}
}
])

这是Mongo游乐场供您参考。

如果您已经过滤掉这些文档,那么一个选项是使用带有管道的$lookup步骤。在$lookup之后,它看起来有点笨拙,但我想不出其他方法在不分组所有文档的情况下继续,这不是最好的方法。

  1. $match-这是一个;假的";采取步骤来改善你的处境。您当前的管道中已经有了它,因此这里不需要它
  2. CCD_ 7$$ROOT";以便以后使用
  3. $lookup两次,以便从原始集合中获取您所需的文档
  4. 为每个文档创建一个文档数组,以便从当前文档中获得beforeafter
  5. $unwind分离成文档
  6. $group通过_id来去除beforeafter文档的重复
  7. 格式
db.collection.aggregate([
{$match: {timestamp: {$gte: startTime, $lte: stopTime}}},
{$set: {data: "$$ROOT"}},
{$lookup: {
from: "collection",
let: {},
pipeline: [
{$match: {timestamp: {$lt: startTime}}},
{$sort: {timestamp: -1}},
{$limit: 1}
],
as: "before"
}},
{$lookup: {
from: "collection",
let: {},
pipeline: [
{$match: {timestamp: {$gt: stopTime}}},
{$sort: {timestamp: 1}},
{$limit: 1}
],
as: "after"
}},
{$project: {_id: 0, data: {$concatArrays: ["$after", "$before", ["$data"]]}}},
{$unwind: "$data"},
{$group: {_id: "$data._id", data: {$first: "$data"}}},
{$replaceRoot: {newRoot: "$data"}},
{$sort: {timestamp: 1}}
])

看看它是如何在操场上工作的例子

最新更新