MongoDb -每次调用(分页)时,从嵌套数组的末尾返回N个元素的块



我有一个类别集合,每个类别都有来自不同集合的_id数组。我的目标是通过每次给出N条记录来创建无限滚动,但从末尾开始(最后一条记录总是最近的)。

类别

{ 
"_id" : ObjectId("625167ce3859b8465ccf69dc"), 
"name" : {
"en" : "Category #1"
}, 
"tracks" : [
ObjectId("627f8475c229513838eed070"), 
ObjectId("627f84b4c229513838eed074"), 
ObjectId("6280ef548b97521c1f462266"), 
ObjectId("6280ef68d147e83534f4ca03"), 
ObjectId("6280ef6ad147e83534f4ca07"), 
ObjectId("6280ef6bd147e83534f4ca0b"),
// and so on..
]
}
代码:

categories
.aggregate([
{
$match: {
_id: ObjectId(categoryId),
},
},
{
$project: {
tracks: {
$slice: ["$tracks", -N],
},
},
},
{
$lookup: {
from: "tracks",
as: "tracks",
localField: "tracks",
foreignField: "_id",
pipeline: [{ $sort: { uploadedDate: -1 } }],
},
},
])

基本上我对数组进行切片,得到最后N个元素,然后在tracks集合中查找它们。但是我想要得到N条记录在特定范围内。例如,如果我有100条记录,那么迭代数为0,批量大小为25,则将返回最后25个元素(索引75-99)。在迭代1时,将返回下一个(向后移动)25个元素(索引50-74),依此类推…

你可以这样写:

编辑:要支持边缘情况:

db.collection.aggregate([
{
$match: {_id: ObjectId("625167ce3859b8465ccf69dc")}
},
{
$addFields: {
avilableCount: {$max: [
{$subtract: [{$size: "$tracks" }, bulkSize * iterations]},  
0]}
}
},
{
$project: {
tracks: {
$cond: [{$eq: ["$avilableCount",  0]},
[],
{$slice: ["$tracks", {
$max: [
{$subtract: [{$size: "$tracks"}, bulkSize * (iterations + 1)]}, 0]},
{$min: [bulkSize , "$avilableCount"]}
]
}
]
}
}
}
])

操场例子

这将返回大小为bulkSize的大量曲目,从第一次迭代的列表末尾开始,并沿着迭代向后移动。因此,如果您有100条索引为0-99的曲目,并且bulkSize为25,则第一次迭代将获得75-99的曲目,第二次迭代将获得50-74的曲目,第三次迭代将获得25-49的曲目……avilableCount允许我们查看边缘情况:在边缘情况下,只有一部分容量是可用的,它将返回这一部分,如果non是可用的,它将返回[]。

最新更新