我有以下收藏:
article {
title: String,
slug: String,
published_at: Date,
...
}
MongoDB 版本:
4.4.10
给定一篇文章,我想根据该文章的
published_at
字段获取紧邻的下一篇和上一篇文章。
假设我有一篇文章,其中
published_at
为 100
。并且有很多文章的 published_at
小于 100
,也有很多文章的 published_at
大于 100
。我希望管道/查询仅获取 published_at
值为 99
或 101
或最接近的文章。
这是我的聚合管道:
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 } });
但我很好奇是否有任何可用的方法可以在一次数据库访问中完成此操作。
如果我对所有文章进行排序,将其偏移到时间戳,并提取上一个和下一个条目,这可能会起作用。我不知道语法。
从 MongoDB v5.0 开始,您可以使用
$setWindowFields
根据一定的排序/排名来获取立即的上一个/下一个文档。
您可以通过操作
documents: [<prev offset>, <next offset>]
字段来获取当前和下一个文档。同样,对于 OP 的场景,一次获取上一个、当前和下一个文档将是 [-1, 1]。
{
"$setWindowFields": {
"partitionBy": null,
"sortBy": {
"published_at": 1
},
"output": {
nearDocs: {
$addToSet: "$$ROOT",
window: {
documents: [
-1,
1
]
}
}
}
}
}