MongoDB pagination on arrays - Check if $slice reached the beginning of the array

泪湿孤枕 提交于 2020-05-31 02:24:45

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!