我有一个类别集合,每个类别都有来自不同集合的_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是可用的,它将返回[]。