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

j2datikz  于 2022-11-03  发布在  Go
关注(0)|答案(2)|浏览(153)

我们有一个集合,其中有多个文档按照给定的时间戳排序。我们希望聚合两个时间戳之间的文档(比如startTime和stopTime):这是我们聚合中一个简单的匹配阶段,它有一个类似于timestamp的查询:{$gte:开始时间,$lte:stopTime}。但是,我们希望在此步骤的结果中包含两个额外的文档:在startTime之前最接近的文档,无论我们需要查看的时间有多远,并且在stopTime之后最接近的文档。

qhhrdooz

qhhrdooz1#

如果你已经过滤掉这些文档,一个选择是使用一个$lookup步骤和一个管道。在$lookup之后看起来有点笨拙,但是我想不出另一种方法来继续,而不分组所有的文档,这不是最好的方法。

  1. $match-这是一个“假”的步骤,目的是与您的情况保持一致。您已经在当前的渠道中使用了它,因此在这里不需要它
  2. $set“$$ROOT”以便以后使用
  3. $lookup两次,以便从原始集合中获取您请求的文档
    1.为每个文档创建一个文档数组,以获取当前文档中的beforeafter
  4. $unwind以分隔成文件
  5. $group_id,以便删除beforeafter文档的重复项
    1.格式Name
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}}
])

了解它在playground example上的工作原理

iqxoj9l9

iqxoj9l92#

$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 Playground供您参考。

相关问题