【问题标题】:Fetch immediate next and previous documents based on conditions in MongoDB根据 MongoDB 中的条件获取下一个和上一个文档
【发布时间】:2021-12-15 02:02:33
【问题描述】:

背景

我有以下收藏:

article {
  title: String,
  slug: String,
  published_at: Date,
  ...
}

MongoDB 版本:4.4.10

问题

给定一篇文章,我想根据该文章的 published_at 字段获取紧接的下一篇和上一篇文章。

假设我有一篇文章,published_at100。还有很多文章published_at 小于100 和很多published_at 大于100。我希望管道/查询仅获取具有 published_at 值为 99101 或最接近的可能的文章。

尝试

这是我的聚合管道:

const article = await db.article.findOne({ ... });

const nextAndPrev = db.article.aggregate([
    {
        $match: {
            $or: [
                {
                    published_at: { $lt: article.published_at },
                    published_at: { $gt: article.published_at },
                },
            ],
        },
    },
    {
        $project: { slug: 1, title: 1 },
    },
    {
        $limit: 2,
    },
]);

它给出了错误的结果(提供的文章之后的两篇文章),这是预期的,因为我知道它是不正确的。

可能的解决方案

  • 我可以使用两个单独的findOne 查询轻松地做到这一点,如下所示:

    const next = await db.article.findOne({ published_at: { $gt: article.published_at } });
    const prev = await db.article.findOne({ published_at: { $lt: article.published_at } });
    

    但我很想知道任何可用的方法可以在一次访问数据库中完成。

  • 如果我对所有文章进行排序,将其偏移到时间戳,然后提取上一个和下一个条目,这可能会起作用。我不知道语法。

【问题讨论】:

  • 如果您能提供示例数据集和预期输出将会很有帮助
  • 嘿@ray,我已经用一个场景/示例更新了这个问题。这有帮助吗?
  • 当然。请问您使用的是哪个版本的MongoDB?
  • db.version() 给出 4.4.10

标签: mongodb mongoose mongodb-query aggregation-framework


【解决方案1】:

从 MongoDB v5.0 开始,

您可以使用$setWindowFields 根据一定的排序/排名来获取即时的上一个/下一个文档。

您可以通过操作documents: [<prev offset>, <next offset>]字段获取当前和下一个文档的_id。同样,对于 OP 的场景,一次获取上一个、当前和下一个文档将是 [-1, 1]。执行$lookup,通过nearIds数组中存储的_id取回文档。

{
    "$setWindowFields": {
      "partitionBy": null,
      "sortBy": {
        "published_at": 1
      },
      "output": {
        nearIds: {
          $addToSet: "$_id",
          window: {
            documents: [
              -1,
              1
            ]
          }
        }
      }
    }
  }

这里是Mongo playground 供您参考。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-23
    • 2014-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-17
    相关资源
    最近更新 更多