问题
In my application i have an box where users can read comments. If some user scrolls down, it loads more and more comments, everything fine. I slice the array from the back to the begin because i use $push
whenever somebody write some comment so i slice it like this $slice: [ -5 , 5]
. This will slice the last 5 elements out of the array. The -5
is actually an variable in my aggregation pipeline. Whenever i loaded some comments i decrease the value from -5
to -10
and so on so on. The problem i got here is if my array has an legth for example of 50, and i execute this slice $slice: [ -70, 5]
i get the first 5 comments, but i expected to receive 0. The result is that i have an infinity scrollbar witch loads over and over the same 5 first comments. How do i fix this?
let result = await Post.aggregate([
{
$match: {
_id: userId,
"posts._id": postId
}
},
{
$addFields: {
posts: {
$map: {
input: "$posts",
as: "p",
in: {
_id: "$$p._id",
comments: { $slice: ["$$p.comments", -start, 5] }
}
}
}
}
},
{
$project: {
posts: {
$filter: {
input: "$posts",
as: "posts",
cond: { $eq: ["$$posts._id", postId] }
}
}
}
}
]);
回答1:
One way to do is to use $cond
operator :
Query :
let inputPosition = -70
let positionConverted = -position // 70
let maxNumber = 1000
db.collection.aggregate([
{
$project: {
comments: {
$slice: [ "$comments",
{ $cond: [ { $gte: [ { $size: "$comments" }, positionConverted ] }, inputPosition, maxNumber ] }, 5 ] }
}
}
])
Test : mongoplayground
Explanation :
So syntax of $slice
is { $slice: [ <array>, <position>, <n> ] }
from that if you pass a value larger than size of array for <position>
then you'll get an empty array in response.
Here we're using $cond
to conditionally send either value of inputPosition
or value of maxNumber
to <position>
. Additionally, I've a hard coded value of maxNumber
to 1000
but in general it all depends on your choice - You can use a lesser number, it doesn't matter, that number should be a greater value than size of your array, You can also you size of array + 1
but instead of doing that operation if you believe your array is always less than 1000 then directly use 1000
.
Ref : $slice
来源:https://stackoverflow.com/questions/62105123/mongodb-pagination-on-arrays-check-if-slice-reached-the-beginning-of-the-arra