假设我有以下聚合管道:
db.getCollection('posts').aggregate([
{ $match: { _id: { $gt: "some id" }, tag: 'some tag' } },
{ $limit: 5 },
{ $group: { _id: null, hasNextPage: {??}, hasPreviousPage: {??} } }
])
因此,$match
和$limit
阶段将导致所有带有标签some tag
的帖子的子集。我怎么知道子集前后有帖子?
我猜,一种可能的方法是在$let
和hasPreviousPage
中包含表达式(带有hasNextPage
),该表达式将搜索少于_id
的帖子分别为"some id"
和大于$last: "$_id"
。但是我不确定如何在$let
中将组引用为变量。另外,也许还有其他更有效的方法。
答案 0 :(得分:1)
您可以使用以下汇总:
db.posts.aggregate([
{ $match: { tag: 'some tag' } },
{ $sort: { _id: 1 } },
{
$facet: {
data: [
{ $match: { _id: { $gt: 'some id' } } },
{ $limit: 5 }
],
hasPreviousPage: [
{ $match: { _id: { $lte: 'some id' } } },
{ $count: "totalPrev" }
],
hasNextPage: [
{ $match: { _id: { $gt: 'some id' } } },
{ $skip: 5 },
{ $limit: 1 }, // just to check if there's any element
{ $count: "totalNext" }
]
}
},
{
$unwind: { path: "$hasPreviousPage", preserveNullAndEmptyArrays: true }
},
{
$unwind: { path: "$hasNextPage", preserveNullAndEmptyArrays: true }
},
{
$project: {
data: 1,
hasPreviousPage: { $gt: [ "$hasPreviousPage.totalPrev", 0 ] },
hasNextPage: { $gt: [ "$hasNextPage.totalNext", 0 ] }
}
}
])
要对您的集合$sort应用任何分页,以确定的顺序获得结果。在按tag
排序和过滤的集合上,您可以运行$facet,该集合允许您应用多个子聚合。代表上一页和下一页的管道可以以$count
结尾。 $facet
中的每个子聚合都将返回一个数组,因此我们可以运行$unwind来获取嵌套文档,而不是hasPreviousPage
和hasNextPage
的数组。这里需要选项preserveNullAndEmptyArrays
,因为如果没有上一个/下一个文档,则MongoDB将从聚合管道中删除整个文档。在最后一步中,我们可以将子聚合转换为布尔值。